[ OpenCV ] 利用 Opencv訓練 Haar級聯數據

本篇純為筆記,先寫下來擔心自己忘了,同時希望也能幫助到一些朋友。
可能有很多地方有錯,歡迎糾正。

開始前請先確認自己安裝了 Opencv,作者是在 Python2環境下使用 opencv-2.4.9,但我在 Python2環境中用 opencv-3.1.0也可以正常訓練。
接著 clone訓練用的代碼
git clone https://github.com/mrnugget/opencv-haar-classifier-training
資料夾結構如下
. opencv-haar-classifier-training
├── LICENSE
├── README.md
├── bin
│   └── createsamples.pl
├── classifier
├── negative_images
├── positive_images
├── samples
├── tools
│   └── mergevec.py
└── trained_classifiers
    └── banana_classifier.xml
把正樣本放到 positive_images資料夾中,負樣本放到 negative_images資料夾中。
正樣本的圖像要將要 detect的目標物剪裁成只有目標物的大小。
圖像的比例沒有硬性要求,但不要差太多。
  
工作上的圖片不方便放到這,所以就直接放上 Tutorial裡的照片。
而負樣本就我所知,什麼照片都可以,就是不要放圖中有目標物的照片。(聽說負樣本越多越好)
接著輸入以下指令,將 positive_images和 negative_images裡的一些資訊打包成 txt檔。
find ./positive_images -iname "*.jpg" > positives.txt
find ./negative_images -iname "*.jpg" > negatives.txt
接著輸入下列指令,將正樣本打包成 *.vec的文件,文件將會儲存在 samples資料夾中。
perl bin/createsamples.pl positives.txt negatives.txt samples 1500\
  "opencv_createsamples -bgcolor 0 -bgthresh 0 -maxxangle 1.1\
  -maxyangle 1.1 maxzangle 0.5 -maxidev 40 -w 80 -h 40"
特別需要注意的是 -w和 -h,這將會影響之後在 detect時尋找目標的尺寸。至於其他參數可以參考這裡

然後輸入下列指令,將 samples資料夾中所有的 *.vec檔打包成 samples.vec,並儲存在文檔的主目錄。作者撰寫該文件時是在 Python2的環境,所以 Python3環境會執行錯誤。
python ./tools/mergevec.py -v samples/ -o samples.vec
最後輸入下列指令,開始訓練 Haar級聯數據。
opencv_traincascade -data classifier -vec samples.vec -bg negatives.txt\
  -numStages 20 -minHitRate 0.999 -maxFalseAlarmRate 0.5 -numPos 1000\
  -numNeg 600 -w 80 -h 40 -mode ALL -precalcValBufSize 1024\
  -precalcIdxBufSize 1024
特別需要注意的是 -w和 -h的值要輸入前面打包 *.vec的文件時輸入的 -w和 -h,如果不一樣會不能訓練。
-precalcValBufSize和 -precalcIdxBufSize是提供訓練時使用的記憶體(Mb),如果想要訓練快一點可以把值加大。
其他參數也很重要,可以參考這裡

如果急著需要 trained model,可以加上 "-featureType LBP"。會快非常多,但相對 loss會比較大。
opencv_traincascade -data classifier -vec samples.vec -bg negatives.txt\
  -numStages 20 -minHitRate 0.999 -maxFalseAlarmRate 0.5 -numPos 1000\
  -numNeg 600 -w 80 -h 40 -mode ALL -precalcValBufSize 1024\
  -precalcIdxBufSize 1024 -featureType LBP
訓練完成後,就會在 classifier資料夾中看到 classifier.xml,接著就可以拿來捕捉物件啦。

假設 -numStages設定為 20,但有時 Stage可能還沒走到20,但卻顯示下列資訊,
Required leaf false alarm rate achieved. Branch training terminated.
意思是指說訓練的模型已經達到指定的精度,有需要的話可以把精度調整更苛刻,或是添加更多的數據。
不打算做任何更動的話,在 classifier資料夾一樣會出現 classifier.xml。

如何利用 Haar級聯數據捕捉歡迎參考 "利用 OpenCV抓取相片中的臉部數據"。

本文參考 Train your own OpenCV Haar classifierOpenCV documentation

留言