做了一段時間的adaboost訓練乙個可以檢測張開的手掌的檢測器,最後訓練出來的效果不錯,在保證較高的檢測率的情況下還能保持幾乎沒有誤檢的情況出現,adaboost用在物體檢測上的效果讓我大吃一驚。adaboost的特點是誤檢測少,且速度快,因為在檢測的時候採用滑窗法對視窗挨個進行乙個二分類(是手掌或者不是手掌),但是大多數視窗無法通過前面幾個stage的分類器就直接被判斷為負樣本了,因此有著速度快的特點,但是限於檢測過程是在手機端執行的,手機的計算能力不比電腦,所以fps還是會存在一點問題,對此我也進行了相應的方法來加速檢測的過程,以提高檢測速度。這篇部落格分為兩個部分,一部分是如何準備資料集,包括正樣本和負樣本,另乙個部分是如何進行訓練以及訓練過程中一些需要注意的地方。下面開始啦~
一、準備資料集
資料集包括了正樣本和負樣本,正樣本毫無疑問就是真正包括想要檢測的物體。舉個栗子:
截圖工具大概就是qq截圖之類的東西了。。影象的大小可以不一樣,也可以都縮放為乙個尺寸,最好是縮放為乙個尺寸,方便後面準備info.data檔案,但原則上是只要保證正樣本影象中基本恰好包括了想檢測的物體即可。把它們放在乙個叫做pos的資料夾中。我用到的正樣本個數是1400個。正樣本這樣截好圖放在pos資料夾之後就告一段落了,接下來是負樣本。關於負樣本,有一點值得注意,就是負樣本不需要自己去擷取,可以拿任何不包括正樣本影象的大圖作為負樣本,再舉個栗子,我想檢測的是手掌,那麼只要一張中沒有手掌,我就可以把這張拿來當做負樣本的一部分。也就是說,負樣本是大圖而不是截圖,只要這個大圖不包括正樣本。還是拿圖舉個栗子:
現在有了資料集,還差描述這些正負樣本的檔案。正樣本需要乙個叫做info.dat(也可以是info.txt)的檔案,這個檔案表達了什麼含義呢?上個info.dat的圖:
這就可以把檔案所在目錄和檔名的資訊寫到info.dat檔案中,然後再使用文字替換,把info.dat中的所有jpg替換為jpg 1 0 0 24 24,就可以得到上圖info.dat檔案形式了。這下就可以解釋為什麼建議先把所有正樣本縮放到乙個尺寸了,因為方便最後統一替換。現在有了正樣本的描述檔案了,還差負樣本的了,在同樣的工作目錄下開啟終端輸入以下指令:
這樣就可以生成負樣本描述檔案neg.txt,如下圖所示:
還差最後一步就可以完成資料集的準備了。需要opencv中的乙個可執行檔案,叫做opencv_createsamples,可以從opencv的bin目錄中拷貝到工作目錄下,然後開啟終端輸入以下指令:
./opencv_createsamples -info info.dat -vec pos.vec -num 1400 -w 24 -h 24
1400這個數字是你有的正樣本的總數,後面訓練的時候還會涉及到比這個1400少一點的數,是一次訓練中真正使用到的正樣本的個數。-w -h的引數是程式會將你的正樣本縮放到指定的wh尺度,我這裡影象本身就是24*24的,再縮放到24*24。執行這個指令後就可以得到乙個pos.vec檔案,它是乙個二進位制檔案,包含了正樣本資料的畫素值,具體含義參考另一篇部落格。也就是說pos.vec是訓練的時候真正讀取的資料,包括了正樣本的長寬以及畫素值的資訊。下面進行第二步,訓練檢測器:
二、訓練檢測器
在準備好了資料集之後,就要開始訓練檢測器了,用到的工具是opencv提供的可執行檔案opencv_traincascade,同樣可以將其拷貝到工作目錄下面來。然後在工作目錄開啟終端,輸入指令./opencv_traincascade,就可以檢視使用這個可執行檔案需要什麼引數了。如下圖:
下面主要來解釋這些引數的含義,以便我們可以正確的選擇引數。
-data是訓練生成的檢測器存放的目錄,你可以自己在工作目錄下面建乙個叫做cascade的目錄,然後訓練的時候就可以使用這個作為引數填進去,-vec就是正樣本的vec檔案,也就是前面說的pos.vec檔案,-bg是負樣本描述檔案,即neg.txt。中的是可以選擇填的引數,比較重要的有:
-numpos:訓練的時候用到的正樣本的個數 ,這個個數要比你實際擁有的正樣本的個數少個100到200個,因為每乙個stage的分類器會將少量正樣本識別為負樣本,因此需要新的正樣本補充進來,也就是那100到200個,如果你這裡填的-numpos引數是你實際擁有的也就是pos.vec檔案中包含的正樣本個數,那麼當需要補充正樣本的時候你就沒有新的正樣本可以來補充了。我總共有1400個正樣本,所以這裡我可以填寫1200作為訓練時候的正樣本數,留下200個正樣本做替補隊員。
-numneg:訓練的時候用到的負樣本個數,這個個數和你neg.txt中負樣本大的個數沒什麼直接關係,舉個栗子我這裡填的是6000,那麼程式會從neg.txt中的大圖中按照某種規則摳出指定個數以及w和h的小圖作為負樣本,也就是說一張負樣本大圖可以產生數十上百個負樣本小圖,這些小圖才是真正在訓練的時候作為負樣本出現的。乙個經驗的填法是-numneg是-numpos的5倍左右。比例太低導致虛警高,太高了導致檢測率低。正負比為1:5挺合適的。
-numstages:是你想生成多少個stage的分類器,並將它們級聯起來,經驗值是20,也就是預設值。太低了會導致虛警高。
-featuretype:是你可以選擇的特徵的種類,總共3種特徵可以選擇,harr,lbp以及hog。我訓練過手掌和人頭的檢測器,實踐表明,harr特徵往往在adaboost中有著更好的表現,因此這裡我填的是harr,也就是預設值其實可以不填的。
-w -h也就是你想扣出多大的圖作為負樣本。一般正負樣本的尺度保持一致,我這裡使用的24 24。
-bt:全名boost type,即boost的幾種方法,選擇預設的即可,也可以去查下這幾個分別是什麼意思,我查過然後忘記了。。
-minhitrate以及-maxfalsealarmrate。這裡的引數表示的是乙個stage訓練到什麼程度就結束,然後開始訓練下乙個stage呢?標準就是在這個stage的正負樣本中,檢測率不能小於-minhitrate,虛警率不能高於-maxfalsealarmrate。比如這裡我們都採用預設值,-maxfalsealarmrate為0.995,-maxfalsealarmrate為0.5,表示的就是給出1000個正樣本,至少分類器要將其中的995個樣本判斷為正樣本,如果給出1000個負樣本,最多只能將500個判斷為正樣本。
-maxdepth:指的是在乙個stage中會有多個弱分類器,而在opencv中這個弱分類器使用決策樹實現的,這個引數就表示決策樹的最大深度,填1的話表示決策樹就只有乙個節點,也只有一層深。一般填1就可以了。
-maxweakcount:指的是在訓練乙個stage的過程中,如果弱分類器(也就是決策樹)的 數量大於了這個--maxfalsealarmrate引數的但-minhitrate以及-maxfalsealarmrate還沒有達到指標的話,這個stage也會停止訓練,進行下乙個stage的訓練。
-mode:這是選擇了harr特徵之後所獨有的乙個引數,basic、core、all分別含有不同的特徵,但三者是包含關係,也就是all包含了core中的特徵,core包含了basic中的特徵。具體內容可以參考部落格,也可以看下圖:
basic就橫豎的特徵,即1中的ab以及2中的abcd,core在basic的基礎上還包括了傾斜的橫豎特徵,即1,2所有的特徵,all包括了1,2,3中所有的特徵。因此可以根據自己想要檢測的物體的情況選擇這個引數。
在工作目錄開啟終端輸入以下指令即可開始訓練:
./opencv_traincascade -data cascade -vec pos.vec -bg neg.txt -numpos 1200 -numneg 5000 -featuretype harr -w 24 -h 24
訓練時間的話,到後面訓練乙個stage會比前面的stage訓練時間要長,我訓練1000個正樣本和5000個負樣本在i7的筆記本上花了將近20個小時,所以看到訓練程式沒有反應的時候不要擔心,其實是在訓練的,如果程式因為某些原因比如負樣本不夠而停止訓練的話,程式會自己輸出提示資訊的。我也沒有遇到過卡住了不繼續訓練的情況。另外,如果程式在訓練過程中被人為終止了,可以再次輸入上面的指令,會接著上次訓練的結果繼續訓練的。比如上次訓練了6個stage,那麼這次再訓練的話會從第7個stage開始的,只要不去改變cascade目錄下的檔案就行了。最後,祝大家都能訓練出效果好的檢測器吧。再上倆圖:
基於Adaboost檢測的分類器訓練
最近工作遇到了需要檢測影象的問題,需要自己訓練分類器,根據網上的一些參考 mfc基礎入門 基於adaboost演算法的車牌檢測在opencv上的研究與實現 進行了自己的一些嘗試,opencv中提供了兩種訓練函式 opencv haartraining 和 opencv traincascade,具體...
檢測器編寫
大家好我是 噩靈 風雅今天沒事給大家做乙個 用c語言編寫檢測器工具 如果大家需要什麼工具編寫 可以到群裡 找我給我q留言由於在上學所以時間比較少!也可以發郵件找我xingya.4980 163.com當然也可以去我q空間裡我會把寫好的 放在我日誌裡 我空間位址是 另外再給大家推薦乙個免費學習的技術論...
加法檢測器
題目描述 maoge在教小maoge加法,他想計算出小maoge加法的準確度如何,但是因為題目太多了,他算不出來,所以找到了你。資料格式 輸入一行三個數a,b,c。c表示兩個加數和小maoge算出來的答案 a,b,c在0 10000之間 輸出一行乙個字串。如果小maoge算的答案和正確答案的差值在正...