閱讀187 返回首頁    go 阿裏雲 go 技術社區[雲棲]


如何用OpenCV訓練自己的分類器

最近要做一個性別識別的項目,在人臉檢測與五官定位上我采用OPENCV的haartraining進行定位,這裏介紹下這兩天我學習的如何用opencv訓練自己的分類器。在這兩天的學習裏,我遇到了不少問題,不過我遇到了幾個好心的大俠幫我解決了不少問題,特別是無忌,在這裏我再次感謝他的幫助。

一、簡介
目標檢測方法最初由Paul Viola [Viola01]提出,並由Rainer Lienhart [Lienhart02]對這一方法進行了改善。該方法的基本步驟為: 首先,利用樣本(大約幾百幅樣本圖片)的 harr 特征進行分類器訓練,得到一個級聯的boosted分類器。
分類器中的"級聯"是指最終的分類器是由幾個簡單分類器級聯組成。在圖像檢測中,被檢窗口依次通過每一級分類器, 這樣在前麵幾層的檢測中大部分的候選區域就被排除了,全部通過每一級分類器檢測的區域即為目標區域。
分類器訓練完以後,就可以應用於輸入圖像中的感興趣區域的檢測。檢測到目標區域分類器輸出為1,否則輸出為0。為了檢測整副圖像,可以在圖像中移動搜索窗口,檢測每一個位置來確定可能的目標。 為了搜索不同大小的目標物體,分類器被設計為可以進行尺寸改變,這樣比改變待檢圖像的尺寸大小更為有效。所以,為了在圖像中檢測未知大小的目標物體,掃描程序通常需要用不同比例大小的搜索窗口對圖片進行幾次掃描。
目前支持這種分類器的boosting技術有四種: Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost。
"boosted" 即指級聯分類器的每一層都可以從中選取一個boosting算法(權重投票),並利用基礎分類器的自我訓練得到。
根據上麵的分析,目標檢測分為三個步驟:
1、 樣本的創建
2、 訓練分類器
3、 利用訓練好的分類器進行目標檢測。

二、樣本創建
訓練樣本分為正例樣本和反例樣本,其中正例樣本是指待檢目標樣本,反例樣本指其它任意圖片。
負樣本
負樣本可以來自於任意的圖片,但這些圖片不能包含目標特征。負樣本由背景描述文件來描述。背景描述文件是一個文本文件,每一行包含了一個負樣本圖片的文件名(基於描述文件的相對路徑)。該文件創建方法如下:

采用Dos命令生成樣本描述文件。具體方法是在Dos下的進入你的圖片目錄,比如我的圖片放在D:/face/posdata下,則:

按Ctrl+R打開Windows運行程序,輸入cmd打開DOS命令窗口,輸入d:回車,再輸入cd D:/face/negdata進入圖片路徑,再次輸入dir /b > negdata.dat,則會圖片路徑下生成一個negdata.dat文件,打開該文件將最後一行的negdata.dat刪除,這樣就生成了負樣本描述文件。dos命令窗口結果如下圖:


   e.g: 負樣本描述文件的一個例子:
      假定目錄結構如下:
      /img
        img1.jpg
        img2.jpg
        bg.txt
      則背景描述文件bg.txt的內容為:
         img/img1.jpg
         img/img2.jpg

 

正樣本

對於正樣本,通常的做法是先把所有正樣本裁切好,並對尺寸做規整(即縮放至指定大小),如下圖所示:


由於HaarTraining訓練時輸入的正樣本是vec文件,所以需要使用OpenCV自帶的CreateSamples程序(在你所按照的opencv/bin下,如果沒有需要編譯opencv/apps/HaarTraining/make下的.dsw文件,注意要編譯release版的)將準備好的正樣本轉換為vec文件。轉換的步驟如下:

1) 製作一個正樣本描述文件,用於描述正樣本文件名(包括絕對路徑或相對路徑),正樣本數目以及各正樣本在圖片中的位置和大小。典型的正樣本描述文件如下:

posdata/1(10).bmp 1 1 1 23 23
posdata/1(11).bmp 1 1 1 23 23
posdata/1(12).bmp 1 1 1 23 23

不過你可以把描述文件放在你的posdata路徑(即正樣本路徑)下,這樣你就不需要加前麵的相對路徑了。同樣它的生成方式可以用負樣本描述文件的生成方法,最後用txt的替換工具將“bmp”全部替換成“bmp 1 1 1 23 23
”就可以了,如果你的樣本圖片多,用txt替換會導致程序未響應,你可以將內容拷到word下替換,然後再拷回來。bmp後麵那五個數字分別表示圖片個數,目標的起始位置及其寬高。這樣就生成了正樣本描述文件posdata.dat。

2) 運行CreateSamples程序。如果直接在VC環境下運行,可以在Project/Settings/Debug屬性頁的Program arguments欄設置運行參數。下麵是一個運行參數示例:
-info D:/face/posdata/posdata.dat -vec D:/face/pos.vec -num 50 -w 20 -h 20
表示有50個樣本,樣本寬20,高20,正樣本描述文件為posdata.dat,結果輸出到pos.vec。

或者在dos下輸入:

"D:/Program Files/OpenCV/bin/createsamples.exe" -info "posdata/posdata.dat" -vec data/pos.vec -num 50 -w 20 -h 20 
運行完了會d:/face/data下生成一個*.vec的文件。該文件包含正樣本數目,寬高以及所有樣本圖像數據。結果入下圖:


