版權聲明:本文為部落客原創文章,轉載請注明。
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t0">綜述</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t1">代碼解讀 step by step</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t2">1 預處理階段</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t3">11 載入訓練集測試集</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t4">12 圖檔上采樣</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t5">13 鏡像圖檔</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t6">2 訓練階段</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t7">21 定義scanner用于掃描圖檔并提取特征</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t8">22 設定scanner掃描視窗大小</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t9">23 定義trainer用于訓練人臉檢測器</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t10">24 訓練生成人臉檢測器</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t11">25 測試</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t12">3 tips</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t13">31 模型的存儲</a>
<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t14">32 多個detector聯合使用</a>

以下給出完整的人臉檢測器訓練代碼(詳細代碼解讀請看第2部分):
訓練集和測試集圖檔存儲在”faces”檔案夾下,另外該檔案夾下還需包含training.xml,testing.xml,包含圖檔中人臉bounding box的位置。組織形式為:
即圖檔放大兩倍,這樣有助于檢測較小的人臉。
上述函數在對圖檔進行上采樣的同時,也相應地調整了人臉bounding box的位置。
1
對訓練所用圖檔做鏡像處理,擴充訓練集的訓練樣本。
class scan_fhog_pyramid定義來自于scan_fhog_pyramid.h,原型如下:
2
類模闆中參數1表示圖像金字塔的類型,本文使用的是pyramid_down<6>,表示圖像金字塔進行下采樣的比率為5/6,即對原圖像不斷縮小5/6,構成多級金字塔。什麼時候停止下采樣呢?當圖像的大小<掃描視窗大小的時候。
參數2表示特征提取器,預設情況下使用fhog.h中的extract_fhog_feature()提取特征,函數原型為:
此函數提取的HOG特征來自于Felzenszwalb版本的HOG [1] (簡稱fhog),它是對每個8*8像素大小的cell提取31維的fhog算子,然後儲存到上述hog array中供後續計算使用。
31D fhog=18D+9D+4D。
(1) 18D來自于對cell做18個bin的梯度方向直方圖,即将360°劃分為18個bin,然後令cell中的每個像素根據其梯度方向權重投影到直方圖相應的bin中,這樣就得到了18維有符号的fhog梯度。
(2) 9D來自于對cell做9個bin的梯度方向直方圖,此時是将180°劃分為9個bin,則得到無符号的9維fhog梯度。
(3) 最後的4D是來自于目前cell和其對角線臨域的4個領域cell的歸一化操作。具體地,取block=2*2 cell,則得到無符号fhog梯度4*9維,将其看成矩陣做按行按列累加可得到1D特征,4個領域則可得到4個block,共4維特征。
最終,每個cell的31維fhog特征就來自于上述三部分的串聯。
設定掃描視窗大小為80*80,即掃描視窗是固定大小的,通過放縮圖像(圖像金字塔)以達到在不同尺度上檢測人臉的目的。
由于在預進行中圖像放大了2倍,則圖像中最小能檢測到的人臉大小為40*40。
structural_object_detection_trainer定義來自于structural_object_detection_trainer.h,通過scanner來初始化trainer。
train()的函數原型在structural_object_detection_trainer.h有4個,這裡用的是其中一個,即輸入參數為圖檔和圖檔中人臉的正确位置,輸出一個object_detector。
注意這種情況下除了已經标出的人臉位置為正樣本以外,圖檔的其他位置随機取負樣本,是以在标注訓練圖檔的人臉時,應確定所有人臉都已标注出來。如果出現不太确定是不是人臉的圖檔,應調用另一個版本的train()函數并設定ignore區域。
關于train()的内部實作,其實就是訓練一個SVM模型,當模型loss<之前所設的epsilon的時候,輸出訓練好的模型到object_detector。
detector()函數直接傳回圖檔中所有檢測到的人臉的bounding box資訊。
通過serialize()可以實作對模型的儲存,而deserialize()可以将磁盤中儲存的模型取出來用。
3
4
5
在文章開篇的時候提到上述人臉檢測器比較适用于正臉的檢測,對于側臉的檢測效果并不好。那麼我們可以單獨訓練側臉的人臉檢測器,然後多個detector聯合使用。
串聯所有人臉檢測器一起使用的好處是,全圖的fhog特征隻需要提取一遍即可。
例如,在dlib自帶的人臉檢測器中就用了5個HOG-based detector,分别用于檢測front looking, left looking, right looking, front looking but rotated left, and a front looking but rotated right one. 下面是這五個detector的訓練參數log:
[1] Object Detection with Discriminatively Trained Part Based Models by P. Felzenszwalb, R. Girshick, D. McAllester, D. Ramanan, IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol. 32, No. 9, Sep. 2010。
【新浪微網誌】 張昺華--sky
【twitter】 @sky2030_
【facebook】 張昺華 zhangbinghua
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利.