之前做了SVM的車臉檢測,主要是針對車臉,接下來嘗試利用Adaboost和Haar進行車臉的檢測。我利用的主要是opencv中的cascade,其已經把Adaboost相關的算法做成了exe,直接調用就可以了,不像SVM中我們可能需要再調用。如果需要對boost源碼進行修改,可以利用Cmake將生成opencv的源代碼,(Cmake真是個很方便的東西,之前做交叉編譯用Automake來弄,差點累的半死)。
首先我來介紹一下幾個主要使用的工具。分別在opencv庫路徑下的,build/x64/vc10/bin目錄下,你也可以選擇vc11,12 或者x64,根據自己電腦的情況來使用。
主要我們使用的是opencv_createsamples.exe,opencv_traincascade.exe,其中前者主要是來創建訓練的樣本文件,vec文件。另外還有倆那個opencv_haartraining.exe,這個馬上就要被淘汰了,主要是用c來實現的,並且僅支持haar這個特征描述子,opencv_performace,主要是用來測試模型的性能的。
級聯分類器的參數設置,取自opencv官網,針對這兩個exe的參數,opencv官網還有剛詳細的鏈接
opencv官網cascade的詳細參數講解
下面是 opencv_traincascade (主要參數和haar_training還是有部分不同的)的命令行參數,以用途分組介紹:
通用參數:
-data <cascade_dir_name>
目錄名,如不存在訓練程序會創建它,用於存放訓練好的分類器。
-vec <vec_file_name>
包含正樣本的vec文件名(由 opencv_createsamples 程序生成)。
-bg <background_file_name>
背景描述文件,也就是包含負樣本文件名的那個描述文件。
-numPos <number_of_positive_samples>
每級分類器訓練時所用的正樣本數目。
-numNeg <number_of_negative_samples>
每級分類器訓練時所用的負樣本數目,可以大於 -bg 指定的圖片數目。
-numStages <number_of_stages>
訓練的分類器的級數。
-precalcValBufSize <precalculated_vals_buffer_size_in_Mb>
緩存大小,用於存儲預先計算的特征值(feature values),單位為MB。
-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>
緩存大小,用於存儲預先計算的特征索引(feature indices),單位為MB。內存越大,訓練時間越短。
-baseFormatSave
這個參數僅在使用Haar特征時有效。如果指定這個參數,那么級聯分類器將以老的格式存儲。
級聯參數:
-stageType <BOOST(default)>
級別(stage)參數。目前只支持將BOOST分類器作為級別的類型。
-featureType<{HAAR(default), LBP}>
特征的類型: HAAR - 類Haar特征; LBP - 局部紋理模式特征。
-w
-h
訓練樣本的尺寸(單位為像素)。
必須跟訓練樣本創建(使用 opencv_createsamples 程序創建)時的尺寸保持一致。這里需要注意的是w,h不要亂寫啊,計算負責度開銷很大,否則會嚴重影響訓練速度,根據實際的需求來填寫,我選擇的是32×32,之前用了50×50很慢很慢
Boosted分類器參數:****
-bt <{DAB, RAB, LB, GAB(default)}>
Boosted分類器的類型: DAB - Discrete AdaBoost, RAB - Real AdaBoost, LB - LogitBoost, GAB - Gentle AdaBoost。
-minHitRate <min_hit_rate>
分類器的每一級希望得到的最小檢測率。總的檢測率大約為 min_hit_rate^number_of_stages。
-maxFalseAlarmRate <max_false_alarm_rate>
分類器的每一級希望得到的最大誤檢率。總的誤檢率大約為 max_false_alarm_rate^number_of_stages.
-weightTrimRate <weight_trim_rate>
Specifies whether trimming should be used and its weight. 一個還不錯的數值是0.95。
-maxDepth <max_depth_of_weak_tree>
弱分類器樹最大的深度。一個還不錯的數值是1,是二叉樹(stumps)。
-maxWeakCount <max_weak_tree_count>
每一級中的弱分類器的最大數目。The boosted classifier (stage) will have so many weak trees (<=maxWeakCount), as needed to achieve the given -maxFalseAlarmRate.
類Haar特征參數:
-mode <BASIC (default) | CORE | ALL>
選擇訓練過程中使用的Haar特征的類型。 BASIC 只使用右上特征, ALL 使用所有右上特征和45度旋轉特征。
當opencv_traincascade 程序訓練結束以后,訓練好的級聯分類器將存儲於文件cascade.xml中,這個文件位於 -data 指定的目錄中。這個目錄中的其他文件是訓練的中間結果,當訓練程序被中斷后,再重新運行訓練程序將讀入之前的訓練結果,而不需從頭重新訓練。訓練結束后,你可以刪除這些中間文件。
注意事項,我訓練時碰到的諸多問題!!!!!這里說的都是訓練的關鍵!!!
1.首先是,train的bat文件和create_sample的bat文件中,大小寬高一定要一致,否則會報錯。
2.run_train.bat中,對於緩沖區的大小的設置-precalcValBufSize, -precalcIdxBufSize當時我為了訓練的快一點,在服務器上設置的是5000,5000,換到另一台服務器上之后總報錯,設置為4000MB就不報錯了,可能是內存設置的過大,原則上是盡可能設置的較大,訓練的速度會更快,其可以把計算的特征值存在內存中,不用虛擬內存。
3.在這里-numPos和-numNeg的設置,這里設置的是在每一級訓練中參與訓練的正樣本和負樣本個數,千萬不要和訓練的樣本數一樣,應該設置為80%左右適宜,否則容易陷入死循環,就是訓練程序一直不動了,不走向下一級的訓練。
4.有時會顯示中途terminated,原因是每一級分配的numPos,numNeg太少,已經達到設定的精度需求,就不再繼續下一級,此時加大numPos即可。
5.在樣本數據集的准備上,首先至少要多點吧,最好是幾千個,這才叫機器學習嘛。此外,負樣本的數量一定要比正樣本多,這樣才能突出正樣本,最好在1:2 1:3左右吧,根據訓練的結果。其實,大家不要小看訓練樣本,其實這些都是固定的,算法形成基本就那樣了,更關鍵的是在樣本的准備上,對於最終的模型性能至關重要,不要小看樣本。
首先我使用的是opencv下自帶的opencv_createsamples.exe和opencv_opencv_traincascade.exe。
這個在opencv 的庫目錄bin下面可以找到。
由於這里使用的是編譯好的工具exe,因此傳入的參數我們通常通過寫批處理文件bat文件來實現。
以下是run_createssamples.bat,需要自己建立
這里說明一下這個文件,-vec 制定生成的vec文件,-info指定正樣本文件列表,-num指定樣本數量,-w,-h指定樣本的大小,需要主要的是樣本的數量最后不要留有空行。
我這次訓練的數據集正樣本個數為6587,負樣本個數為6584。這里對於負樣本的討論暫不展開,讀者可以自己設置,我這里大致是1:1,看到一些別的人說1:2,1:3的效果比較好,讀者可以自己控制個數作比較,但是訓練的樣本數至少在兩三千以上才會有比較好的效果。
PosImageList32_32.txt內部是這樣的,行中第一個參數是圖片的路徑,第二個參數是正樣本個數,之后跟着的正樣本的坐標,由於我這里已經將樣本截取了出來車臉就是32*32,因此這里是直接給出0 0 32 32。
NegImageList.txt內部是這樣的,直接給出負樣本的文件路徑即可,我這里負樣本文件名中還有face,但已經是負樣本不包含車臉,負樣本一般最后跟實際的應用場景一致,在這里可以選取為卡口馬路上的景象,雜物,行人,自行車等。
以下是run_traincascade_test2.bat,需要自己建立 !
詳細說明一下這幾個參數 -data 是用來存放模型的路徑以及每一級生成的相關參數注意!!,在這里-data的路徑必須自己手動設置,要不然會報錯,說找不到這個路徑,重要的事情說3遍!! -vec用來指定正樣本生成的向量文件,-bg是指定負樣本文件文件,-numPos這里說明是每一級使用的正樣本個數,一般為正樣本數總量的80%左右,如果跟總樣本數一致會導致無法收斂,也就是訓練一致不結束,如果太少,訓練的效果較差。 -numNeg同理, -numStages指定訓練的級數,一般15-20級可以達到較好的效果,-precalcValBufSize 和 -precalcIdxBufSize 指定的是存儲計算過程中特征和特征索引的緩存大小,在內存足夠的情況下,這兩個值設置的大一點可以加速訓練過程,但是千萬不要設置的太大,電腦內存不夠,訓練會報錯的!!! -maxWeakCount 設置每一級中弱分類器的最大個數,這里設置為150,-mode 指定使用harr特征中右上特征和旋轉特征,-miniHitRate 每一級的最低的命中率,默認為0.995,這里設置為0,997, -maxFalseAlarmRate 最大誤報率設置為0.5
OK設置好這些參數,就可以開啟訓練啦!!!!
訓練過程,當可以中斷訓練,重新運行批處理文件,他會載入之前生成的中間文件,所以不影響。如果發現長時間一級下不去的話,可能是沒收斂,需要重新調整參數,參見我上面說的。我運行了這個大概32*32的規模,運行了18級,每次取5000個樣本計算,總共是花了3天時間才訓練完。僅供參考
訓練結束后生成18個過程的中間文件,以及最后的模型文件cascade.xml,我將在下一講中介紹怎么使用這個模型文件。
這是我在應用過程中的一些見解和心得,網上也看了零零碎碎不少資料,希望能幫到你。如有錯誤,敬請指出。謝謝。