1. 程式人生 > >利用OpenCV自帶的traincascade程式訓練分類器

利用OpenCV自帶的traincascade程式訓練分類器

級聯分類器簡介
OpenCV中的Adaboost級聯分類是樹狀結構,如下圖,其中每一個stage都代表一級強分類器。當檢測視窗通過所有的強分類器時才被認為是目標,否則就認為當前視窗不是我們要找的目標。實際上,不僅強分類器是樹狀結構,強分類器中的每一個弱分類器也是樹狀結構。

一個完整的弱分類器包含包含:Haar特徵+leftValue+rughtValue+弱分類器閾值(threshold)
這些元素共同構成了弱分類器,缺一不可。
下圖為深度為2的兩種形式的弱分類器。左邊形式包含2個Haar特徵、1個leftValue、2個rightValue和2個弱分類器閾(t1和t2);右邊形式包括2個Haar特徵、2個leftValue、1個rightValue和2個弱分類器閾。

左邊形式的計算流程:
1.計算第一個Haar特徵的特徵值haar1,與第一個弱分類器閾值t1對比,當haar1< t1時,進入步驟2;當haar1>t1時,該弱分類器輸出rightValue2並結束。
2.計算第二個Haar特徵值haar2,與第二個弱分類器閾值t2對比,當 haar2 < t2時輸出leftValue;當haar2>t2時輸出rightValue1。

分類器訓練
利用opencv自帶的opencv_traincascade程式訓練一個分類器,需要經過以下幾個步驟:
(1)收集訓練樣本
訓練樣本包括正樣本和負樣本。正樣本,通俗點說,就是圖片中只有你需要的目標。而負樣本的圖片只要其中不含有目標就可以了。但需要說明的是,負樣本也並非隨便選取的,最好是與檢測目標相關的圖片。例如,你需要檢測的目標是汽車,那麼正樣本就應該是僅僅含有汽車的圖片,而負樣本顯然不能是一些包含天空、海洋等風景的圖片,因為最終訓練分類器的目的是檢測汽車,而汽車應該出現在馬路上。也就是說,分類器最終檢測的圖片應該是那些包含馬路,交通標誌,建築物,廣告牌,汽車,摩托車,三輪車,行人,自行車等在內的圖片。很明顯,這裡的負樣本應該是包含摩托車、三輪車、自行車、行人、路面、灌木叢、花草、交通標誌、廣告牌等的圖片。
需要注意的是,adaboost方法是機器學習中的一個經典演算法,而機器學習演算法的前提條件是,測試樣本和訓練樣本獨立同分布。所謂的獨立同分布,可以簡單理解為:訓練樣本要和最終的應用場合非常接近或者一致。否則,基於機器學習的演算法並不能保證演算法的有效性。此外,足夠的訓練樣本(至少得幾千張正樣本、幾千張負樣本)也是保證訓練演算法有效性的一個前提條件。
(2)正樣本尺寸歸一化
將上一步收集到的正樣本進行尺寸歸一化,尺寸歸一化的目的是將所有的圖片都縮放到同一大小,比如,縮放到28*28的大小,可以用批量編輯工具,批量將圖片改成同一尺寸。
(3)建立正負樣本說明檔案
利用指令碼檔案 dir.bat(檔案內容:dir /b > possamples.txt)置於正樣本圖片同一目錄下,執行生成正樣本圖片名描述檔案,開啟possamples.txt刪除非圖片名的行;同樣的方法建立負樣本名描述檔案negsamples.txt,注意刪除非圖片名的行,每一行為一個檔名,負樣本影象可以是不同的尺寸,但是影象尺寸應該比訓練視窗的尺寸大,因為這些影象將被用於摳取負樣本。


(4)生成正樣本描述檔案
正樣本描述檔案,其實就是一個文字檔案。正樣本描述檔案中的內容包括:檔名 目標個數 目標在圖片中的位置(x,y,width,height),可直接將上一步生成的正樣本圖片名描述檔案中的bmp替換成bmp 1 0 0 28 28即可,如下圖所示:

正樣本描述檔案如下圖所示:

……
正樣本描述檔案中,每一個正樣本佔一行,每一行以正樣本圖片開頭,後面緊跟著該圖片中正樣本的數量(通常為1),以及正樣本在圖片中的位置。

(5)建立正樣本.vec檔案

由於opencv_raincascade訓練的時候需要輸入的正樣本是vec檔案,所以需要使用createsamples程式來將正樣本轉換為vec檔案。
利用OpenCV安裝目錄下bin資料夾裡面的名為opencv_createSamples的可執行程式,該程式可通過命令列啟動,這裡利用bat指令碼檔案createsamples.bat,檔案內容為:

