前言
使用opencv自帶的分類器效果並不是很好,由此想要訓練自己的分類器,正好opencv有自帶的工具進行訓練。本文就對此進行展開。
步驟
1.查找工具文件;
2.准備樣本數據;
3.訓練分類器;
具體操作
注意,本文是在windows系統實現的,當然也可以在linux系統進行。
1.查找工具文件;
opencv中的自帶的分類器訓練工具在開源庫中以應用程序的類型呈現的,具體目錄如下。
.\opencv2410\build\x64\vc12\bin
可以在該目錄下查找到相關的工具文件,有opencv_createsamples、opencv_haartraining、opencv_performance、opencv_traincascade;
其中,opencv_haartraining和opencv_traincascade是opencv開源庫用於訓練級聯分類器的兩個程序。opencv_traincascade是一個較新的程序,使用OpenCV2.x API以c++編寫,二者的主要區別是opencv_traincascade支持Haar和LBP兩種特征,並易於增加其他特征。與Haar特征相比,LBP特征是整數特征,因此訓練和檢測過程都會比Haar特征快幾倍。LBP和Haar特征用於檢測的准確率是依賴訓練過程中訓練數據的質量和訓練參數。訓練一個與基於Haar特征同樣准確度的LBP的分類器是可能的。
另外,opencv_traincascade和opencv_haartraining兩個訓練程序的輸入參數有些微的差別,比如前者是numPos和numNeg,而后者是npos和nneg,同時二者所輸出的分類器的文件格式也並不相同,注意區分。新的級聯檢測器接口(object模塊中的CascadeClassifier類)支持這兩種格式。opencv_traincascade可以舊格式導出訓練好的級聯分類器,但是在訓練過程被中斷后再重啟訓練過程時,二者不能裝載和中斷前不同的文件格式。另外,opencv_traincascade程序使用TBB(Threading Building Blocks)來處理多線程,如果希望使用多核並行運算加速,請使用TBB來編譯opencv。
opencv_createsamples用來准備用於訓練的正樣本數據和測試數據,能夠生成新舊兩個訓練程序支持的正樣本數據。輸出為以*.vec為擴展名的文件,該文件以二進制方式存儲圖像。
opencv_performance可以用來評估分類器的質量,但是只能評估opencv_haartraining輸出的分類器。它讀入一組標注好的圖像,運行分類器並報告性能。
2.准備樣本數據;
訓練需要一些樣本數據,分別是正樣本和負樣本。負樣本是指不包括目標的圖像,正樣本是只包含待檢測目標的圖像。負樣本必須手工准備,而原始正樣本可以使用opencv_createsamples創建訓練器需要的正樣本圖像。樣本圖像可以是不同尺寸的,但是不能小於訓練窗口的大小。
2.1樣本數據要求;
正樣本原始圖像應該包含要檢測的目標對象,比如人臉或者其他,而負樣本圖像不能包含要檢測的目標。正樣本圖像的背景需要多樣化,可以嘗試用隨機噪點填充背景,避免固定的背景。目標的像素數量肯定要多於背景像素數量的,原始正樣本圖像尺寸可以不同,但是應該有相同的高寬比。正負樣本的格式、尺寸、通道數目可以不同,但是要保證尺寸不能小於訓練的參數(即生成vec文件時輸入的-w-h參數)。負樣本不能包含目標,且應該多樣化。正負樣本的數目和比例的選取依賴於檢測任務,建議在1:2-1:3之間,但這不是硬性規定的。建議開始使用小數目的樣例生成級聯器然后進行測試,如果效果不佳就可以增加正負樣本數量。
2.2生成負樣本描述文件;
負樣本here(xte1);
在工程目錄下,創建一個文件夾用於存放負樣本圖像,可以不同尺寸、不同通道數、不同格式,但尺寸不能小於正樣本訓練參數。負樣本要盡量多樣化,且不能包含要檢測的目標對象。
負樣本目錄結構
/negimg
img1.jpg
img2.bmp
negimg.txt
其中,negimg.txt是負樣本的描述文件,
E:\work\facedet\facedet-train\negall\GULF_99.bmp E:\work\facedet\facedet-train\negall\u=1000618073,567507844&fm=23&gp=0.jpg E:\work\facedet\facedet-train\negall\u=1000795684,2512483114&fm=23&gp=0.jpg
生成方式是在圖像目錄下新建批量生成文件negimg.bat,雙擊即可;
dir /b/s/p/w *.bmp > num.txt
注意,1)不同的圖像格式; 2)避免空行,將最后一行的空行刪除;
2.3生成正樣本描述文件*.vec;
2.3.1 創建文件夾的過程和負樣本基本一樣,此處不再贅述。生成正樣本描述文件之后,打開描述文件,將jpg全部替換成jpg 1 0 0 20 20,其中jpg是圖像格式,1表示對應圖像中檢測目標數目,[0 0 20 20]表示對應圖像中目標位置分別是[left top width height];注意可以有多個目標,不同圖像對應的目標數目和位置可能不同,可能需要分別處理;可以使用相對路徑,也可以是絕對路徑。
正樣本描述文件將每張圖像上的目標數目,以及每個目標對象的位置信息進行描述,按照以下格式描述。本質上講,正樣本描述文件是用來加速機器學習的。
positive_image_name num_of_objects x y width height x y width height …
如果一張圖像有多個目標,則文件內容為
img/img_with_faces_1.jpg 1 140 100 45 45 img/img_with_faces_2.jpg 2 100 200 50 50 50 30 25 25
2.3.2 生成*.vec正樣本描述文件;
這個時候就要使用opencv_createsample生成vec文件啦!訓練圖像正樣本目標尺寸的高寬參數一般設置為20*20或者24*24,本文設置為20*20.
opencv_createsamples.exe -vec pos.vec -info posimg.txt -num 7767 -w 20 -h 20
-vec是輸出文件,內含用於訓練的正樣本;-info是描述目標所在圖像及大小位置的描述文件;-num是生成正樣本的數目(應該是所有圖像中的目標數目吧?);
-w和-h是輸出樣本的目標尺寸,以像素為單位;
3.訓練分類器;
3.1 本文使用opencv_traincascade訓練一個級聯分類器。現在正負樣本、正負樣本描述文件都已准備好,開始進行訓練,只需要設置想要的參數即可;
opencv_traincascade.exe -data xml -vec posall.vec -bg negall.txt -numPos 1000 -numNeg 2500 -mem 500 -mode ALL -w 20 -h 20
其中,xml是存放訓練結果的目錄;注意,參數-w和-h應該與在生成.vec文件時候設置的-w和-h保持一致,同時寫在-numPos和-numNeg的正負樣本圖像應該都是真正可用的,可打開的。各個參數的意義可參考here,有通用參數、級聯參數、Boosted分類器參數、類Haar特征參數、LBP參數;
-
通用參數:
-
-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>
訓練的分類器的級數。一般取值15-25。
-
-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 <sampleWidth>
-
-h <sampleHeight>
訓練樣本的尺寸(單位為像素)。必須跟訓練樣本創建(使用 opencv_createsamples 程序創建)時的尺寸保持一致。
-
-
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。一般取值0.95-0.995。
-
-maxFalseAlarmRate <max_false_alarm_rate>
分類器的每一級希望得到的最大誤檢率。總的誤檢率大約為 max_false_alarm_rate^number_of_stages.一般取值0.4-0.5。
-
-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度旋轉特征。
-
-
LBP特征參數:
LBP特征無參數。
訓練完成之后,打開保存-data對應目錄,即可看到訓練結果。cascade.xml文件即為最終的訓練結果,可以用來進行目標檢測。
3.2訓練過程相關問題;
問題1:
Train dataset for temp stage can not be filled. Branch training terminated.
原因:訓練數據在中間訓練階段沒有filled,訓練分支被終止。此時可以生成cascade.xml文件,終止的原因是訓練數據不足,一般已經訓練了多個stage。
還有一個原因可能是圖像數據的路徑有問題,這種情況一般stage0即出現錯誤。
問題2:
Required leaf false alarm rate achieved. Branch training terminated
原因:負樣本數據中包含要檢測的目標對象,導致錯誤預警率過高。此時可以檢查正負訓練樣本數據,是否有誤。
接下來就要測試訓練的模型能否得到較好的檢測效果,請參看here。
參考
1.opencv人臉檢測訓練分類器及其常見問題-譯文-Good;
3.人臉檢測訓練心得;
4.opencv_traincascade支持Haar和LBP特征;
6.如何使用工具進行訓練;
7.如何訓練詳解;
9.opencv官網-原文;
10.模型訓練簡介;
完
