1. 程式人生 > >人臉特徵點檢測(Facial landmark detection)

人臉特徵點檢測(Facial landmark detection)

1)cnn face detetor(Deep Convolutional Network Cascade for Facial Point Detection)
http://blog.csdn.net/hjimce/article/details/50099115

2) dataset,with point
https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/

3) Facial landmark detection on android
https://github.com/flyingzhao/FacialLandmarkAndroid    (good)
http://dlib.net/   (base on dlib)

4) blog

http://blog.csdn.net/xiamentingtao/article/details/50908190

--------------------------------------------------------------------------------------------------------------------------------

以下轉自:http://blog.csdn.net/hjimce/article/details/50099115

基於改進Coarse-to-fine CNN網路的人臉特徵點定位

作者:hjimce

一、相關理論

    本篇博文主要講解2013年face++的大牛們提出粗到精人臉特徵點定位演算法paper:《Extensive Facial Landmark Localization 

with Coarse to fine Convolutional Network Cascade》,發表於2013年ICCV上的一篇用於定位多個人臉特徵點的文獻,實現了68個人臉特徵點的高精度定位。這篇paper沒有給出訓練資料,也沒有給出測試模型、原始碼等,所以原始碼需要自己寫,訓練資料我們需要自己到IBUG網站下載,可以下載到兩千多張的訓練資料,這篇paper的程式碼花了我兩週的時間,主要是裁一些細節方面很麻煩。

    我個人感覺這篇文章的創新點不是很大,基本上是在文獻:《Deep Convolutional Network Cascade for Facial Point Detection》的基礎上做了一點點的修改,使得我們構建的CNN模型可以用於定位更多的特徵點,總結為一句話就是如果想要看懂這篇文獻,還是建議先好好學習paper:《Deep Convolutional Network Cascade for Facial Point Detection》,熟悉程式碼是怎麼實現的,然後再來搞這篇文章的演算法,就只需要改一改就OK了。

    人臉68特徵點的定位方法,也是採用了從粗到精的定位思想,網路屬於DCNN,開始講解這篇paper之前,我先講解一下文獻的創新點,因為如果你已經熟悉了《Deep Convolutional Network Cascade for Facial Point Detection》的演算法,我們只要把創新點抓住,就OK了。本篇給我的感覺最大的創新點在於:在網路的輸入方面,不是用人臉檢測器檢測到的人臉區域圖片作為網路的輸入,而是採用CNN預測人臉的bounding box,這個改進對初始level定位精度提高非常多,如下圖所示,當我們輸入一張圖片的時候,我們用CNN,分別預測出Inner points和Contour points的最小包圍盒:

切記:上面的兩個部分的特徵點預測是完全分開的,各自的網路可以進行並行訓練、預測。就像上面,兩部分的分開預測,第一層次的目的都是為了獲得Bounding Box。

   雖然文獻還提出了一些其它方面的細節,但是我感覺基本上對精度影響都不大,比如文獻最後在預測inner point的時候,還多了一個層次網路level 4(對總精度提高非常小,後面再講解),如果你僅僅是為了學習這個演算法的話,完全可以不用level 4,當然如果你要實現最高的精度(用於商用),就要把老老實實根據文獻的演算法,一步一步來了。好了,言歸正傳,下面開始講解paper演算法。在這篇paper的演算法中,被預測的68個人臉特徵點分為兩個部分。

第一部分:主要是人臉五官的特徵點預測,這部分預測點的個數為51,在文獻中又把這部分特徵點命名為:Inner points,貌似文獻中並沒有顯示51個點,如下圖所示:


第二部分:用於預測人臉外輪廓的17個特徵點。我們又稱之為:Contour points ,請記住Contour points和Inner points這兩個名詞指的是哪部分特徵點,我後面都使用這兩個詞進行講解。

Inner points和Contour points這兩部分相互獨立,用不同的網路結構進行預測,也就說這兩部分可以平行計算,其中contour point的預測比較簡單,paper的大部分精力都花在講解inner points 上面,演算法也都是講解inner points,因為inner points是五官特徵點的位置,定位比較複雜,所以才要花費更多的精力去提高精度。

一、Inner points預測

Inner points的預測是一個四層次的DCNN模型。level 1就是我們前面講的預測bounding box;level 2 用於這51個點的初始定位,也就是粗定位;level 3 用於精定位;level 4 用於更精定位(這一層次對精度提高很小)。

