訓練級聯分類器

原文地址:http://blog.csdn.net/ariesjzj/article/details/8639208


物體檢測方法大體可分爲兩類,基於知識的方法和基於統計的方法。前者如template matching, surf/sift detector等等。這些方法都基於我們對於識別目標已有比較清晰的刻畫。雖然有些特徵能抗一定的形變,但總體泛化性不夠強。如果檢測目標比較固定且對時間要求不高,可以考慮用這類方法。但有些應用是沒法提供模板的,或者說模板太多(一一匹配的話檢測時間無法接受),又或者說我們需要容忍更大程度或更多樣的形變(如人臉,行人等)。這時候就要考慮用基於統計的方法了。既然是基於統計,就得有大量的樣本,分類器對這些樣本進行學習來獲得參數。得到目標分類器後,要進行檢測時就很快了。OpenCV中帶的Haar特徵級聯分類器就是這樣一種方法,它位於app目錄下,該目錄下有兩個實現,一個是老的實現haartraining,只支持Haar特徵。另一個是新的traincascade,支持更多特徵(LBP,HOG)和boosted分類器,更易於擴展。除此之外OpenCV的data目錄下有很多訓練好的級聯分類器(如人臉,眼睛檢測等),load進來就可以用,無需訓練。官方例程中的objectdetection,facedetect等例子就是直接用了這些訓練好的分類器,如自帶的face detection程序:


當然了,作爲有理想有抱負的碼農,用現成的分類器是不會滿足的。現實使用中我們經常需要訓練針對各種應用的分類器。下面介紹如何訓練一個自己的級聯分類器。整個過程大致可分爲以下幾步(基於OpenCV 2.4.4):


1. 收集數據

數據可分爲正樣本和負樣本。正樣本即要檢測的目標,負樣本則不包含目標。

首先我們要生成正負樣本的索引(或稱描述文件)。正樣本描述文件官方文檔中給了例子:

img/img1.jpg 1 140 100 45 45
img/img2.jpg 2 100 200 50 50 50 30 25 25

