opencv学习笔记——自己训练人脸识别分类器
???????在使用opencv自帶的分類器haarcascade_frontalface_alt.xml進行人臉識別的基礎認識后,決定自己訓練一個分類器看一下效果。該過程大致可分為三個階段:樣本采集、分類器訓練和運用訓練好的分類器進行人臉檢測。
1、樣本的采集
????? ?在訓練前,我們需要進行正樣本及負樣本的采集。
????? ?正樣本采用的是ORL人臉數據庫中的部分圖像,本次共選用63張圖像,初始圖像大小為92*112,但在訓練時出現了內存不足的問題,因此將其尺寸歸一化為20*20。部分截圖如下:
???????負樣本采用的是weizmann團隊http://www.wisdom.weizmann.ac.il/~vision/Seg_Evaluation_DB/dl.html 網站上的圖像分割數據庫里面的灰色圖像,總共200幅圖片,大小大約在300*200像素,截圖如下所示:
???????圖像采集完畢后,將其分別放在兩個文件夾pos_img(正樣本)和neg_img(負樣本)下。再新建一個xml文件夾,xml文件夾存放后面訓練過程中產生的數據模型,最后opencv會將其轉換生成一個xml文件,也就是最終的分類器。
???????然后,從OpenCv安裝目錄中查找出如下兩個exe可執行文件:
opencv_createsamples.exe:用于創建樣本描述文件,后綴名是.vec。專門為OpenCV訓練準備,只有正樣本需要,負樣本不需要。?
opencv_haartraining.exe:是OpenCV自帶的一個工具,封裝了haar特征提取以及adaboost分類器訓練過程。?
???????一般來說,正負樣本數目比例為1:3時訓練結果較好,但是不是絕對。由于每個樣本的差異性不同等因素,所以沒有絕對的比例關系。但是負樣本需要比正樣本多,因為原則上說負樣本的多樣性越大越好,我們才能有效降低誤檢率,而不僅僅是通過正樣本的訓練讓其能識別物體。在本次訓練中,我選擇了63個正樣本和200個負樣本,均為灰度圖像。
???????樣本準備完畢后,打開Windows下的命令行窗口cmd,進入指定目錄下。
在當前pos_img目錄下生成一個pos.txt記錄所有圖片的名稱。?
打開該txt文件,將pos.txt去掉,并將pgm 改為pgm 1 0 0 20 20。
這里1表示當前圖片重復出現的次數是1, 0 0 20 20表示目標圖片大小是矩形框從(0,0)到(20,20)。?
同理,進入neg_img目錄,生成neg.txt,然后打開文件去掉neg.txt,其余不做改動。
結束后將pos.txt和neg.txt拷出,與opencv_createsamples.exe文件放在一個目錄下:
2、使用opencv_createsamples.exe建立訓練需要的參數列表
???????Windows控制臺進入指定目錄下,我們之前已經在目錄下放了opencv_createsamples.exe文件,在控制臺下輸入opencv_createsamples.exe可以得到各參數信息:?
在命令行窗口輸入:
則在當前目錄下,產生一個pos.vec文件。
指令介紹:
-vec pos.vec:指定生成的文件,最終生成的就是pos.vec;?
-info pos_img\pos.txt:目標圖片描述文件,在pos\pos.txt;?
-bg neg_img\neg.txt:背景圖片描述文件,在neg\neg.txt;?
-w 20:輸出樣本的寬度,20;?
-h 20:輸出樣本的高度,20;?
-num 63:要產生的正樣本數量,63;
3、訓練模型
???????Windows控制臺進入指定目錄下,我們之前已經在目錄下放了opencv_haartraining.exe文件,在控制臺下輸入opencv_haartraining.exe可以得到各參數信息:?
然后輸入指令進行訓練:
指令介紹:
-vec pos.vec:正樣本文件名;?
-bg neg_img\neg.txt:背景描述文件;?
-data xml:指定存放訓練好的分類器的路徑名,也就是前面建立的xml文件夾;?
-w 20:樣本圖片寬度,20;?
-h 20:樣本圖片高度,20;?
-mem 1024:提供的以MB為單位的內存,很明顯,這個值越大,提供的內存越多,運算也越快;?
-npos 45:取45個正樣本,小于總正樣本數;?
-neg 180:取180個負樣本,小于總負樣本數;?
-nstages 5:指定訓練層數,層數越高耗時越長;?
-nsplits 5:分裂子節點數目, 默認值 為2;(本來設置為5 ,但訓練時一直出差錯,改為默認值后可正常訓練)。
在這里-npos ?-neg 兩個參數若直接與正負樣本總數相同,則在訓練過程中會出現錯誤:訓練中途,程序突然終止,提示"OpenCV Error: Assertion failed (elements_read == 1) in icvGetHaarTraininDataFromVecCallback, file ..\..\..\..\opencv\apps\haartraining\cvhaartraining.cpp, line 1861"。-npos的意思是每次訓練從.vec文件中隨機選取npos個正樣本。由于存在虛警,在每一次訓練一個強分類器之后,會把那些分類錯誤的從整個樣本庫中剔除掉,總的樣本就剩下 CountVec = CountVec - (1 - minhitrate)* npos,在第二個強分類器的訓練過程中就是從剩下的Countvec抽樣,一直這樣進行nstage次,所以就有CountVec >= (npos + (nstages - 1)*(1 -minhitrate) * npos ) + nneg 。當把npos設置與vec中總樣本數相同時,第二個強分類器訓練時,必然就會報錯,提示樣本數不足。只要將取值改小即可。
接下來要做的就是等待訓練結束:
訓練過程參數解釋:
N:層數 ?%
SMP:樣本的使用率?
F : +表示通過翻轉,否則是-
ST.THR : 分類器的閾值?
HR:當前分類器 對正樣本識別正確的概率
FA:當前分類器 對負樣本識別錯誤的概率
EXP.ERR : 分類器的期望錯誤率
訓練結束后會在根目錄下生成xml.xml文件,在xml文件夾下生成最終的分類器:
4、測試
????? ?用自己訓練的分類器替換opencv自帶的分類器進行人臉識別:
因為訓練的樣本過少,分類器的層數也不多,分類效果并不好,還有待提高。
總結
以上是生活随笔為你收集整理的opencv学习笔记——自己训练人脸识别分类器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 测度上Lebesgue积分的确定
- 下一篇: 58.什么是深度学习中的anchor