Adaboost
Boosting 指的是通過結(jié)合一些精度較低的弱學(xué)習(xí)器來獲得較高精度的方法,弱學(xué)習(xí)器指的是表現(xiàn)比隨即猜測(cè)稍微好一些的學(xué)習(xí)器。
AdaBoost是Adaptive Boosting的縮寫领追。主要思想是維持訓(xùn)練集上的權(quán)重分布。最初馅而,所有訓(xùn)練樣本的權(quán)重均等設(shè)置,但每輪之后會(huì)增加未被正確分類的示例權(quán)重包吝,以使弱學(xué)習(xí)器不得不將注意力集中在訓(xùn)練困難的樣本上。最終的輸出結(jié)果為所有弱分類器的加權(quán)和源葫。
Adaboost的算法的偽代碼如下:
輸入: 樣本
初始化樣本權(quán)重分布
For :
- 用一個(gè)弱分類器在當(dāng)前權(quán)重分布的樣本上訓(xùn)練
- 計(jì)算錯(cuò)誤率
,
是弱分類器的預(yù)測(cè)結(jié)果
- 計(jì)算分類器權(quán)重
- 更新樣本權(quán)重:
息堂,這里的
是一個(gè)歸一化因子
輸出:
Viola-Jones目標(biāo)檢測(cè)算法
Viola-Jones目標(biāo)檢測(cè)是第一個(gè)可以實(shí)時(shí)處理并有著很好檢測(cè)率的目標(biāo)檢測(cè)算法嚷狞,主要用于圖像中的人臉檢測(cè)。
這個(gè)算法使用正面的面部圖像荣堰,整個(gè)面部必須正對(duì)相機(jī)床未,算法是基于眼睛,鼻子的位置來估計(jì)人臉圖像振坚。
這個(gè)算法主要分為四個(gè)階段:
- 選擇haar-like的特征
- 創(chuàng)建積分圖
- 使用AdaBoost進(jìn)行訓(xùn)練
- 創(chuàng)建分類器級(jí)聯(lián)
Haar-like的特征是什么東西薇搁?
人臉上的五官都是有固定位置,額頭下面是眉毛和眼睛渡八,鼻子下面是嘴啃洋,長(zhǎng)成這樣的可能不是人,但是人一定是這么長(zhǎng)的屎鳍。
在上面的灰度圖中宏娄,白色框里的額頭部分的亮度總體上來說要比黑色框里的亮度更高,因?yàn)楹谏蚶锇ǖ拿济脱壑轭伾罡缤АR虼松习紫潞诘倪@樣一個(gè)特征绝编,就可以用于檢測(cè)當(dāng)前區(qū)域是否是額頭和眼睛。當(dāng)然一張圖片里會(huì)有許多類似的區(qū)域貌踏,因此不僅需要檢測(cè)額頭與眼睛十饥,還要它們位于鼻子和嘴的上面,在這些特征的相對(duì)位置都是正確的時(shí)候祖乳,才能判斷出是否找到了人臉逗堵。
針對(duì)不同的區(qū)域,有不同的Haar 特征:
特征值可以被計(jì)算為一個(gè)數(shù)值眷昆,只需要計(jì)算白色矩形內(nèi)的像素值和減去黑色矩形的像素之和蜒秤。這個(gè)值越大,說明特征越有可能提供有用的信息亚斋。
根據(jù)上面的描述應(yīng)該可以想到作媚,如果想要在圖片中找到額頭下面是眼睛,眼睛下面是鼻子嘴帅刊,需要在很多小的區(qū)域內(nèi)計(jì)算特征纸泡,計(jì)算量會(huì)變得很大。為此需要用到一個(gè)叫積分圖的數(shù)據(jù)結(jié)構(gòu)赖瞒,可以在常數(shù)時(shí)間內(nèi)計(jì)算得到矩陣的特征女揭。
積分圖
積分圖是一種快速有效的計(jì)算圖像內(nèi)一部分的像素總和的方法蚤假。
灰度圖可以看作是一個(gè)二維的矩陣。在積分圖中吧兔, 每個(gè)點(diǎn)儲(chǔ)存的都是該點(diǎn)左上方所有像素的總和磷仰。
積分圖可以一次性提前算好,當(dāng)需要求某個(gè)子矩陣的和時(shí)境蔼,只需要查詢4個(gè)數(shù)字灶平,就得以得到子矩陣的和。例如下圖中欧穴,想要計(jì)算矩陣ABCD內(nèi)像素的和民逼,在積分圖內(nèi)找到A,B,C,D四個(gè)位置對(duì)應(yīng)的值,根據(jù)公式D-B-C+A就可以得到涮帘。
Adaboost
利用積分圖可以很快得到某個(gè)特征的值拼苍,并判斷是否包含人臉。弱學(xué)習(xí)器將判斷一個(gè)子區(qū)域內(nèi)是否包含人臉的特征调缨,每個(gè)弱學(xué)習(xí)器只判斷一個(gè)特征疮鲫。
Adaboost里,多個(gè)弱分類器組合最后會(huì)得到的一個(gè)強(qiáng)分類器弦叶,但當(dāng)分類器的數(shù)量過多時(shí)俊犯,也會(huì)得到使得計(jì)算量巨大遵馆,為此Viola和Jones又提出了分類器級(jí)聯(lián)啼辣。
分類器級(jí)聯(lián)
分類器級(jí)聯(lián)可以理解為將一串弱分類器穿起來,第一個(gè)分類器負(fù)責(zé)檢測(cè)一個(gè)人臉特征孵构,如果檢測(cè)到了立莉,說明它可能包含一個(gè)人臉绢彤,將進(jìn)入下一級(jí)的分類器繼續(xù)檢測(cè)下一個(gè)特征;如果沒有蜓耻,就可以直接判斷當(dāng)前不包括人臉了茫舶。下一級(jí)的分類器會(huì)更加復(fù)雜一些。級(jí)聯(lián)序列中的分類器只有當(dāng)樣本經(jīng)過了前面所有的分類器之和才會(huì)被訓(xùn)練到刹淌。級(jí)聯(lián)結(jié)構(gòu)本質(zhì)上是一個(gè)退化型的決策樹饶氏。
在第一級(jí)選擇眼睛和鼻子的特征,可以達(dá)到不到1%的FNR(false negtive rate)和40%的FPR(false positive rate)有勾。因此可以減少超過一半的不必要的最終檢測(cè)疹启。
OpenCV實(shí)現(xiàn)
在安裝OpenCV的目錄下,會(huì)有一個(gè)叫 haarcascades的文件蔼卡,我們只需要haarcascade_frontalface_alt.xml 這個(gè)文件皮仁。
import cv2
# 原始圖片
img = cv2.imread("path/he.png")
# 轉(zhuǎn)為灰度圖
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 加載分類器
face_cascade = cv2.CascadeClassifier("path/haarcascade_frontalface_alt.xml")
# 在圖像上檢測(cè),multiscale表示多個(gè)比例查看圖像子區(qū)域,以檢測(cè)不同大小
detected_faces = face_cascade.detectMultiScale(gray_img)
# 在原圖上加上框
for (column, row, width, height) in detected_faces:
cv2.rectangle(
img,
(column, row),
(column + width, row + height),
(0, 255, 0),
2
)
# 顯示圖片贷祈,按0關(guān)閉窗口
cv2.imshow('Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Viola-Jones已經(jīng)是20年前的算法,現(xiàn)在深度學(xué)習(xí)應(yīng)用在目標(biāo)檢測(cè)上已經(jīng)取得了非常好的成績(jī)喝峦,但不可否認(rèn)的是二十年前的思想奠定了現(xiàn)在的基礎(chǔ)势誊,特征選擇,特征組合谣蠢,分類級(jí)聯(lián)等都與現(xiàn)在的各種神經(jīng)網(wǎng)絡(luò)有異曲同工之妙粟耻。