第一層次(level 1):這個就是我們上面講的預測最小包圍盒。輸入一張完整的圖片,我們通過這一層CNN,預測這51個點的最小包圍盒(Bounding Box)。Bounding box 包含矩形左上角的座標、右下角的座標,也就是網路的輸出是一個4維的向量:

        

輸入                 輸出

第一層次

第二層次(level 2):網路的輸入,就是我們通過第一層次預測到的51個點的最小包圍盒中的人臉圖片;網路的輸出是51個特徵點預測位置(粗定位位置)。這一層次比較簡單,說白了就是我們常見的CNN,用普通的CNN預測51個特徵點(當然用這一層預測出來的位置,只能作為初始位置,因為通過這一層預測的精度還不夠高,只能作為51個點的粗定位。我們需要有後面繼續兩個層次網路進行精定位)。

 

第二層次

網路的輸入:把level 1得到的最小包圍盒中的圖片裁剪出來,作為輸入,進行51個點人臉特徵點預測。

網路的輸出:因為我們是要預測51個特徵點,所以CNN的輸出是102神經元。

第三層次(level 3):因為我們上面一層的網路,已經預測到了51個特徵點,然而這51個點的位置還不夠高,我們需要對其做進一步的精定位。

第二層次預測的51個點,之所以精度不夠高,是因為我們輸入的圖片是大的圖片,是對全域性的統一預測(具體解釋可以參考文獻《Deep Convolutional Network Cascade for Facial Point Detection》),容易受冗餘資訊的干擾。說的簡單一點吧:假設你要定位嘴巴的特徵點,你的輸入圖片就應該只有嘴巴部分的區域圖片,這樣的精度才會比較高,而不是你把一整張人臉圖片作為輸入,這樣冗餘資訊太多,容易干擾到我們的嘴巴區域的定位。

因此我們這一層次的網路,就是要利用level 2的網路預測到的51個點,把五官的圖片裁剪出來,然後對五官進行分別的定位。具體的示意圖如下:

 

第三層次

網路輸入:利用level 2的51個點,對五官圖片裁剪,把裁剪的五官,進行分開訓練、預測。因為我們要各個器官分開訓練,因此自然而然本層需要有4個CNN模型,每個模型用於預測各自的特徵點

網路輸出:各個器官的特徵點

第四層次(level 4):這一層次的輸入,與文獻《Deep Convolutional Network Cascade for Facial Point Detection》相比,稍稍做了修改。跟我想象的有點不一樣,paper通過把level 3的各個五官預測結果,計算各五官的旋轉角度,然後把五官都擺正了,作為第四層次網路輸入圖片,然後在進行預測。

 

第四層次

這一層網路,對於我們來說可以不去實現,只到level 3就好了,這篇paper是為了達到state-off-art 所以才增加了level 4。其實這一層網路,對精度的提高非常非常小,我們看一下paper的每一層的誤差:

 

各層次網路的誤差

好好看一下上面這個表格的資料,level 2 作為初始的預測,驗證誤差是0.051,通過leve 3的精定位,誤差減小到了0.0438,也就是說相對精度相當於提高了14%,這一層精度的提高很明顯。然而從level 3到level 4 誤差從0.0438到0.0431,好像效能提高不了多少。因此對於我們如果要用於商用,需要考慮計算時間效率、精度等綜合因素,可以不要採用paper的level 4,不划算,精度提高那麼小,計算時間卻增加了相當多。

二、Contour points預測

這17個點的預測比較簡單粗暴,就只是兩個層次的DCNN模型,這兩個層次說的簡單一點就是類似上面Inner points的第一、二兩個層次網路。

第一層次:這個在前面已經講過了,也就是預測Contour points的最小包圍盒(下圖中的底部示意圖)。


第二層次:CNN直接預測這17個特徵點。

 

這個預測過程,沒有精定位過程。也就是沒有第三、四層次的CNN精定位,一來是因為這些臉龐特徵點的圖片區域比較大,如果加上第三、四層次的話,會比較耗時間;二來是因為paper還沒想到比較好的方法,用於精定位。

總結:總的來說呢,這篇文獻的思想和《Deep Convolutional Network Cascade for Facial Point Detection》的思想是一樣的,看文獻的名字就知道了,是在這篇paper的基礎上,進行改進的一種用於多個特徵點預測的網路結構。因為paper《Deep Convolutional Network Cascade for Facial Point Detection》只預測5個特徵點,於是face++他們就在這篇文獻的基礎上做了改進,使網路結構可以用於很多個特徵點的預測。

從這篇paper的創新方面講:

1、文獻把人臉的特徵點定位,分開成兩個部分了:Inner和Contour兩部分特徵點,進行分開預測