Createsamples程序的命令行參數:
命令行參數:
-vec <vec_file_name>
訓練好的正樣本的輸出文件名。
-img<image_file_name>
源目標圖片(例如:一個公司圖標)
-bg<background_file_name>
背景描述文件。
-num<number_of_samples>
要產生的正樣本的數量,和正樣本圖片數目相同。
-bgcolor<background_color>
背景色(假定當前圖片為灰度圖)。背景色製定了透明色。對於壓縮圖片,顏色方差量由bgthresh參數來指定。則在bgcolor-bgthresh和bgcolor+bgthresh中間的像素被認為是透明的。
-bgthresh<background_color_threshold>
-inv
如果指定,顏色會反色
-randinv
如果指定,顏色會任意反色
-maxidev<max_intensity_deviation>
背景色最大的偏離度。
-maxangel<max_x_rotation_angle>
-maxangle<max_y_rotation_angle>,
-maxzangle<max_x_rotation_angle>
最大旋轉角度,以弧度為單位。
-show
如果指定,每個樣本會被顯示出來,按下"esc"會關閉這一開關,即不顯示樣本圖片,而創建過程繼續。這是個有用的debug選項。
-w<sample_width>
輸出樣本的寬度(以像素為單位)
-h《sample_height》
輸出樣本的高度,以像素為單位。
到此第一步樣本訓練就完成了。恭喜你,你已經學會訓練分類器的五成功力了,我自己學這個的時候花了我一天的時間,估計你幾分鍾就學會了吧。
三、訓練分類器
樣本創建之後,接下來要訓練分類器,這個過程是由haartraining程序來實現的。該程序源碼由OpenCV自帶,且可執行程序在OpenCV安裝目錄的bin目錄下。
Haartraining的命令行參數如下:
-data<dir_name>
存放訓練好的分類器的路徑名。
-vec<vec_file_name>
正樣本文件名(由trainingssamples程序或者由其他的方法創建的)
-bg<background_file_name>
背景描述文件。
-npos<number_of_positive_samples>,
-nneg<number_of_negative_samples>
用來訓練每一個分類器階段的正/負樣本。合理的值是:nPos = 7000;nNeg = 3000
-nstages<number_of_stages>
訓練的階段數。
-nsplits<number_of_splits>
決定用於階段分類器的弱分類器。如果1,則一個簡單的stump classifier被使用。如果是2或者更多,則帶有number_of_splits個內部節點的CART分類器被使用。
-mem<memory_in_MB>
預先計算的以MB為單位的可用內存。內存越大則訓練的速度越快。
-sym(default)
-nonsym
指定訓練的目標對象是否垂直對稱。垂直對稱提高目標的訓練速度。例如,正麵部是垂直對稱的。
-minhitrate《min_hit_rate》
每個階段分類器需要的最小的命中率。總的命中率為min_hit_rate的number_of_stages次方。
-maxfalsealarm<max_false_alarm_rate>
沒有階段分類器的最大錯誤報警率。總的錯誤警告率為max_false_alarm_rate的number_of_stages次方。
-weighttrimming<weight_trimming>
指定是否使用權修正和使用多大的權修正。一個基本的選擇是0.9
-eqw
-mode<basic(default)|core|all>
選擇用來訓練的haar特征集的種類。basic僅僅使用垂直特征。all使用垂直和45度角旋轉特征。
-w《sample_width》
-h《sample_height》
訓練樣本的尺寸,(以像素為單位)。必須和訓練樣本創建的尺寸相同。
一個訓練分類器的例子:
"D:/Program Files/OpenCV/bin/haartraining.exe"   -data data/cascade -vec data/pos.vec -bg negdata/negdata.dat -npos 49 -nneg 49 -mem 200 -mode ALL -w 20 -h 20

訓練結束後,會在目錄data下生成一些子目錄,即為訓練好的分類器。

訓練結果如下:


 

恭喜你,你已經學會訓練分類器的九成功力了。

四:利用訓練好的分類器進行目標檢測。

這一步需要用到performance.exe,該程序源碼由OpenCV自帶,且可執行程序在OpenCV安裝目錄的bin目錄下。

performance.exe -data data/cascade -info posdata/test.dat -w 20 -h 20 -rs 30

performance的命令行參數如下:

Usage: ./performance
-data <classifier_directory_name>
-info <collection_file_name>
[-maxSizeDiff <max_size_difference = 1.500000>]
[-maxPosDiff <max_position_difference = 0.300000>]
[-sf <scale_factor = 1.200000>]
[-ni]
[-nos <number_of_stages = -1>]
[-rs <roc_size = 40>]
[-w <sample_width = 24>]
[-h <sample_height = 24>]

也可以用opencv的cvHaarDetectObjects函數進行檢測:

CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
                                            1.1, 2, CV_HAAR_DO_CANNY_PRUNING,
                                            cvSize(40, 40) ); //3. 檢測人臉
注:OpenCv的某些版本可以將這些目錄中的分類器直接轉換成xml文件。但在實際的操作中,haartraining程序卻好像永遠不會停止,而且沒有生成xml文件,後來在OpenCV的yahoo論壇上找到一個haarconv的程序,才將分類器轉換為xml文件,其中的原因尚待研究。

最後更新:2017-04-03 05:39:57

  上一篇:go 4種必須知道的Android屏幕自適應解決方案
  下一篇:go XML總結