基于OpenCV的面部關(guān)鍵點(diǎn)檢測(cè)實(shí)戰(zhàn)
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)

這篇文章概述了用于構(gòu)建面部關(guān)鍵點(diǎn)檢測(cè)模型的技術(shù),這些技術(shù)是Udacity的AI Nanodegree程序的一部分。
在Udacity的AIND的最終項(xiàng)目中,目標(biāo)是創(chuàng)建一個(gè)面部關(guān)鍵點(diǎn)檢測(cè)模型。然后將此模型集成到完整的流水線中,該流水線拍攝圖像,識(shí)別圖像中的任何面孔,然后檢測(cè)這些面孔的關(guān)鍵點(diǎn)。

該項(xiàng)目的一部分是要熟悉OpenCV庫(kù)。具體來說,是在預(yù)處理輸入圖像時(shí)使用它。在此項(xiàng)目中,它用于將圖像轉(zhuǎn)換為灰度并檢測(cè)圖像中的人臉。OpenCV的另一個(gè)有用功能是高斯模糊,可以用來隱藏檢測(cè)到的面部的身份。下圖顯示了對(duì)圖像應(yīng)用面部檢測(cè)和高斯模糊的結(jié)果。

使用OpenCV庫(kù)中的面部檢測(cè)器,然后可以裁剪圖像中的面部,以將其輸入到關(guān)鍵點(diǎn)檢測(cè)模型中。
為了訓(xùn)練關(guān)鍵點(diǎn)檢測(cè)模型,使用了具有相應(yīng)關(guān)鍵點(diǎn)標(biāo)簽的面部數(shù)據(jù)集。該數(shù)據(jù)集來自Kaggle,由96個(gè)x 96灰度面部圖像組成,帶有15個(gè)(x,y)坐標(biāo)標(biāo)記了面部關(guān)鍵點(diǎn)。原始數(shù)據(jù)集包含7049張圖像,但是并非所有圖像都具有完整的15個(gè)關(guān)鍵點(diǎn)標(biāo)簽。為了解決這個(gè)問題,只使用了具有全部15個(gè)關(guān)鍵點(diǎn)的圖像。剩下2140張圖像,其中500張被分成了測(cè)試集。下圖顯示了數(shù)據(jù)集的樣本。

使用相對(duì)較小的1640張圖像訓(xùn)練集,可以以幾種方式增強(qiáng)數(shù)據(jù),以增加模型可以從中學(xué)習(xí)的示例圖像的數(shù)量。由于不僅需要增強(qiáng)輸入圖像,而且還必須增強(qiáng)關(guān)鍵點(diǎn)標(biāo)簽,以便它們與新增強(qiáng)的圖像上的相同點(diǎn)相匹配,這一點(diǎn)變得更具挑戰(zhàn)性。應(yīng)用了兩種類型的擴(kuò)充,概述此過程的代碼可以在Jupyter筆記本項(xiàng)目中找到。
水平翻轉(zhuǎn)—這是相對(duì)簡(jiǎn)單的。圖像的x值和關(guān)鍵點(diǎn)反映在圖像的中心。對(duì)應(yīng)于臉部左側(cè)的關(guān)鍵點(diǎn)被替換為相應(yīng)的右關(guān)鍵點(diǎn)。這使訓(xùn)練數(shù)據(jù)增加了一倍。以下是水平翻轉(zhuǎn)的示例。

旋轉(zhuǎn)和縮放—旋轉(zhuǎn)和縮放更具挑戰(zhàn)性,但是由于使用了OpenCV,因此很容易構(gòu)造一個(gè)可同時(shí)應(yīng)用于圖像及其關(guān)鍵點(diǎn)的旋轉(zhuǎn)/縮放矩陣。將旋轉(zhuǎn)/縮放后的數(shù)據(jù)集版本添加到普通數(shù)據(jù)集后,訓(xùn)練示例再次加倍。下面是這種擴(kuò)充的一個(gè)示例。