@echo
opencv_createsamples.exe -info positivesamples/possamples.txt -vec positivesamples/possamples.vec -num 5 -w 28 -h 28
pause

需設定正樣本描述檔案所在的路徑(positivesamples/possamples.txt)以及生成的正樣本檔案儲存路徑(positivesamples/possamples.vec)。
其中命令列引數含義為:
-info
描述物體所在影象以及大小位置的描述檔案
-vec
訓練好的正樣本的輸出檔名。
-num
要產生的正樣本的數量,和正樣本圖片數目相同。
-w
輸出樣本的寬度(以畫素為單位)
-h《sample_height》
輸出樣本的高度,以畫素為單位。

(6)訓練級聯分類器
下面是 opencv_traincascade 的命令列引數,以用途分組介紹:

1.通用引數:
-data
目錄名,如不存在訓練程式會建立它,用於存放訓練好的分類器。

-vec
包含正樣本的vec檔名(由 opencv_createsamples 程式生成)。

-bg
背景描述檔案,也就是包含負樣本檔名的那個描述檔案。

-numPos
每級分類器訓練時所用的正樣本數目。

-numNeg
每級分類器訓練時所用的負樣本數目,可以大於 -bg 指定的圖片數目。

-numStages
訓練的分類器的級數。

-precalcValBufSize
快取大小,用於儲存預先計算的特徵值(feature values),單位為MB。

-precalcIdxBufSize
快取大小,用於儲存預先計算的特徵索引(feature indices),單位為MB。記憶體越大,訓練時間越短。

-baseFormatSave
這個引數僅在使用Haar特徵時有效。如果指定這個引數,那麼級聯分類器將以老的格式儲存。

2.級聯引數:
-stageType< BOOST(default) >
級別(stage)引數。目前只支援將BOOST分類器作為級別的型別。

-featureType<{HAAR(default), LBP}>
特徵的型別: HAAR - 類Haar特徵; LBP - 區域性紋理模式特徵。

-w
-h
訓練樣本的尺寸(單位為畫素)。必須跟訓練樣本建立(使用 opencv_createsamples 程式建立)時的尺寸保持一致。

3.Boosted分類器引數:

-bt <{DAB, RAB, LB, GAB(default)}>
Boosted分類器的型別: DAB - Discrete AdaBoost, RAB - Real AdaBoost, LB - LogitBoost, GAB - Gentle AdaBoost。

-minHitRate
分類器的每一級希望得到的最小檢測率。總的檢測率大約為 min_hit_rate^number_of_stages。

-maxFalseAlarmRate
分類器的每一級希望得到的最大誤檢率。總的誤檢率大約為 max_false_alarm_rate^number_of_stages.

-weightTrimRate
Specifies whether trimming should be used and its weight. 一個還不錯的數值是0.95。

-maxDepth
弱分類器樹最大的深度。一個還不錯的數值是1,是二叉樹(stumps)。

-maxWeakCount
每一級中的弱分類器的最大數目。The boosted classifier (stage) will have so many weak trees (<=maxWeakCount), as needed to achieve the given -maxFalseAlarmRate.

4.類Haar特徵引數:

-mode< BASIC (default) | CORE | ALL >
選擇訓練過程中使用的Haar特徵的型別。 BASIC 只使用右上特徵, ALL 使用所有右上特徵和45度旋轉特徵。

5.LBP特徵引數:
LBP特徵無引數。

使用opencv_traincascade.exe檔案進行訓練,首先在當前目錄下新建一個cascades資料夾用於存放生成的.xml檔案。
opencv_traincascade程式的.bat批處理檔案的格式如下:

@echo
opencv_traincascade.exe  -data classifiers -vec positivesamples/possamples.vec -bg negativesamples/negsamples.txt -numPos 2000 -numNeg 10000 -numStages 20 -precalcValbufSize 200 -precalcdxBufSize 1000 -featureType LBP  -w 28 -h 28 -minHitRate 0.995 -maxFalseAlarmRate 0.5 -weightTrimRate 0.95 -maxDepth 1 -maxWeakCount 100 -mode ALL
Pause  

當opencv_traincascade程式訓練結束以後,訓練好的級聯分類器將儲存於檔案cascade.xml中,這個檔案位於 -data 指定的目錄(這裡為cascades資料夾)中。這個目錄中的其他檔案是訓練的中間結果,當訓練程式被中斷後,再重新執行訓練程式將讀入之前的訓練結果,而不需從頭重新訓練。訓練結束後,可以刪除這些中間檔案。