機器學習 基於級聯分類器的多目標檢測

2021-09-24 11:46:36 字數 3373 閱讀 1957

2019獨角獸企業重金招聘python工程師標準》

當然了,作為有理想有抱負的碼農,用現成的分類器是不會滿足的。現實使用中我們經常需要訓練針對各種應用的分類器。下面介紹如何訓練乙個自己的級聯分類器。整個過程大致可分為以下幾步(基於opencv 2.4.4):

1. 收集資料

資料可分為正樣本和負樣本。正樣本即要檢測的目標,負樣本則不包含目標。

首先我們要生成正負樣本的索引(或稱描述檔案)。正樣本描述檔案官方文件中給了例子:

依次為檔名,目標個數,目標座標。既然是基於統計的方法,樣本自然要求很多(一般以千為單位),因此很多時候這一步是勞力活。當然,勤勞勇敢的碼農們寫了各種工具來解放生產力。這些描述檔案可以人肉生成,也可用object marker(來圈,然後自動生成。除此之外還有些其它工具:

另外後面會講到的createsamples工具還可以自動生成正樣本。

負樣本沒這麼麻煩了,描述檔案只要包含檔案路徑即可,windows中可以用dir /s /b生成,linux下用find命令。

2. 建立vec檔案

createsamples 工具可用於從正負樣本描述檔案生成訓練程式需要的vec檔案。如根據樣本描述檔案samples.txt生成samples.vec:

opencv_createsamples.exe -info samples.txt -vec samples.vec -w 20 -h 20

它還包含乙個功能,通過distortion自動生成樣本。如根據template.png和負樣本描述檔案negative.txt生成3000個樣本。

opencv_createsamples.exe  -img template.png -vec -num 3000 -bg negative.txt -vec samples.vec -w 20 -h 20

還有種很尷尬的情況,就是既沒空圈那麼多的正樣本,又想檢測多種目標,咋辦?因為上面提到的通過distortion來自動生成樣本的方法不支援多個目標。一種方法是先根據多個目標生成多個vec檔案,再用mergevec(這個工具合併vec檔案。mergevec用最新的opencv編譯不了,如果你和我一樣懶不想移植的話就下個opencv 1.0(就下可執行檔案包,3m多那個),把那坨dll放到path裡,然後下mergevec.exe就可以跑了。如根據template1.png ~ template3.png分別生成三個vec檔案:

opencv_createsamples.exe -img template1.png -num 1000 -bg negative -vec sample1.vec -w 20 -h 20

opencv_createsamples.exe -img template2.png -num 1000 -bg negative -vec sample2.vec -w 20 -h 20

opencv_createsamples.exe -img template3.png -num 1000 -bg negative -vec sample3.vec -w 20 -h 20

接著寫vec的索引檔案sample.txt:

sample1.vec

sample2.vec

sample3.vec

然後就可以生成最終的samples.vec檔案了:

mergevec.exe sample.txt samples.vec -w 20 -h 20

另外,如果你的應用比較general,如從自然背景中找特定目標,網上有現成的負樣本資料集:

svn checkout tutorial-haartraining-read-only

3. 訓練分類器

很多地方還是用haartraining,官方手冊中建議用新的traincascade。用法上引數什麼的都差不多,不過還是有差別。

根據剛才生成的樣本描述檔案進行訓練,結果放在classifier目錄裡:

opencv_traincascade.exe -data classifier -vec samples.vec -bg negative.txt -numstages 25 -w 20 -h 20

其餘有一坨引數,諸如maxfalsealarmrate,minhitrate等想設就設下,不過預設的值大多數情況都是挺好的選擇。

-featuretype指定特徵型別,預設為類haar特徵,還可以指定為lbp或hog。基於haar的級聯分類器訓練時間一般很長(以天為單位)。lbp,hog則快得多。

注意這畢竟不是產品,很多時候引數一給不好就掛掉了。當然直接掛掉是最好的情況,最慘的是跑到中間hung住了,都不知道是因為hung住了還是因為訓練時間長。。。

注:無論是haartraining還是traincascade,最終都會生成表示成xml檔案的分類器。但如果你用的是haartraining並且想用中間stage生成的分類器,可以用convert_cascade將中間結果整成xml檔案。

4. 測試&驗證

performance.exe可以對於給定的測試用例給出檢測率報告。注意只對opencv_haartraining的結果適用。如果要寫報告給資料這個很有用。不過這裡先不整這麼抽象的東西,先寫個程式直觀地看看檢測效果如何。官方例程中的objectdetection是從攝像頭抓幀進行檢測。這裡我們略微修改下從檔案讀取然後檢測目標。其中關鍵函式為:

void cascadeclassifier::detectmultiscale(const mat& image, vector& objects, double scalefactor=1.1, int minneighbors=3, int flags=0, size minsize=size(), size maxsize=size())

其中的引數對於檢測結果會有較大影響,如:

minneighbors:其實分類器給出的結果是很多個矩形,那些被多個矩陣覆蓋的區域被保留,而那些個孤立的矩陣被拋棄。這個引數決定了保留還是拋棄的閾值。(

minsize :檢測目標size的閥值,小於它的不會被檢測出來。

這裡拿」憤怒的小鳥「作個簡單的例子,因為每個關卡中籠子裡的鳥雖不完全相同,但都類似。這裡以一關中籠子中的鳥為訓練正樣本,讓其學習並檢測其它關卡中哪些是籠中鳥。

在一些case中還是有不少false alarm的。直觀上可能會覺得這種動畫的檢測會更容易,但動畫由於背景形狀規則,色塊均勻,作為負樣本並不好,所以負樣本盡可能還是要取得變化豐富些。

基於級聯分類器的目標檢測objdect

opencv支援的目標檢測的方法是利用樣本的haar特徵進行的分類器訓練,得到的級聯boosted分類器 cascade classification 注意,新版本的c 介面除了haar特徵以外也可以使用lbp特徵。先介紹一下相關的結構,級聯分類器的計算特徵值的基礎類featureevaluator...

基於Opencv的多目標跟蹤

python實現 import cv2 import sys major ver,minor ver,subminor ver cv2.version split print major ver,minor ver,subminor ver if name main 建立 boosting mil ...

基於Halcon的多目標模板匹配演算法

1.基於灰度值的模板匹配基本原理 模板匹配,顧名思義,需要乙個模板。然後在影象中尋找與模板能匹配得上的區域。halcon中,基於灰度值的模板匹配的演算法中,演算法的基本原理比較簡單,就是簡單的灰度比對。找出灰度值與模板區域相近的區域作為找到的目標區域,具體演算法如下 即,當error滿足閾值時,則該...