【深度學習】最新的一些開源face alignment及評價
評價:速度快,可商用,有些時候不太准確
2. CLM-framework: https://github.com/TadasBaltrusaitis/CLM-framework
評價:很准確,不可商用
3. Face Detection, Pose Estimation and Landmark Localization in the Wild :http://www.ics.uci.edu/~xzhu/face/
評價:Very slow (~10 seconds an image after hyper threading on a 8-core CPU), but very accurate when it comes to high pose variations
4. SDM patrikhuber/superviseddescent:https://github.com/patrikhuber/superviseddescent
評價:Nicely written C++ code, though not very robust
5. Robust face landmark estimation under occlusion:http://www.vision.caltech.edu/xpburgos/ICCV13/
評價:Specially designed for handling occlusions(遮擋區域), but slow on account being written in MATLAB.
6. 應用了CLM的項目:https://www.technologyreview.com/s/541866/this-car-knows-your-next-misstep-before-you-make-it/
評價:I actually explored a large number of open-source facial landmark detectors for a project, and found the CLM framework to outperform everything else (in terms of both speed and accuracy). We eventually used it in our project: www.technologyreview.com/news/…
7. clandmark:https://github.com/uricamic/clandmark
8. kylemcdonald/FaceTracker:https://github.com/kylemcdonald/FaceTracker
9. ++Android app for facial landmark tracking++:https://github.com/ajdroid/facetrackerapp
10. kylemcdonald/FaceTracker:https://github.com/kylemcdonald/FaceTracker
11. http://note.youdao.com/groupshare/web/file.html?token=4F58BCBC04714A7C8ADE604364BA97BB&gid=22052122
12: ofxFaceTracker:https://github.com/kylemcdonald/ofxFaceTracker
參考鏈接:http://www.learnopencv.com/facial-landmark-detection/#comment-2471797375
原文地址:http://blog.csdn.net/hjimce/article/details/49955149
作者:hjimce
一、相關理論
本篇博文主要講解2013年CVPR的一篇利用深度學習做人臉特征點定位的經典paper:《Deep Convolutional Network Cascade for Facial Point Detection》,論文的主頁為:http://mmlab.ie.cuhk.edu.hk/archive/CNN_FacePoint.htm 。網頁提供了訓練數據、測試demo,但是我卻沒有找到源碼,所以只能自己寫代碼實現。這篇paper是利用深度學習搞人臉特征點定位的開山之作,想當年此算法曾經取得了state-of-art 的結果。后來face++發表的幾篇paper的思想,都是在這篇paper的算法上進行擴展的。
如果之前沒有學過類似DCNN的思想的話,那么會感覺相當難,至少我是這么覺得的。在之前學過的各種深度學習模型中,一般就只有一個CNN,可這篇paper是由十幾個CNN組成的。我一看到文獻中如下網絡結構圖片:
作為菜鳥的我,就已經暈了,然后在看一下文獻的一些公式,我徹底沒了耐性。因為我看外文paper,一般首先會直接看圖、看公式,可這篇paper的圖,一上來就把我嚇到了。之前學過反卷積網絡,FCN、R-CNN、FR-CNN、OverFeat、Siamese Network、NIN等等各種網絡,感覺花個一兩天的時間,總可以把算法想通。可是學了這篇paper之后,感覺難度完全不是一個等級的,因為初次接觸這種DCNN,花了好幾周的時間,才把源碼實現出來,過程相當痛苦,好吧,還是不羅嗦了,這篇博文將仔細講解paper算法的實現過程,領略不一樣的CNN模型,也就是傳說中的DCNN(這篇paper,后來人們又把這種多層次的CNN模型稱之為DCNN)。接着我將先簡單介紹,文章的主要思想。
1、RCNN回顧
paper的總思想是一種從粗到精的定位思想,如果你之前已經對R-CNN有所了解,我們就回憶一下現在的一些物體檢測的大體算法思路,因為我覺得RCNN也是一種從粗定位,到精識別的過程,跟本篇paper的思想很相似,下面是RCNN的流程圖(RCNN文獻《Region-based Convolutional Networks for Accurate Object Detection and Segmentation》):
首先輸入一張圖片,然后RCNN的思路是:
(1)采用傳統的方法,先把一張圖片中各個可能的物體的bounding box分割出來
(2)把各個可能的裁剪出來的物體檢測框,輸入cnn,進行特征提取,最后進行物體分類識別
OK,算法的總體思路很簡單。其實這也是一種從粗到精的思想,就是我們對輸入的一整張圖片先進行粗定位,先定位出物體的bounding box,也就是物體的大體的位置。然后進行裁剪(bouding box),這樣我們裁剪出來的圖片范圍就變小了,外界背景因素的干擾就減小了,然后我們在把裁剪后的圖片,作為CNN的輸入,這樣有利於提高精度。總之,假設你要用CNN做人臉識別,那么你就不應該把一整張圖片,包括風景、背景、身體、頭發這些背景因素都扔進CNN中,這樣的精度會比較小。你應該是先用人臉檢測器,把人臉部位的圖片裁剪出來,送入CNN中,精度才會較高。OK,可能你覺得,我這邊講的話題有點廢話,其實《Deep Convolutional Network Cascade for Facial Point Detection》這篇paper的思想就是這樣,很簡單的一個思想。
2、paper的思想
圖 1
回到本篇文章的主題,特征點定位。以上面的圖片為例,假設我們要定位出上面的5個人臉特征點,從粗定位到精定位的過程如下(下面我先用最簡單的理解方式,講解粗到精的定位過程,先不根據paper的算法進行講解,等明白了粗定精的定位過程,我們再結合paper的算法進行細講):
(1) level1。首先我們要做的第一步,把人臉圖片裁剪出來,而不是直接把上面的一整張圖片,扔到CNN中,因為上面圖片包含的范圍太大了,我們需要使得輸入CNN的圖片范圍越小越好,比如裁剪成下面的圖片,然后輸入CNN中(我們只需要保證要定位的5個特征點包含在里面就可以了):
圖 2
因此網絡的第一層次CNN模型,我們的目標就是要定位出包含這5個特征點的最小包圍盒,縮小搜索范圍(paper沒有這一層,它所采用的算法是直接采用人臉檢測器,但是如果采用cnn,先定位出5個特征點的bounding box 精度會比直接采用人臉檢測器,定位精度來的高,這個可以從后面face++發表的paper:《Extensive Facial Landmark Localization with Coarse-to-fine Convolutional Network Cascade》中看到,這篇我以后會在另外一篇博文中講解,這邊只是為了方便理解)
本層次CNN模型的輸入:原始圖片(圖1)
本層次CNN模型的輸出:包含五個特征點的bonding box,預測出bounding box后,把它裁剪出來,得到圖2
(2) level2。接着我們采用CNN,粗定位出這五個特征點,如下圖所示(換了一張示例圖片,將就一下):
圖 3
上面示例圖中,藍色的點是正確的點;然后紅色的點是,我們采用本層次網絡CNN模型,預測定位出來的特征點。可以看到紅色的點和正確的藍色點,之間還是有很大的誤差,這就是所謂的粗定位,只能大體的搜索到各個點的位置,精度還有待提高。這一層次,又稱之為網絡特征點的初始定位層,很粗糙的一個定位。然后根據我們cnn的粗定位點,也就是紅色的點,作為中心,進行裁剪出一個小的矩形區域,進一步縮小搜索范圍:
鼻子
左右嘴角
左右眼睛
圖 4
本層次CNN模型輸入:包含五個特征點的bounding box圖片(也就是圖 2)
本層次CNN模型輸出:預測出五個特征點的初始位置,得到圖3的紅色特征點位置,預測出來以后,進行裁剪,把各個特征點的一個小區域范圍中的圖片裁剪出來,得到圖4
(3) level3。這一層又稱之位精定位。
因此接着我們就要分別設計5個CNN模型,用於分別輸入上面的5個特征點所對應的圖片區域了,然后用於分別定位,找到藍色正確點的坐標。通過圖4的裁剪,我們的搜索的范圍一下子小了很多,就只有小小的一個范圍而已了。這邊需要注意,各個部位的CNN模型參數是不共享的,也就是各自獨立工作,5個CNN用於分別定位5個點。每個CNN的輸出是兩個神經元(因為一個CNN,只定位1個特征點,一個特征點,包含了(x,y)兩維)。聲明:這一層次的網絡,文獻不僅僅包含了5個CNN,它是用了10個CNN,每個特征點有兩個CNN訓練預測,然后進行平均,我們這里可以先忽略這一點,影響不大。
本層次CNN模型輸入:各個特征點,對應裁剪出來的圖片區域,如圖4
本層次CNN模型輸出:各個特征點的精定位位置。
OK,到了這里,基本講完了,從粗定位到精定位的思想了,如果看不懂,就得結合文獻,反復的讀了,因為只有懂了這個思想,才能進行下一步。
二、網絡架構
上面只是對從粗到精的思想,大體的思路進行了講解,但是具體我們要怎么實現,代碼要怎么實現,各個網絡是如何訓練的?因此接着我要講的就是細節、代碼實現問題,上面講解從粗到精的思想的時候,我為了方便理解,所以有的一些細節也沒有根據文獻的講。這一部分,我們將根據文獻的一步一步,每個細節,網絡結構進行講解。首先我們先再次看一下網絡的結構圖:
這篇papar的DCNN,總體上分成三大部分,分別是:level 1、level 2、level 3。每個level 里面,包含着好幾個CNN模型,我們將一步一步剖析這個網絡結構。在最開始的時候,首先,我們利用人臉檢測器,裁剪出人臉圖片,具體的人臉檢測器的就是用我們傳統的方法,比如haar特征。然后把我們裁剪出來的人臉圖片,作為level 1的輸入。下面開始分層次講解各個level 的具體細節(在此不要糾結level 這個詞怎么翻譯,如果非要理解這個詞,可以用“等級”,leve 1表示最粗糙的等級,然后level 2表示精等級,level 3表示更精的等級)。
1、level 1網絡架構
網絡的輸入:我們通過人臉檢測器,裁剪出face bounding box,然后把它轉換成灰度圖像,最后縮放到39*39大小的圖片,這個39*39的圖片,將作為我們level 1的輸入。在網絡的第一層次上,由三個卷積神經網絡組成,這三個卷積神經網絡分別命名為:F1(網絡的輸入為一整張人臉圖片),EN1(輸入圖片包含了眼睛和鼻子)、NM1(包含了鼻子和嘴巴區域)。這三個卷積網絡區別在於輸入的圖片區域不同:
第一層次網絡
A、F1結構
F1的輸入為整個人臉圖片(39*39的大小),輸出為我們所要預測的五個特征點。F1的網絡結構如下:
F1的網絡結構圖
輸入一張人臉圖片大小為39*39,然后通過卷積神經網絡,輸出一個10維的特征向量(5個特征點)。F1的結構,第一個層特征圖選擇20,第二次卷積特征圖個數選擇40,然后接着是60、80。具體各層的參數可以參考下面表格:
F1網絡參數
I(39,39)表示輸入圖片大小為39*39,P(2)應該表示池化為stride大小為2。具體的各層參數我就不再詳解,因為這個不是重點,而且即便是你沒有根據paper的結構進行設計,對精度的影響也不大(只要你設計的網絡合理,不要出現過擬合、欠擬合都OK)
B、EN1、NM1的網絡結構
這兩個CNN和F1基本相同,不過輸入圖片的大小不同,輸出神經元的個數也不相同。
EN1用於定位:左眼+右眼+鼻子 三個特征點,因此自然而然,網絡設計的時候,輸出層的神經元個數就是6。然后輸入的圖片,是我們根據比例裁剪的,我們把39*39圖片的上半部分裁剪出來,裁剪出31*39大小的圖片,當然裁剪大小比例這個是一個經驗裁剪,我們只要保證裁剪的區域包含了眼睛和鼻子區域就好了。
NM1用於定位:左嘴角+右嘴角+鼻子 三個特征點。同樣的,網絡的輸出就是6個神經元,輸入部分,從人臉的底部往上裁剪,也是裁剪出31*39的圖片,只要裁剪出來的區域,只包含嘴巴和鼻子,就OK了。具體這兩個CNN的各層相關參數,如下表格中的S1行所示(S0是F1,S1是EN1、NM1):
EN1\NM1網絡參數
那么F1、EN1、NM1三個網絡是怎么連接在一起的?我們通過平均的方法,把重復預測的特征點進行位置平均。比如我們的鼻子點,三個網絡都可以預測到位置,那么我們就把這三個網絡預測出來的鼻子點,三個點相加,然后除以3,就可以得到平均位置了。再如,右眼睛,我們F1、EN1這兩個網絡有預測,我們就把這兩個網絡預測到的右眼睛點相加在一起,然后除以2,就得到平均位置了。
那么為什么要搞得這么復雜了,為什么要用三個網絡進行分別預測,然后進行平均呢?其實這個就像Alexnet一樣,采用平均預測的方法,可以提高網絡的穩定性,提高精度,如果你之前已經學過Alexnet,就會明白作者為什么要用平均預測。總之”平均“,可以提高網絡的穩定性、防止預測特征點的位置偏差過大,提高精度。
OK,我們大體知道了level 1由三個CNN組成,三個CNN分別預測各自所需要的特征點,然后進行位置平均。這三個CNN都包含了9層(如上面的表格所示),算是一個深度網絡。level 1因為是粗定位,輸入的圖片區域比較大,特征提取難度比較大,所以我們設計這一層級網絡的時候,需要保證網絡的深度,用於提取復雜的特征(原理解釋請自己查看paper)。突然感覺講到這邊,有點累了,好漫長的算法,感覺才講了一半左右,堅持……
2、level 2 網絡架構
A、level 2的輸入
經過了level 1 我們大體可以知道了,各個特征點的位置,接着我們要減小搜索范圍,我們以第一層級預測到的特征點,以這五個預測特征點為中心,然后用一個較小的bbox,把這五個特征點的小區域范圍內的圖片裁剪出來,如下圖所示:
鼻子
左右嘴角
左右眼睛
level 2 輸入
上圖中,紅色的點就是我們用level 1 預測出來的位置,然后在進行裁剪(上面圖,我是自己手動隨便裁剪的,因為比較懶,所以就隨便做了一個示意圖,我們程序裁剪的時候,是以預測點為中心點,裁剪出一個矩形框)。OK,既然是裁剪,那么我們要裁剪多大?這個可以從下面表格參數中知道,level 2采用的是S2行,我們只需要看S2那一行參數就可以了:
我們裁剪的時候,是以level 1的特征點為中心,裁剪出小區域范圍的圖片。
B、網絡總體結構
level 2 組成
本層次的網絡CNN個數可就多了,level 2 由10個CNN組成,每個CNN網絡層數、每層的相關參數,如上面的表格中S2那一行所示。總之就是leve 2 和level 3的結構都是用了S2那一行的參數,每個CNN包含6層。
哎,看到上面level 2的10個CNN,估計會有點暈,其實很簡單,且聽我細細道來:這10個CNN,分別用於預測5個特征點,每個特征點用了兩個CNN,然后兩個CNN對預測的結果進行平均。我們以左眼特征點為例,我們用表格S2行的參數設計出了LE21、LE22,我們在訓練的時候,訓練了兩個模型,這兩個CNN都是用於預測左眼特征點,然后我們使用的時候,就直接用這兩個CNN預測到的特征點,做位置平均。總之一句話就是:還是平均,跟level 1一樣,也是用多個CNN進行位置平均。
3、level 3網絡架構
level 3是在level 2得到預測點位置的基礎上,重新進行裁剪。我們知道由level 2的網絡,我們可以進一步得到那5個特征點的位置(離正確的點越近了),然后我們利用level 2的預測位置,重新進行裁剪。然后在重新進行預測,level 3的總體結構如下:
與level 2結構相同,也是由10個CNN組成,每兩個CNN預測1個特征點。那么level 3和level 2的區別在哪里呢?首先我們的裁剪區域發生了變化,我們也可以讓level 3的裁剪圖片大小再變得更小一些。
三、網絡訓練
測試誤差評價標准公式如下:
其中l是人臉框的長度。
其它細節:
1、采用local shared weights 有助於level 1的精度提高
2、采用abs+tanh 激活,可以提高網絡性能:
OK,終於解放了,講解完畢,對於人臉特征點的定位,出了從粗到精的定位方法,后面還有一些paper采用的是mutil-task方法,好像很不錯的樣子,以后在慢慢學習。
參考文獻:
1、《Deep Convolutional Network Cascade for Facial Point Detection》
2、《Extensive Facial Landmark Localization with Coarse-to-fine Convolutional Network Cascade》
3、《Face Alignment at 3000 FPS via Regressing Local Binary Features》
4、《Face Alignment by Explicit Shape Regression》
**********************作者:hjimce 時間:2015.11.1 聯系QQ:1393852684 地址:http://blog.csdn.net/hjimce 原創文章,版權所有,轉載請保留本行信息(不允許刪除)********************