1. 程式人生 > >OpenCV學習記錄(二):自己訓練haar特徵的adaboost分類器進行人臉識別

OpenCV學習記錄(二):自己訓練haar特徵的adaboost分類器進行人臉識別

上一篇文章中介紹瞭如何使用OpenCV自帶的haar分類器進行人臉識別(點我開啟)。
這次我試著自己去訓練一個haar分類器,前後花了兩天,最後總算是訓練完了。不過效果並不是特別理想,由於我是在自己的筆記本上進行訓練,為減少訓練時間我的樣本量不是很大,最後也只是勉強看看效果了。網上有關的資料和部落格可以說很多了,只要耐心點總是能成功的。

採集樣本:

首先要訓練,就得有訓練集。網上有很多國外高校開源的庫可供下載:
1、卡耐基梅隆大學影象資料庫(點我開啟
2、MIT人臉資料庫(點我開啟
3、ORL人臉資料庫(點我開啟
由於是國外的網站,可能需要翻牆,所以下載可能會有些麻煩。這裡給出了我在網上收集的訓練集,正樣本為20*20的人臉圖片,負樣本為50*50的背景圖片。樣本集下載地址:

http://download.csdn.net/detail/hongbin_xu/9887672

準備工作:

在指定目錄中放入以下所提到的資料夾及檔案。
將正樣本放在pos資料夾中,負樣本放在neg資料夾中,xml資料夾存放後面訓練過程中產生的資料模型,最後opencv會將其轉換生成一個xml檔案,也就是最終的分類器。
這裡寫圖片描述
從OpenCv安裝目錄中查找出如下兩個exe可執行檔案。
這裡寫圖片描述
opencv_createsamples.exe:用於建立樣本描述檔案,字尾名是.vec。專門為OpenCV訓練準備,只有正樣本需要,負樣本不需要。
opencv_haartraining.exe:是OpenCV自帶的一個工具,封裝了haar特徵提取以及adaboost分類器訓練過程。
一般來說,正負樣本數目比例在1:3的時候訓練結果比較好,但是不是絕對。由於每個樣本的差異性不同等因素,所以沒有絕對的比例關係。但是負樣本需要比正樣本多,因為原則上說負樣本的多樣性越大越好,我們才能有效降低誤檢率,而不僅僅是通過正樣本的訓練讓其能識別物體。為了節約時間,我選了1500個正樣本和4500個負樣本。

獲取樣本路徑列表:

開啟Windows下的命令列視窗,進入指定目錄下。

1、建立正樣本的描述檔案:
首先進入pos資料夾中,輸入:

dir /b > pos.txt
  • 1

在當前pos目錄下生成一個pos.txt記錄所有圖片的名稱。
這裡寫圖片描述

開啟記事本,去除pos.txt最後一行的pos資料夾;
將所有jpg替換成 jpg 1 0 0 20 20。這裡1表示當前圖片重複出現的次數是1, 0 0 20 20表示目標圖片大小是矩形框從(0,0)到(20,20)。
這裡寫圖片描述

2、建立負樣本的描述檔案:
接下來重新進入neg資料夾,輸入:

dir /b > neg.txt
  • 1

之後,生成neg.txt檔案,這裡負樣本不做其他修改。
這裡寫圖片描述

3、使用opencv_createsamples.exe建立訓練需要的引數列表:
Windows控制檯進入指定目錄下,我們之前已經在目錄下放了opencv_createsamples.exe檔案,在控制檯下輸入opencv_createsamples.exe可以得到各引數資訊:
這裡寫圖片描述
在當前目錄下輸入如下指令:

opencv_createsamples.exe -vec pos.vec -info pos\pos.txt -bg neg\neg.txt -w 20 -h 20 -num 1500 ;
  • 1

當前目錄下,產生了pos.vec檔案。
這裡寫圖片描述
簡要介紹指令:

-vec pos.vec:指定生成的檔案,最終生成的就是pos.vec;
-info pos\pos.txt:目標圖片描述檔案,在pos\pos.txt;
-bg neg\neg.txt:背景圖片描述檔案,在neg\neg.txt;
-w 20:輸出樣本的寬度,20;
-h 20:輸出樣本的高度,20;
-num 1500:要產生的正樣本數量,1500;

訓練模型:

Windows控制檯進入指定目錄下,我們之前已經在目錄下放了opencv_haartraining.exe檔案,在控制檯下輸入opencv_haartraining.exe可以得到各引數資訊:
這裡寫圖片描述
輸入如下指令進行訓練:

opencv_haartraining.exe -vec pos.vec -bg neg\neg.txt -data xml -w 20 -h 20 -mem 1024 -npos 1000 -neg 3000 -nstages 2 -nsplits 5
  • 1

簡要介紹指令:

-vec pos.vec:正樣本檔名;
-bg neg\neg.txt:背景描述檔案;
-data xml:指定存放訓練好的分類器的路徑名,也就是前面建立的xml資料夾;
-w 20:樣本圖片寬度,20;
-h 20:樣本圖片高度,20;
-mem 1024:提供的以MB為單位的記憶體,很明顯,這個值越大,提供的記憶體越多,運算也越快;
-npos 1000:取1000個正樣本,小於總正樣本數;
-neg 3000:取3000個負樣本,小於總負樣本數;
-nstages 2:指定訓練層數,層數越高耗時越長;
-nsplits 5:分裂子節點數目, 預設值 為2;

其他引數:

-minhitrate:最小命中率,即訓練目標準確度;
-maxfalsealarm:最大虛警(誤檢率),每一層訓練到這個值小於0.5時訓練結束,進入下一層訓練;
-sym或者-nonsym:臉是否垂直對稱,若是,則選前者,且可以加快訓練速度。

輸入指令之後就是等待了,最後可以看到結果如下:
這裡寫圖片描述
這裡我的層數太少了,導致訓練結果不是很好,一般要增加到15~20層才能有較好的效果。

中間可能遇到的問題:

可能在訓練的過程中,過了很長時間但是卻一直停留在某一層不動,上網查詢解決辦法如下:增大負樣本數目,增大負樣本之間的變化! 增加負樣本,然後重新接著訓練,注意更改負樣本的數目。
詳細說明可以檢視:http://blog.csdn.net/jimeshui/article/details/42039615

--------------------- 本文來自 hongbin_xu 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/hongbin_xu/article/details/74203215?utm_source=copy