推測(cè)由于渲染引擎問(wèn)題,部分公式渲染不正常,公式完整版請(qǐng)移步個(gè)人博客
1.識(shí)別系統(tǒng)架構(gòu)
以上是Harr特征+級(jí)聯(lián)分類器的識(shí)別系統(tǒng)架構(gòu)圖穷劈,系統(tǒng)分為以下幾個(gè)部分:
- 滑動(dòng)框:固定大小的在原圖上滑動(dòng)的框夸浅,用于獲取子圖
- Harr特征提取器:在子圖上提取指定的四種Harr特征(獲取的特征非常多)
- 級(jí)聯(lián)分類器:基于選定的一些特征,進(jìn)行分類辽话,篩選出正例
對(duì)于該目標(biāo)識(shí)別器肄鸽,將目標(biāo)檢測(cè)問(wèn)題轉(zhuǎn)換為目標(biāo)分類問(wèn)題:滑動(dòng)框在原圖上滑動(dòng),識(shí)別部分識(shí)別每一個(gè)滑動(dòng)子圖油啤,判斷是否為需要識(shí)別的目標(biāo)典徘。
1.1.Harr特征
Harr特征是一類非常簡(jiǎn)單的特征,如下圖所示有四個(gè)框益咬,這四個(gè)框的大小是可變的烂斋,使用黑色部分覆蓋的像素之和減去白色部分覆蓋的像素之和即為Harr特征:
Harr(x) = \sum pic_{black}(x) - \sum pic_{white}(x)
例如以下圖片示意:
取第一個(gè)4x4的區(qū)域數(shù)據(jù)計(jì)算第二種harr特征,被黑色覆蓋的區(qū)域和為3础废,被白色區(qū)域覆蓋的和為2汛骂,因此可獲得基于第二種模板下滑動(dòng)框的harr特征為3-2=1。對(duì)于基于某一個(gè)模板评腺,一個(gè)候選框可取多個(gè)特征帘瞭,例如對(duì)于24x24的滑動(dòng)框,基于第一種模板(對(duì)角線模板)蒿讥,可以在2x2蝶念,3x3,...芋绸,24x24等多個(gè)尺寸取特征媒殉,對(duì)于2x2的特征而言,也可以在24x24的框內(nèi)取23x23個(gè)特征摔敛,因此廷蓉,每個(gè)滑動(dòng)框的harr特征數(shù)量都是海量的,在原論文中马昙,使用20x20的滑動(dòng)框桃犬,每個(gè)滑動(dòng)框有約18k個(gè)特征值刹悴。
1.2.級(jí)聯(lián)分類器
由于Harr特征數(shù)量過(guò)多,已經(jīng)幾乎超過(guò)任何一種機(jī)器學(xué)習(xí)算法的輸入特征數(shù)量極限(2001年)攒暇,因此直接訓(xùn)練一個(gè)分類器是不現(xiàn)實(shí)的土匀,于是使用多個(gè)弱分類器組成一個(gè)強(qiáng)分類器的方法訓(xùn)練。在本系統(tǒng)中形用,每一個(gè)弱分類器只針對(duì)一個(gè)單獨(dú)的特征:
h_j(x) = \begin{cases} 1 & f_j(x) < \theta_j \\ 0 & other \end{cases}
該級(jí)聯(lián)分類器使用AdaBoost方法訓(xùn)練就轧,訓(xùn)練分類器的同時(shí)也篩選特征,最終分類器的級(jí)數(shù)與使用的特征數(shù)量相同(每個(gè)分類器只使用一個(gè)特征)田度。最終的分類器為:
h(x) = \begin{cases} 1 & \sum_\limits{t=1}^{T}a_th_t(x) \geq \frac{1}{2}\sum\limits^T_{t=1}a_t \\ 0 & other \end{cases}
T為級(jí)聯(lián)分類器的數(shù)量钓丰,同時(shí)也是選擇特征的數(shù)量,級(jí)聯(lián)分類器不使用的特征在計(jì)算Harr特征時(shí)可以不計(jì)算以減少計(jì)算量每币;a_t為單個(gè)分類器的權(quán)重携丁,在訓(xùn)練過(guò)程中得到。
2.訓(xùn)練方法
需要訓(xùn)練的部分為級(jí)聯(lián)分類器兰怠,由于每個(gè)弱分類器僅使用一個(gè)特征梦鉴,因此每個(gè)弱分類器的參數(shù)為閾值\theta_j。訓(xùn)練算法如下圖所示:
首先揭保,初始化樣本權(quán)值w_{1,i} = \begin{cases}\frac{1}{2m} & y_i = 0 \\ \frac{1}{2l} & y_i = 1\end{cases}肥橙,其中y_i為當(dāng)前樣本的標(biāo)簽,1表示正例秸侣;m和l為反例和正例的數(shù)量存筏。進(jìn)入訓(xùn)練循環(huán)后,對(duì)于每次迭代:
- 首先標(biāo)準(zhǔn)化樣本權(quán)值w_{t,i} = \cfrac{w_{t,i}}{\sum^n_{j=1}w_{t,j}}
- 根據(jù)每個(gè)特征訓(xùn)練弱分類器h(x)味榛,訓(xùn)練過(guò)程中椭坚,代價(jià)函數(shù)與樣本權(quán)值有關(guān),代價(jià)函數(shù)為\epsilon_j = \sum_iw_i|h_j(x_i)-y_i|搏色。
- 所有特征對(duì)應(yīng)的弱分類器訓(xùn)練完成后善茎,選擇代價(jià)函數(shù)最低的分類器和對(duì)應(yīng)特征,同時(shí)該特征從待選則特征中移除频轿。
- 最后更新樣本權(quán)值:w_{t+1,i} = w_{t,i}\beta_t^{1-e_i}垂涯,其中e_i = \begin{cases}1 & classifid \ correctly \\ 0 & otherwise \end{cases} ;\beta_t = \cfrac{\epsilon_t }{1-\epsilon_t}
最終獲得分類器h(x)和每個(gè)分類器的權(quán)值a_t = log\cfrac{1}{\beta_t}航邢。
3.加速方法
為了達(dá)到較快的檢測(cè)速度耕赘,該系統(tǒng)分別對(duì)計(jì)算Harr特征和級(jí)聯(lián)分類器提出了加速方案
3.1.積分圖
積分圖用于加速計(jì)算Harr特征,其方法是生成一個(gè)與原圖片大小相同的圖膳殷,使用以下公式:
ii(x) = \sum\limits_{x' \leq x,y' \leq y}{i(x',y')}
如下圖所示操骡,積分圖的數(shù)據(jù)為以圖片對(duì)應(yīng)位置和圖片左上角連線為對(duì)角線的矩形覆蓋的所有像素的和。在按行生成計(jì)算圖的過(guò)程中,每個(gè)位置的值可以由計(jì)算圖上方的數(shù)據(jù)和這一行之前的累加與該位置的值相加得到当娱,因此計(jì)算圖的生成比較簡(jiǎn)單吃既。
在計(jì)算harr特征時(shí)考榨,需要計(jì)算大量的一定面積像素和跨细,基于積分圖,若要計(jì)算以下計(jì)算區(qū)域的和河质,僅需要計(jì)算:A-B-C+D即可冀惭,其中ABCD分別為積分圖對(duì)應(yīng)位置的值,因此任何一個(gè)矩形區(qū)域的求和都可以用3次加減法計(jì)算完成掀鹅,有效的加速了Harr特征的提取速度散休。
3.2.級(jí)聯(lián)計(jì)算
在基本級(jí)聯(lián)分類器需要計(jì)算全部所需要的Harr特征,盡管已經(jīng)使用學(xué)習(xí)算法篩選過(guò)乐尊,特征數(shù)量仍然較多戚丸,基于大部分子圖中沒(méi)有需要識(shí)別的物品,提出了級(jí)聯(lián)的方法:
- 在訓(xùn)練篩選分類器時(shí)扔嵌,不選擇誤差最小的分類器限府,而是選擇最少的將正例劃分為反例的分類器,即召回率最高的分類器痢缎。且下一次計(jì)算的樣本集合為使用該分類器剔除反例的樣本集合胁勺。
- 運(yùn)行時(shí),順序計(jì)算特征-分類独旷,當(dāng)樣本被一個(gè)分類器識(shí)別為反例時(shí)署穗,直接拒絕該樣本,后續(xù)的特征和分類都可以不被計(jì)算嵌洼。
4.代碼實(shí)踐
4.1.使用自帶級(jí)聯(lián)分類器
OpenCV自帶了一些級(jí)聯(lián)分類器案疲,可以用于識(shí)別人臉,五官和人體等等麻养,在Python下使用方法如下:
face_cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_frontalface_alt2.xml")
faces = face_cascade.detectMultiScale(
gray, scaleFactor=1.3, minNeighbors=2, minSize=(60, 60), maxSize=(300, 300))
首先調(diào)用cv2.CascadeClassifier()
打開(kāi)一個(gè)級(jí)聯(lián)分類器络拌,這里載入的xml為OpenCV自帶的人臉識(shí)別級(jí)聯(lián)分類器,隨后調(diào)用.detectMultiScale()
方法進(jìn)行識(shí)別回溺,參數(shù)含義為:
- 第一個(gè)參數(shù)image:待識(shí)別圖片春贸,必須是灰度圖片(channel=1)
- scaleFactor:被檢測(cè)對(duì)象的尺度變化,合理范圍1.1~1.4遗遵,該參數(shù)越大檢測(cè)越細(xì)致萍恕,速度越慢
- minNeighbors:每個(gè)候選框需要保持多少個(gè)領(lǐng)域,該參數(shù)越大车要,一個(gè)候選框被接受越困難
- minSize和maxSize:目標(biāo)的最小尺寸和最大尺寸允粤,當(dāng)目標(biāo)超過(guò)這一范圍時(shí)無(wú)法識(shí)別
該函數(shù)返回一個(gè)list,其中每個(gè)元素為一個(gè)有4個(gè)元素的list,分別是[x,y,w,h]类垫,可直接用于繪制矩形框司光。
4.2.訓(xùn)練級(jí)聯(lián)分類器
選擇FDDB數(shù)據(jù)集訓(xùn)練針對(duì)人臉的級(jí)聯(lián)分類器
4.2.1.處理標(biāo)簽
FDDB的標(biāo)注方式是橢圓形標(biāo)注,提供橢圓形的中心悉患,長(zhǎng)短軸和角度信息残家,原label為<major_axis_radius minor_axis_radius angle center_x center_y detection_score>,先要將label轉(zhuǎn)為<left_x top_y width height>的格式售躁∥牖矗考慮簡(jiǎn)便,使用以下公式:
left\_x = clamp(center\_x - minor\_axis\_radius,0,-1) \\ top\_y = clamp(center\_y - major\_axis\_radius,0,-1) \\ width = 2 \times minor\_axis\_radius \\ height = 2 \times major\_axis\_radius
該公式簡(jiǎn)單的將橢圓轉(zhuǎn)為矩形陪捷,clamp為鉗位函數(shù)回窘,將輸入限制在0~-1,-1表示不限制市袖。同時(shí)限制矩形的范圍一定在圖片范圍中啡直。代碼如下:
def FDDB2label(source_path, target_path):
source_list = read_ellipseList(source_path) //讀取原有l(wèi)abel文件
target_list = change_label(source_list) //轉(zhuǎn)換label格式
save_rec_label(target_list, target_path) //保存label格式
轉(zhuǎn)換label的部分如下:
def change_label(source):
"""source:list[[path,label],...],label:[major_axis_radius minor_axis_radius angle center_x center_y detection_score]"""
result = []
for name, label in source:
name = name + ".jpg"
data = [float(x) for x in label.replace(" ", ' ').split(' ')]
data = [int(data[3] - data[1]), int(data[4] - data[0]),
int(data[1] * 2), int(data[0] * 2)]
data = check_label(name, data, root="../FDDB-folds/")
result.append(
[name, data])
return result
檢查部分如下:
def check_label(name, data, root=""):
img_shape = cv2.imread(os.path.join(root, name)).shape
if data[0] < 0:
data[0] = 0
if data[1] < 0:
data[1] = 0
if data[0] + data[2] > img_shape[1]:
data[2] = img_shape[1] - data[0] - 1
if data[1] + data[3] > img_shape[0]:
data[3] = img_shape[0] - data[1] - 1
return data
共檢查兩種情況:
- 物品左上角坐標(biāo)小于0
- 物品右下角坐標(biāo)超過(guò)圖片限制
4.2.2.準(zhǔn)備文件
訓(xùn)練前需要準(zhǔn)備數(shù)據(jù),包括正例和反例苍碟。
4.2.2.1.準(zhǔn)備正例
正例使用opencv自帶的opencv_createsamples.exe
生成酒觅,注意該exe文件不可獨(dú)立運(yùn)行,因此不能拷貝出來(lái)使用驰怎,其依賴OpenCV的其他文件阐滩,因此必須從OpenCV中調(diào)用(opencv\build\x64\vc14\bin\opencv_createsamples.exe
),該工具將正例轉(zhuǎn)為.vec文件县忌,主要有以下命令行參數(shù):
-
-vec
:輸出vec文件的路徑 -
-info
:正例描述文件路徑 -
-num
:生成的正例數(shù)量 -
-w
和-h
:正例圖片的長(zhǎng)寬
使用之前掂榔,需要準(zhǔn)備一個(gè)描述正例文件的文件info.dat
,其格式如下:
FDDB-folds\2002\08\11\big\img_591.jpg 1 184 38 171 247
FDDB-folds\2002\07\19\big\img_423.jpg 1 196 46 118 174
FDDB-folds\2002\08\24\big\img_490.jpg 1 110 23 70 109
<相對(duì)路徑> <目標(biāo)數(shù)量n> <目標(biāo)1的x,y,w,h> ... <目標(biāo)n的x,y,w,h>
隨后使用該工具症杏,生成正例文件pos.vec装获。
.\opencv\build\x64\vc14\bin\opencv_createsamples.exe -vec .\pos.vec -info info.dat -num 178 -w 40 -h 40
4.2.2.2.準(zhǔn)備反例
對(duì)于反例,反例只需要準(zhǔn)備一個(gè)文件列表neg_list.dat
即可:
.\dataset\negtive\neg_img2698.jpg
.\dataset\negtive\neg_img2699.jpg
.\dataset\negtive\neg_img2700.jpg
<相對(duì)路徑>
4.2.3.模型訓(xùn)練
模型訓(xùn)練使用OpenCV的opencv_traincascade.exe
厉颤,主要的參數(shù)如下:
-
-data
:最終保存分類器文件的位置 -
-vec
:正例vec文件的路徑 -
-bg
:反例文件列表的路徑 -
-numPos
和-numNeg
:正例和反例的數(shù)量 -
-numStages
:多層分類器的層數(shù) -
-w
和-h
:正例文件的長(zhǎng)寬穴豫,必須和生成樣本時(shí)填入的對(duì)應(yīng)長(zhǎng)寬相同
本次使用的命令行參數(shù)如下圖所示:
.\opencv\build\x64\vc14\bin\opencv_traincascade.exe -data . -vec .\pos
.vec -bg .\neg_list.dat -numPos 178 -numNeg 200 -numStages 10 -w 40 -h 40
最終訓(xùn)練的模型會(huì)保存在-data/cascade.xml
中。
4.2.4.模型測(cè)試
可以使用官方提供的測(cè)試工具opencv_visualisation.exe
測(cè)試逼友,該工具會(huì)可視化測(cè)試過(guò)程并打印使用的分類器的類型精肃,命令行參數(shù)如下:
-
--image
:用于測(cè)試的圖片路徑 -
--model
:用于測(cè)試的模型(.xml文件) -
--data
:保存測(cè)試結(jié)果的路徑(可選)
官方給出的例子如下:
.\opencv\build\x64\vc14\bin\opencv_visualisation --image=\data\object.png --model=\
data\model.xml --data=\data\result\
參考文獻(xiàn)
理論部分:Viola P, Jones M. Rapid object detection using a boosted cascade of simple features[C]// IEEE Computer Society Conference on Computer Vision & Pattern Recognition. IEEE Computer Society, 2001:511.
實(shí)踐部分:OpenCV官方教程——訓(xùn)練級(jí)聯(lián)分類器