級(jí)聯(lián)分類器
執(zhí)行訓(xùn)練的時(shí)候會(huì)輸出一系列的參數(shù)满粗,其中可以看到:【stageType: BOOST】
。boosting算法涉及到弱分類器和強(qiáng)分類器的概念。弱分類器分類正確率較低青扔,但是較容易獲得,強(qiáng)分類器分類正確率較高翩伪,但是較難獲得微猖。只要樣本充足,弱學(xué)習(xí)可以通過一定的組合獲得任意精度的強(qiáng)學(xué)習(xí)缘屹。級(jí)聯(lián)分類器就是 N個(gè)弱分類器 以級(jí)聯(lián)的方式凛剥,從簡單到復(fù)雜逐步串聯(lián)而成。
可以用決策樹來構(gòu)建一個(gè)簡單的弱分類器轻姿, 將提取到的特征與分類器的特征進(jìn)行逐個(gè)比較犁珠,從而判斷該特征是否屬于人臉:
而強(qiáng)分類器相當(dāng)于先讓各個(gè)弱分類器進(jìn)行投票,然后讓投票結(jié)果根據(jù)各弱分類器的錯(cuò)誤率進(jìn)行加權(quán)相加互亮,最后與平均的投票結(jié)果進(jìn)行比較得到最終結(jié)果犁享。
訓(xùn)練
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/user_guide/ug_traincascade.html
正樣本:包含人臉的圖片,灰度圖。 正樣本大斜荨:統(tǒng)一大小并且不能小于負(fù)樣本 負(fù)樣本:不包含人臉的圖片 負(fù)樣本大写独ァ:無所謂
正、負(fù)樣本個(gè)數(shù)比列大約為 1: 3
制作正樣本
正樣本目錄為:pos
假設(shè)目錄結(jié)構(gòu)如下:
/pos
0.jpg
1.jpg
pos.txt
文件pos.txt里的內(nèi)容如下:
#分別表示 1張人臉 ;人臉從 0,0坐標(biāo)開始凤巨;大小為24x24
pos/0.jpg 1 0 0 24 24
#2個(gè)人臉视乐; 人臉分別為 100,200處的50x50 和 50,30處的25x25為人臉
pos/1.jpg 2 100 200 50 50 50 30 25 25
#這部分內(nèi)容可以使用java 程序來修改,如增加"pos/"
執(zhí)行:(opencv環(huán)境變量配置opencv\build\x64\vc15\bin到path里)
這里生成樣本的opencv_createsamples.exe以及后面訓(xùn)練級(jí)聯(lián)器用到opencv_traincascade.exe在opencv 3.4.7版本以后被移除了,需要下載舊版本的opencv來進(jìn)行訓(xùn)練敢茁,訓(xùn)練結(jié)果與版本無關(guān)佑淀,可以在opencv 4.x的版本上使用。
opencv_createsamples -info pos.txt -vec pos.vec -num 100 -w 24 -h 24
-info: 正樣本描述
-vec : 輸出的正樣本向量
-num : 正樣本數(shù)量
-w -h: 輸出樣本的大小
#輸出:Done. Created 100 samples 表示成功生成100個(gè)樣本
制作負(fù)樣本
負(fù)樣本與正樣本執(zhí)行一樣的操作卷要,假如目錄結(jié)構(gòu)如下:
/neg
0.jpg
1.jpg
neg.txt
則neg.txt文件中的內(nèi)容將如下所示:
neg/0.jpg
neg/1.jpg
訓(xùn)練
創(chuàng)建一個(gè)data 目錄渣聚,執(zhí)行:
opencv_traincascade -data data -vec pos.vec -bg neg.txt -numPos 100 -numNeg 300 -numStages 15 -featureType LBP -w 24 -h 24
?
-data : 需要手動(dòng)創(chuàng)建,生成的結(jié)果 訓(xùn)練的模型會(huì)輸出到這個(gè)目錄
-vec : 正樣本
-bg : 負(fù)樣本
-numPos :每級(jí)分類器訓(xùn)練時(shí)所用到的正樣本數(shù)目
-numNeg :每級(jí)分類器訓(xùn)練時(shí)所用到的負(fù)樣本數(shù)目僧叉,可以大于-bg數(shù)目
-numStages:訓(xùn)練分類器的級(jí)數(shù)奕枝,如果層數(shù)多,分類器的誤差就更小瓶堕,但是檢測速度慢隘道。(15-20)
-featureType: 特征類型(LBP)
-w -h 樣本寬高
?
輸出:
Training until now has taken 0 days 0 hours 0 minutes 10 seconds.
表示成功
?
輸出:
Required leaf false alarm rate achieved. Branch training terminated.
表示成功,但是誤檢率已經(jīng)達(dá)標(biāo)。(樣本太少了)
?
輸出:
Bad argument < Can not get new positive sample. The most possible reason is insufficient count of samples in given vec-file.
則意味著錯(cuò)誤郎笆。
?
?
minHitRate:分類器的每一級(jí)希望得到的最小檢測率谭梗。當(dāng)設(shè)置為0.995時(shí)如果正訓(xùn)練樣本個(gè)數(shù)為100個(gè),那么其中的0.5個(gè)就很可能不被檢測宛蚓,第二次選擇的時(shí)候必須多選擇后面的5個(gè)激捏,按照這種規(guī)律我們?yōu)楹竺娴拿考?jí)多增加numPosminHitRate個(gè)正樣本.
實(shí)際準(zhǔn)備的正樣本數(shù)量應(yīng)該(讀入vec的正樣本數(shù)) >= numPos + (numStage - 1) * numPos * (1 - minHitRate)
按照此公式計(jì)算: x+14x0.005 = 1.07x ,也就是正樣本數(shù)量要大于等于 1.07*x 而我們正樣本是100,所以x = 93.45凄吏,但是此處傳100也可以远舅。
因?yàn)閷?shí)際的檢測率會(huì)比minHitRate高,所以在設(shè)置numPos時(shí)可以將其設(shè)置的稍微再大些痕钢,最終的目的是要盡量讓所有的正樣本都參與到訓(xùn)練中图柏。但是,過大就會(huì)出錯(cuò)任连。
//人臉樣本采集
for (Rect face : faces) {
rectangle(img, face, Scalar(255, 0, 255));
#ifdef COLECT_SAMPLES //采集樣本
Mat sample;
frame(face).copyTo(sample);
resize(sample, sample, Size(24, 24));
cvtColor(sample, sample, COLOR_BGR2GRAY);
char p[100];
sprintf(p, "C:/Users/Administrator/Desktop/opencv/train/face/pos/%d.jpg", i++);
imwrite(p, sample);
#endif
}