2、在Inner的預測部分,從level 2 開始把五官裁剪分開,進行精定位。

3、在每個器官的每個特徵點的定位方面,文獻並沒有像《Deep Convolutional Network Cascade for Facial Point Detection》的方法,把每個特徵點的都用獨立的網路進行定位,不然如果按照《Deep Convolutional Network Cascade for Facial Point Detection》的思想,51個特徵點的定位,精定位的每一層次就要有102個CNN模型(因為《Deep Convolutional Network Cascade for Facial Point Detection》文獻每個特徵點的精定位是用了兩個網路進行訓練、預測,然後用兩個網路的輸出作為平均值,所以是102個網路),這樣太耗時間了,萬一我要定位300個特徵點,不得崩潰。因此face++的這篇paper並沒有把每個特徵點分開獨立訓練、預測,僅僅把各個器官分開訓練。

4、多了一個bounding box 層,可以大大提高特徵點粗定位網路的精度。

三、相關細節與原理解釋

採用粗定位到精定位的過程,有很多優點:

1、各個五官分開預測的原因解釋

    各個部分分開訓練,這樣網路的損失函式是分開的。這樣做可以提高精度的原因在於:因為網路各個部位特徵點的定位難度不同,或者說定位難度不平衡。比如,contour特徵點的定位比inner 特徵點的定位難度大,這個主要是因為人臉外輪廓往往比較模糊、還有受到頭髮等背景因素的干擾,所以人臉的外輪廓的特徵點的定位難度會比較大。這些因素,引起了訓練損失函式各個特徵點嚴重的不平衡,比如比較難定位的contour的特徵點,就會對損失函式,佔用比較大的比重,因此如果我們68個特徵點一起訓練的話,L2損失函式值基本上是contour的特徵點佔用了比較大的比重。所以文獻才採用把inner和contour分開預測,這樣可以避免不平衡問題。

    同理,在inner預測部分,把五官的預測都分開。比如因為眉毛的誤差往往會比較大,而眼睛的預測精度就比較高了,這樣把各個器官都分開,不共用一個損失函式,可以避免不平衡問題。

2、採用多層迴歸的原因

也就是採用從粗定位到精定位的原因,這個感覺paper解釋的有點不好,可以自己去看一下《Deep Convolutional Network Cascade for Facial Point Detection》文獻的解釋,這裡懶得解釋了。打了一個早上的字,才講解到這邊,心塞……。

3、採用CNN預測bounding box

相比與直接採用人臉檢測器,進行預測人臉矩形框來說,這個方法比較靠譜。因為採用人臉檢測器檢測到的人臉框,往往包含了太多了無關的背景,會對我們的網路有一定的干擾。另一方面,如果直接採用人臉檢測器,檢測到的人臉有的時候,並不是位於矩形的中心,這樣對結果也會有一定的影響。

四、網路結構及其訓練

OK,到了這裡我們就要講具體的相關實現了。首先我們先做個定義:N1表示為inner point各個特徵點的初始位置預測,也就是相當於inner 的level 2。N2表示為contour point點的預測(contour的level 2)。

 

下面是N1的網路結構圖,網路的輸入是60*60大小的圖片:

 

網路結構方面基本上與傳統的CNN模型,差不多,最大的區別在於locally sharing weights,也就是上面的unshared conv層,我們平時所遇到的CNN都是global sharing weights的。但是對於特徵點的預測,五官的高層特徵差別比較大,所以需要在高層採用unshared weight的方式,在低層採用global sharing weights。

1、網路訓練:採用隨機梯度下降,同時採用圖片相似變換(旋轉、縮放、平移等),對資料進行擴充,防止過擬合。

2、資料預處理:採用資料歸一化到:均值為0,方差為1,然後採用hyper-tangent 函式,把資料對映到-1~1之間。還有就是以上各層,在進行圖片裁剪的時候,需要稍微大一點點,不然當定位稍微不準的時候,直接採用原比例進行裁剪,會把我們想要的部分也可能給剔除掉。

六、演算法試驗

1、bounding box level 測試(level 1 到level 2)

為了快速驗證文獻的主要思想、創新點,也就是增加bounding box level層,我對《Deep Convolutional Network Cascade for Facial Point Detection》演算法進行了改進測試,先測試5個特徵點的情況,因為我對文獻《Deep Convolutional Network Cascade for Facial Point Detection》之前已經比較熟悉了,而且程式碼也寫過了一遍,所以利用已有的程式碼,直接測試本篇paper所提出的bounding box level,看看增加bouding box層與直接採用人臉檢測器,對各特徵點初始位置預測精度能提高多少?