依次爲文件名,目標個數,目標座標。既然是基於統計的方法,樣本自然要求很多(一般以千爲單位),因此很多時候這一步是勞力活。當然,勤勞勇敢的碼農們寫了各種工具來解放生產力。這些描述文件可以人肉生成,也可用object marker(http://inflomatik.com/)來圈,然後自動生成。除此之外還有些其它工具:

http://code.google.com/p/opencv-haar-cascade-positive-image-builder/

http://code.google.com/p/imageclipper/

http://code.google.com/p/ml-object-marker/source/checkout

ffmpeg -i 可以將視頻分解爲圖片

另外後面會講到的createsamples工具還可以自動生成正樣本。


負樣本沒這麼麻煩了,描述文件只要包含文件路徑即可,Windows中可以用dir /s /b生成,Linux下用find命令。


2. 創建vec文件

createsamples 工具可用於從正負樣本描述文件生成訓練程序需要的vec文件。如根據樣本描述文件samples.txt生成samples.vec:

opencv_createsamples.exe -info samples.txt -vec samples.vec -w 20 -h 20

它還包含一個功能,通過distortion自動生成樣本。如根據template.png和負樣本描述文件negative.txt生成3000個樣本。

opencv_createsamples.exe  -img template.png -vec -num 3000 -bg negative.txt -vec samples.vec -w 20 -h 20


還有種很尷尬的情況,就是既沒空圈那麼多的正樣本,又想檢測多種目標,咋辦?因爲上面提到的通過distortion來自動生成樣本的方法不支持多個目標。一種方法是先根據多個目標生成多個vec文件,再用mergevec(http://note.sonots.com/SciSoftware/haartraining/mergevec.cpp.html)這個工具合併vec文件。mergevec用最新的OpenCV編譯不了,如果你和我一樣懶不想移植的話就下個OpenCV 1.0(就下可執行文件包,3M多那個),把那坨dll放到PATH裏,然後下mergevec.exe就可以跑了。如根據template1.png ~ template3.png分別生成三個vec文件:

opencv_createsamples.exe -img template1.png -num 1000 -bg negative -vec sample1.vec -w 20 -h 20

opencv_createsamples.exe -img template2.png -num 1000 -bg negative -vec sample2.vec -w 20 -h 20

opencv_createsamples.exe -img template3.png -num 1000 -bg negative -vec sample3.vec -w 20 -h 20

接着寫vec的索引文件sample.txt:

sample1.vec

sample2.vec

sample3.vec

然後就可以生成最終的samples.vec文件了:

mergevec.exe sample.txt samples.vec -w 20 -h 20


另外,如果你的應用比較general,如從自然背景中找特定目標,網上有現成的負樣本數據集:
svn checkout http://tutorial-haartraining.googlecode.com/svn/trunk/ tutorial-haartraining-read-only


3. 訓練分類器

很多地方還是用haartraining,官方手冊中建議用新的traincascade。用法上參數什麼的都差不多,不過還是有差別。

根據剛纔生成的樣本描述文件進行訓練,結果放在classifier目錄裏:

opencv_traincascade.exe -data classifier -vec samples.vec -bg negative.txt -numStages 25 -w 20 -h 20

其餘有一坨參數,諸如maxFalseAlarmRate,minHitRate等想設就設下,不過默認的值大多數情況都是挺好的選擇。

-featureType指定特徵類型,默認爲類Haar特徵,還可以指定爲LBP或HOG。基於Haar的級聯分類器訓練時間一般很長(以天爲單位)。LBP,HOG則快得多。

注意這畢竟不是產品,很多時候參數一給不好就掛掉了。當然直接掛掉是最好的情況,最慘的是跑到中間hung住了,都不知道是因爲hung住了還是因爲訓練時間長。。。


注:無論是haartraining還是traincascade,最終都會生成表示成xml文件的分類器。但如果你用的是haartraining並且想用中間Stage生成的分類器,可以用convert_cascade將中間結果整成xml文件。


4. 測試&驗證

performance.exe可以對於給定的測試用例給出檢測率報告。注意只對opencv_haartraining的結果適用。如果要寫報告給數據這個很有用。不過這裏先不整這麼抽象的東西,先寫個程序直觀地看看檢測效果如何。官方例程中的objectdetection是從攝像頭抓幀進行檢測。這裏我們略微修改下從文件讀取圖片然後檢測目標。其中關鍵函數爲:

void CascadeClassifier::detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())

其中的參數對於檢測結果會有較大影響,如:

minNeighbors:其實分類器給出的結果是很多個矩形,那些被多個矩陣覆蓋的區域被保留,而那些個孤立的矩陣被拋棄。這個參數決定了保留還是拋棄的閾值。(http://www.cognotics.com/opencv/servo_2007_series/part_2/page_2.html)。

minSize :檢測目標size的閥值,小於它的不會被檢測出來。


這裏拿”憤怒的小鳥“作個簡單的例子,因爲每個關卡中籠子裏的鳥雖不完全相同,但都類似。這裏以一關中籠子中的鳥爲訓練正樣本,讓其學習並檢測其它關卡中哪些是籠中鳥。

在一些case中還是有不少false alarm的。直觀上可能會覺得這種動畫圖片的檢測會更容易,但動畫圖片由於背景形狀規則,色塊均勻,作爲負樣本並不好,所以負樣本儘可能還是要取得變化豐富些。


一些案例和參考資料:

Tutorial: OpenCV haartraining (Rapid Object Detection With A Cascade of Boosted Classifiers Based on Haar-like Features) http://note.sonots.com/SciSoftware/haartraining.html
Haar-feature Object Detection in C#  http://www.codeproject.com/Articles/441226/Haar-feature-Object-Detection-in-Csharp
Ivan Laptev | INRIA Paris - Rocquencourt, France http://www.di.ens.fr/~laptev/download.html#objectdetection
OBJECT DETECTION IN OPENCV USING HAARTRAINING http://achuwilson.wordpress.com/2011/02/13/object-detection-using-opencv-using-haartraining/
Ultra Rapid Object Detection in Computer Vision Applications with Haar-like Wavelet Features http://www.codeproject.com/Articles/27125/Ultra-Rapid-Object-Detection-in-Computer-Vision-Ap
HaarTraining for Pedestrian Detection http://se.cs.ait.ac.th/cvwiki/opencv:tutorial:haartraining#step_1dataset
A simple object detector with boosting http://people.csail.mit.edu/torralba/shortCourseRLOC/boosting/boosting.html
OpenCV Object Detection Howto http://opencv.willowgarage.com/wiki/ObjectDetection
How to use HaarTraining in OpenCV http://kang.blog.com/2009/08/12/how-to-use-haartraining-in-opencv/
Create Your Own Haar Classifier for Detecting objects in OpenCV http://achuwilson.wordpress.com/2011/07/01/create-your-own-haar-classifier-for-detecting-objects-in-opencv/
How-to build a cascade of boosted classifiers based on Haar-like features http://opencv.willowgarage.com/wiki/ObjectDetection
Face Detection using OpenCV http://opencv.willowgarage.com/wiki/FaceDetection
Seeing With OpenCV http://www.cognotics.com/opencv/servo_2007_series/part_1/index.html
FAQ for OpenCV haartraining http://www.computer-vision-software.com/blog/2009/11/faq-opencv-haartraining/
Simple Qt interface to try OpenCV implementations of SIFT, SURF, FAST, BRIEF and other feature detectors and descriptors http://code.google.com/p/find-object/
《The OpenCV User Guide》 Chapter 4 Cascade classifier training
《Learning.OpenCV.Computer.Vision.with.the.OpenCV.Library》Chapter 13 Machine learning
發佈了53 篇原創文章 · 獲贊 12 · 訪問量 55萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章