擴(kuò)充原始數(shù)據(jù)集后,該模型現(xiàn)在有6560個(gè)示例可以進(jìn)行訓(xùn)練。
用于此模型的體系結(jié)構(gòu)大致基于VGG16模型,該模型是為在ImageNet上進(jìn)行分類而構(gòu)建的卷積神經(jīng)網(wǎng)絡(luò)。VGG16模型使用5個(gè)卷積塊從圖像中提取特征。這些塊由幾個(gè)卷積層組成,后跟一個(gè)最大池化層,其中圖像尺寸減小了一半。在用于該項(xiàng)目的模型中,每個(gè)卷積塊只有一個(gè)卷積層。這樣做的原因是,由于數(shù)據(jù)量有限,因此較簡(jiǎn)單的模型不太可能過擬合。
除了使用較少的卷積層之外,還將丟失層添加到前3個(gè)卷積塊中,其丟失率為20%,并且在每個(gè)卷積層之后添加了批處理歸一化層。最初的VGG16網(wǎng)絡(luò)都缺少這兩種更新的技術(shù),有助于防止過度安裝。
使用這種架構(gòu)提取圖像特征,將卷積層的輸出饋送到全局平均池化層,然后饋送到30個(gè)節(jié)點(diǎn)(15個(gè)關(guān)鍵點(diǎn)中每個(gè)點(diǎn)的x,y值)的完全連接的輸出層。下圖說明了該模型的完整架構(gòu)。

為了訓(xùn)練模型,使用標(biāo)記的關(guān)鍵點(diǎn)和預(yù)測(cè)關(guān)鍵點(diǎn)的均方誤差來計(jì)算損失。發(fā)現(xiàn)Adam優(yōu)化器提供了最佳結(jié)果。還發(fā)現(xiàn),通過提高批量大小和學(xué)習(xí)率可以實(shí)現(xiàn)最低的損失。從0.001的學(xué)習(xí)率開始,對(duì)模型進(jìn)行了針對(duì)32、64和128批次大小的15個(gè)時(shí)期的訓(xùn)練。對(duì)于0.0001和0.00001的學(xué)習(xí)率重復(fù)此步驟。原因是批次數(shù)量較小時(shí),梯度下降步驟更加隨機(jī)(隨機(jī)性更高),因?yàn)樗窃谳^少的示例中進(jìn)行平均的結(jié)果。當(dāng)優(yōu)化達(dá)到最小值時(shí),參數(shù)步應(yīng)代表更通用的解決方案,方法是采用較大批次大小的平均梯度來提供。
下圖顯示了訓(xùn)練曲線,后者顯示了最后時(shí)期的近距離視圖。如你們?cè)谧詈髸r(shí)期所看到的,訓(xùn)練損失的步驟是由每種學(xué)習(xí)率的批量大小增加而產(chǎn)生的。


經(jīng)過第一輪訓(xùn)練后,模型相對(duì)準(zhǔn)確。為了利用原始數(shù)據(jù)集中的所有數(shù)據(jù),使用經(jīng)過訓(xùn)練的模型來預(yù)測(cè)缺失值的關(guān)鍵點(diǎn)并將其用作標(biāo)簽。本質(zhì)上,數(shù)據(jù)集具有大量不完整的示例,這些示例被扔掉了,但它們?nèi)匀粡拇_實(shí)存在的關(guān)鍵點(diǎn)那里獲得有用的信息。為了從該信息中學(xué)習(xí),模型以其最佳猜測(cè)填充了不完整的點(diǎn)。
以偽標(biāo)簽完整數(shù)據(jù)集并像以前一樣對(duì)其進(jìn)行擴(kuò)充,使用29520個(gè)示例創(chuàng)建了一個(gè)新的訓(xùn)練數(shù)據(jù)集。然后,該模型繼續(xù)對(duì)該數(shù)據(jù)集進(jìn)行訓(xùn)練,然后再進(jìn)行對(duì)原始的全標(biāo)簽數(shù)據(jù)集的另一輪訓(xùn)練。最終,模型誤差被訓(xùn)練為低于0.0005。我們對(duì)此感到非常高興,正如項(xiàng)目筆記本所述:“一個(gè)很好的模型將實(shí)現(xiàn)約0.0015的損失”。此外,當(dāng)繪制在測(cè)試圖像上時(shí),關(guān)鍵點(diǎn)預(yù)測(cè)似乎位于你們期望的位置。
通過訓(xùn)練關(guān)鍵點(diǎn)檢測(cè)模型,將面部檢測(cè)器和模型組合起來,將關(guān)鍵點(diǎn)應(yīng)用于圖像中的面部。下圖給出了此過程的示例產(chǎn)品。

此外,該模型已擴(kuò)展為可與網(wǎng)絡(luò)攝像頭一起使用,并使用關(guān)鍵點(diǎn)功能應(yīng)用蒙版濾鏡(在這種情況下為太陽鏡)。

交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請(qǐng)按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~

