訓練自己haar-like特徵分類器並識別物體(2)
在上一篇文章中,我介紹了《訓練自己的haar-like特徵分類器並識別物體》的前兩個步驟:
1.準備訓練樣本圖片,包括正例及反例樣本
2.生成樣本描述檔案
3.訓練樣本
4.目標識別
=================
今天我們將著重學習第3步:基於haar特徵的adaboost級聯分類器的訓練。若將本步驟看做一個系統,則輸入為正樣本的描述檔案(.vec)以及負樣本的說明檔案(.dat);輸出為分類器配置引數檔案(.xml)。
老規矩,先介紹一下這篇文章需要的工具,分別是(1)訓練用的opencv_haartraining.exe,該程式封裝了haar特徵提取以及adaboost分類器訓練過程;(2)haarconv.exe(老版本命名法)或者convert_cascade.exe(新版本命名法),該程式用於合併各級分類器成為最終的xml檔案。一般這兩個程式都能在opencv的工程檔案裡找到,請善用ctrl+F。若沒有,則請到
工具都準備好了,下面進入正題:
1.訓練分類器
開啟cmd,cd到當前目錄,執行命令:
1 |
opencv_haartraining.exe -data ./cascade -vec ./pos/sample_pos.vec <span style= "color: #ff0000;" >-bg ./neg/sample_neg.dat</span> -npos
20 -nneg 60 -mem 200 -mode ALL -w 20 -h 20
|
引數說明,這個要好好看,出錯了好除錯
-data 指定生成的檔案目錄, -vec vec檔名, -bg 負樣本描述檔名稱,也就是負樣本的說明檔案(.dat) -nstage 20 指定訓練層數,推薦15~20,層數越高,耗時越長。 -nsplits 分裂子節點數目,選取預設值 2 -minhitrate 最小命中率,即訓練目標準確度。 -maxfalsealarm最大虛警(誤檢率),每一層訓練到這個值小於0.5時訓練結束,進入下一層訓練,-npos 在每個階段用來訓練的正樣本數目, -nneg在每個階段用來訓練的負樣本數目 這個值可以設定大於真正的負樣本影象數目,程式可以自動從負樣本影象中切割出和正樣本大小一致的,這個引數一半設定為正樣本數目的1~3倍 -w -h樣本尺寸,與前面對應 -mem 程式可使用的記憶體,這個設定為256即可,實際執行時根本就不怎麼耗記憶體,以MB為單位 -mode ALL指定haar特徵的種類,BASIC僅僅使用垂直特徵,ALL表示使用垂直以及45度旋轉特徵 -sym或者-nonsym,後面不用跟其他引數,用於指定目標物件是否垂直對稱,若你的物件是垂直對稱的,比如臉,則垂直對稱有利於提高訓練速度
其中要注意,負樣本使用的是.dat檔案,而不是.vec檔案。訓練結束後會在cascade目錄下生成0-N的子目錄。訓練過程如下圖,我的正樣本20,負樣本60,小試牛刀,畢竟資料量有限。
想讓自己更強大,就應該知道這張圖裡面一些引數的意思。
1 2 3 4 5 6 7 |
BACKGROUNG PROCESSING TIME 是負樣本切割時間,一般會佔用很長的時間
N 為訓練層數
%SMP 樣本佔總樣本個數
ST.THR 閾值,
HR 擊中率,
FA 虛警,<span style= "background-color: #ff0000; color: #000000;" ><strong>只有當每一層訓練的FA低於你的命令中宣告的maxfalsealarm數值才會進入下一層訓練</strong></span>
EXP.ERR 經驗錯誤率
|
2.合併子分類器生成xml檔案
輸入命令:
1 |
haarconv.exe ./cascade haar_adaboost.xml 25 25
|
若你使用的是convert_cascade.exe則是另外一種格式:
1 |
convert_cascade.exe --size= "20x20"
..\cascade haar_adaboost.xml
|
想知道用法可以輸入xxx.exe usage,用法以及引數說明一目瞭然
3.總結以及注意事項
看起來很簡單是不是,你錯了!真正做起來會有各種各樣的錯誤發生讓你措手不及。以下是我總結的問題及分析:
1)訓練時間非常久,少則秒鐘,多則幾天甚至一禮拜。具體的時間跟你樣本的選取、樣本數量、機器的效能有著直接聯絡。舉個例子,有人正樣本7097負樣本2830,在8核3.2Ghz的機器上,開啟了多核並行加速(MP)的情況下訓練了一週時間,跑到19層。連結http://blog.csdn.net/liulina603/article/details/8197889 。這個真心有點久了,有點誇張。舉這個例子是想跟你說明,這是一件耗時間的事情,所以請你耐心等待。
2)卡死在某一層,好像進入死迴圈。這種情況一般跟樣本的選擇有關,尤其是負樣本。當剩下所有的negtive樣本在臨時的cascade Classifier中evaluate的結果都是0(也就是拒絕了),隨機取樣本的數目到幾百萬都是找不到誤檢測的neg樣本了,因而沒法跳出迴圈!
解決方法是,增大負樣本數目,增大負樣本之間的變化!
3)訓練帶某一層出錯,報錯提示下圖。檢視cascade目錄下發現確實走到第5層。這種情況跟上一種情況其實有點類似,都是opencv_haartraining.exe無法正常terminate。而我們的關注點在於,所生成的這些子分類器能用嗎?要依實際情況而定。拿下圖來說,在第5層的時候FA已經很低了,0.125000,說明效果已經夠用。2)中也是這個道理。
That`s all.