我根據paper的演算法,進行人臉特徵點定位試驗,只測試了5個特徵點的預測,比較採用bounding box level和face detector 對5個特徵點初始位置預測精度的影響。驗證過程:主要是測試bounding box層對精度的影響,paper在驗證集上測試誤差,然後與直接採用人臉框檢測的精度預測結果,對人臉特徵點初始預測精度的影響。

(1)直接採用人臉檢測器作為level 1

直接採用人臉檢測器作為level 1,在我的測試集上,損失誤差如下:

 

測試過程中,為了簡單起見,暫時沒有使用unshared weights的、也沒有使用fabs層,直接採用face detector 各特徵點的預測結果(藍色的點代表標準點,紅色點表示利用網路進行預測的點):

 

紅色的點是預測點,藍色點是手工標定的點

(2)採用bounding box estimation作為level 1

下面是採用bounding box 作為DCNN的level 1,最後測試level 2預測的精度:

 

結論:採用bounding box作為level 1,相比於直接採用人臉檢測器作為level 1,人臉五官特徵點的初始位置預測,誤差可以減少0.02左右,相對精度相當與提高了26%。相關預測效果(藍色的點代表標準點,紅色點表示利用網路進行預測的點):

        

精度的提高還是比較明顯的。

2、68個特徵點測試(level 2 到level 3)

    因為5個點的訓練資料很多,所以上面一開始我才使用5個點的訓練資料1w張,作了bounding box level層的測試。最後為了測試68個點的情況,我從ibug網站:

http://ibug.doc.ic.ac.uk/resources/300-W/   下載了68個點的訓練資料,總共有3k張,我等窮人只能硬著頭皮上,利用3k張做訓練測試。而且我比較懶,資料擴充也只用了360度旋轉,沒有采用映象,因為映象資料擴充的時候,各個特徵點的序號是要改變的,最討厭這些小細節了(特別是五官的裁剪,然後預測到特徵點後,要重新組合,好心煩),所以乾脆不映象了,因為自己一個人要搞這些小細節,實在是很苦逼,很心煩。最後我也沒有使用縮放擴充。(ps:文獻使用了旋轉、映象、縮放等資料擴充,而且也不知到用了多少訓練資料圖片),總之窮人的難處,說多了,都是淚啊,囉嗦了這麼多,該繼續搬磚了……。

在第一部分,我已經測試了bounding box level 1層對leve2 層精度的影響,因此接著我就直接測試從leve2 到leve3 的粗預測到精定位過程(最後驗證,效能跟文獻說的差不多,提高了15%左右)。

(1)鼻子從粗到細

為了清楚檢視從leve2 到leve3 的精度變化我裁剪出鼻子部位的預測結果,進行比較測試(藍色的點代表標準點,紅色點表示利用網路進行預測的點):

      

粗定位                        精定位

試驗1、粗定位&灰度影象:

 

試驗2、精定位&灰度影象&左右expand大小選擇0.3 ,上下expand選擇0.1

 

(2)嘴巴從粗到細

試驗1、粗&灰度影象:

 

試驗2、細&灰度影象:

 

精度反而比粗定位的精度降低了。於是接著我用彩色影象定位嘴巴,得到如下的試驗

試驗3、細&彩色影象:

 

總結:對於嘴巴部位的精度,有可能是訓練資料的原因,最後我是採用彩色影象作為網路的輸入,提高精度

(3)右眼眼睛從粗到細

試驗1、粗&灰度影象

 

 

試驗2、精&灰度影象


 

(4)左眼從粗到細

試驗1、粗&灰度影象:

 

 

試驗2、精&灰度影象:

 

 

(6)左眉毛從粗到細

試驗1、粗&灰度影象:

 

 

試驗2、精&灰度影象:

 

 

(7)51點整體誤差

試驗1、粗&灰度影象:

 

試驗2、精&灰度影象

 

最後結果:

 

左邊圖是標準的基準點,右邊是文獻paper演算法的最後預測結果。

參考文獻:

1、《Extensive Facial Landmark Localization with Coarse-to-fine Convolutional Network Cascade》

2、《Face Alignment at 3000 FPS via Regressing Local Binary Features》

3、《Deep Convolutional Network Cascade for Facial Point Detection》

**********************作者:hjimce   時間:2015.11.29  聯絡QQ:1393852684  原創文章,轉載請保留原文地址、作者等資訊***************