1. 程式人生 > >專案實戰 - 原理講解<-> Keras框架搭建Mtcnn人臉檢測平臺

專案實戰 - 原理講解<-> Keras框架搭建Mtcnn人臉檢測平臺

Mtcnn它是2016年中國科學院深圳研究院提出的用於人臉檢測任務的多工神經網路模型,該模型主要採用了三個級聯的網路,採用候選框加分類器的思想,進行快速高效的人臉檢測。這三個級聯的網路分別是快速生成候選視窗的P-Net、進行高精度候選視窗過濾選擇的R-Net和生成最終邊界框與人臉關鍵點的O-Net。和很多處理影象問題的卷積神經網路模型,該模型也用到了影象金字塔、邊框迴歸、非最大值抑制等技術。

​01什麼是Mtcnn

MTCNN是一個人臉檢測演算法,英文全稱是Multi-task convolutional neural network,中文全稱是多工卷積神經網路,該神經網路將人臉區域檢測與人臉關鍵點檢測放在了一起。該演算法的網路結構總體可分為P-Net、R-Net、和O-Net三層網路結構。

Mtcnn演算法結構圖

總結:Mtcnn分為四步,分別是影象金字塔先把輸入圖片進行縮放,縮放完成之後,我們可以提取出大的人臉和小的人臉,使得網路提取的效果更有效。

然後Pnet網路會對影象金字塔得到的影象進行一個粗略的篩選,得到一大堆的人臉粗略框,然後對這些粗略框進行一個非極大值抑制篩選操作得到相對於好一點的框。再把這些相對好一點的粗略框傳入到Rnet精修網路中,Rnet會對這些粗略框的內部區域進行物體識別,判斷是否是一張人臉,同時對框的長和寬進行修正,然後對調整好的粗略框進行非極大抑制操作篩選出相對上一步更好的框框。

最後這些經過Rnet調整好的相對較好的框框傳入到Onet網路中,Onet依舊判斷這些框的內部區域是否有人臉,同時對Rnet得到的這些框的長和寬再一次進行精修,使得這個框更好的符合人臉大小,最終再進行非極大值抑制操作,得到最終的人臉預測框,與此同時還會得到人臉的5個特徵點的位置。

 

02mtcnn人臉檢測演算法實現思路

對於我們而言,輸入這樣一張人臉圖片,我們可以輕易地知道圖片中哪裡是人臉,哪裡不是人臉,下圖紅色方框的位置就是人臉的部分。

但是計算機時如何識別的呢?mtcnn為計算機提供了一種非常有效的思路:

  • 第一步: 首先mtcnn對我們輸入的一張圖片進行不同尺度的縮放,生成影象金字塔,是為了檢測不同大小的人臉。
  • 第二步:然後將我們活得的影象金字塔傳入Pnet,Pnet會生成一堆相對於原圖的人臉候選框,我們利用這些人臉候選框在原圖片中截取出一塊又一塊地區域,把截取出來的圖片傳入到Rnet中。
  • 第三步:當Rnet接受到這些分散的圖片之後,會對截取出的圖片中是否真正有人臉進行判斷和評分,同時對原有的人臉後選框區域進行修正,通過Rnet我們將獲得一些相對正確的人臉候選框。但是還要繼續進行二次修正。
  • 第四步:我們利用Rnet修正後的人臉候選框再次從原圖片中擷取一塊又一塊的區域,把截出來的區域圖片傳入到Onet中,Onet是mtcnn中最精細的網路,它會再次對擷取圖片內中是否真正存在人臉進行判斷和評分,同時把人臉候選框進行修正,Onet輸出結果就是我們需要的人臉位置了。

Mtcnn實現流程圖

03Mtcnn具體實現流程

1.構建影象金字塔

當我們輸入一張圖片X到mtcnn網路模型進行預測時,首先會對我們的圖片進行不同尺度的縮放,構建我們的影象金字塔。

如:上圖中的左圖。構建過程中圖片的不同縮放尺度是由縮放係數factor決定的,通過不同的縮放係數factor對圖片進行縮放,每次縮小為原來圖片縮放的factor大小。其實就是對我們的原圖進行多次縮放,每次縮放的比例是一個確定的數factor=0.709,第一次縮放為原圖X尺寸的0.709倍得到0.709X尺寸的圖片,第二次對已經縮放的圖片再次進行縮放0.709*0.709X尺寸的圖片,依次類推,我們將會得到非常多原圖的不同尺寸的圖片。

這樣的縮放的目的是為了能夠檢測圖片中不同大小的人臉,因為我們拍攝一張圖片,裡面的人臉會有大有小,這樣的一個影象金字塔縮放操作,就是為了讓我們獲得不同大小的人臉的特徵。通過這樣的一個影象金字塔的構建,我們會獲得非常多的圖片,縮放截止的點是:當縮放的最後的一張的圖片的長或者寬小於12時就停止縮放。構建完影象金子塔之後,我們就帶著這一大堆的圖片到Pnet網路中。

實現程式碼:

如下,當一個圖片輸入的時候,會縮放為不同大小的圖片,但是縮小後的長寬最小不可以小於12

 

2.Pnet

Pnet的全稱為Proposal Network, 作用是給出一些框的一個建議位置。它的基本構造是一個全連線網路FNC,對上一步構建完成的影象金字塔,通過一個全連線網路FCN進行初步特徵提取和邊框的標定。如下圖:

Pnet網路處理過程

​初步特徵提取和邊框標定

當我們將影象金字塔的圖片輸入到Pnet網路之後,會輸出classifier和bbox_regress兩個引數。

Pnet的兩個輸出:

  • classifier: 用於判斷該網格點上的框的可信度
  • bbox_regress: 用於表示該網格點上框的位置

Pnet和yolov3有一定的相似,當我們的圖片經過卷積神經網路的卷積之後,它的特徵層的長和寬會進行一定的縮小,有可能會是原圖的2分之一,4分之一,Pnet是將變為了原來的2分之一,也就是每隔兩個畫素點會有一個特徵點(網格點),這個特徵點就負責預測它的右下角這個區域的檢測。

classifier就表示這個特徵點負責的這個右下角區域有沒有人臉,bbox_regression就代表這個右下角區域中有人臉的長和寬的框的位置。我們通過Pnet就獲得了這樣的一系列的框框,如上圖的左圖,得到的框框有很多是重疊的,我們就利用非極大抑制操作在每一個區域中挑選出分數最大的一個框,並將這個區域中和這個分數最大的框重合程度大的那些框框進行剔除,只保留這個區域中得分最高的那個框,從而篩選掉一些框框,保留下來一些稍微有精度的一些框,然後我們就帶這些的精度的框就傳入到Rnet網路中。

Pnet的網路比較簡單,實現程式碼如下:

在完成初步特徵提取後,還需要進行Bounding-Box Regression 調整視窗與非極大值抑制進行大部分視窗的過濾。Pnet有兩個輸出,classifier用於判斷這個網格點上的框的可信度,bbox_regress表示框的位置。bbox_regress並不代表這個框在圖片上的真實位置,如果需要將bbox_regress對映到真實影象上,還需要進行一次解碼過程。

解碼過程利用detect_face_12net函式實現,其實現步驟如下(需要配合程式碼理解):

  • 1、判斷哪些網格點的置信度較高,即該網格點記憶體在人臉。
  • 2、記錄該網格點的x,y軸。
  • 3、利用函式計算bb1和bb2,分別代表圖中框的左上角基點和右下角基點,二者之間差了11個畫素,堆疊得到boundingbox 。
  • 4、利用bbox_regress計算解碼結果,解碼公式為boundingbox = boundingbox + offset*12.0*scale,這個就是框對應在原圖上的框的位置。

簡單理解就是Pnet的輸出就是將整個網格分割成若干個網格點,;然後每個網格點初始狀態下是一個11x11的框,這個由第三步得到;之後bbox_regress代表 每個網格點確定的框 的 左上角基點和右下角基點 的偏移情況。

Pnet解碼程式碼:

 

3.Rnet

Rnet全稱為Refine Network, 維/精修神經網路。它的基本構造是一個卷積神經網路,相對於第一層的P-Net網路來說,它增加了一個全連線層,因此對輸入的資料篩選會更加嚴格。當我們的影象金字塔的圖片經過P-Net網路之後,會留下許多預測視窗,我們將所有的預測視窗代表的人臉區域從圖片中截取出來傳入到Rnet網路之中,Rnet會根據截取出來的人臉計算它們的分數以及它們長和寬需要調整的地方。Pnet會給出人臉候選區域的以左上角和右下角形式表示的框的位置,也就是預測視窗,我們就是根據Pnet預測的框的左上和右下角的位置從原圖中截取出原圖帶有人臉的區域再送到Rnet中,Rnet會首先對這個截取出來的區域進行內容的可信度判斷,即判斷是否是一張人臉,同時會對Pnet預測的粗略的框進行寬和高的修正,使得調整後的框更符合人臉的一個大小。

Rnet也有兩個輸出classifier和bbox_regress: classifier用於判斷這個網格點上的框的可信度,bbox_regress用來輔助調整Pnet獲得的粗略框,表示調整後的框的位置。

經過這樣調整之後我們就進行非極大值抑制操作進行再次篩選,保留下來比Pnet更優秀的一些框,但是還會存在如上圖中右圖的那個眼睛部分的那樣的小框問題,所以要進入一個比Rnet更嚴格的神經網路Onet進行修正。

Rnet網路:

最後對Rnet選定的候選框進行Bounding-Box Regression和非極大值抑制NMS進一步優化預測結果。

Rnet的兩個輸出classifier和bbox_regress,bbox_regresss並不代表這個框在圖片上的真實位置,而是調整引數,所以如果需要將bbox_regress對映到真實影象上,還需要進行解碼操作:

解碼過程需要與Pnet的結果進行結合。 在程式碼中,x1、y1、x2、y2代表由Pnet得到的圖片在原圖上的位置,w=x2-x1和h=y2-y1代表Pnet得到的圖片的寬和高,bbox_regress與Pnet的結果結合的方式如下:

其中dx1、dx2、dy1、dy2就是Rnet獲得的bbox_regress,實際上Rnet獲得bbox_regress是長寬的縮小比例。

Rnet解碼程式碼

4.Onet

Onet和Rnet的工作流程十分相似,它的全稱為Output Network, 基本結構是一個較為複雜的卷積神經網路,相對於Rnet來說多了一個卷積層。Onet的效果與Rnet的區別在於Onet的這一層結構會通過更多的監督來識別面部的區域,而且會對人的面部特徵點進行迴歸,最終輸出5個人臉面部特徵點。

 

Onet會對Rnet的輸出,也是Onet的輸入,進行再次調整以消除像Rnet的輸出中眼睛部分的這樣的框框。首先我們會對Rnet網路輸出結果中的候選框對應的原圖中這樣的區域截取出來傳入到Onet網路中,Onet會首先判斷這個截取出來的區域是否真正含有人臉,然後對這個區域的Rnet的候選框的長和寬進行調整,與此同時識別出人臉面部的5個特徵點。

因此Onet會有3個輸出:classifier、bbox_regress、landmark_regress

  • claassifier: 這個網格點上框的可信度
  • bbox_regress: 這個網格點上框調整的一個範圍
  • landmark_regress: 表示人臉上的5個標誌點

Onet網路:

最後對Onet網路選定的候選框進行Bounding-Box Regression和NMS進一步優化預測結果。

Onet有三個輸出,classifier用於判斷這個網格點上的框的可信度,bbox_regress表示框的位置,landmark_regress表示臉上的五個標誌點。

bbox_regress並不代表這個框在圖片上的真實位置,如果需要將bbox_regress對映到真實影象上,還需要進行一次解碼過程。

解碼過程需要與Rnet的結果進行結合。在程式碼中,x1、y1、x2、y2代表由Rnet得到的圖片在原圖上的位置,w=x2-x1和h=y2-y1代表寬和高,bbox_regress與Rnet的結果結合的方式如下:

其中dx1、dx2、dy1、dy2就是Onet獲得的bbox_regress,實際上Onet獲得bbox_regress是長寬的縮小比例。

Onet解碼過程:

 

04 論文和程式碼下載

在後臺回覆關鍵字:專案實戰,獲取Mtcnn論文和專案原始碼。

05環境配置

  • Windows10
  • Anaconda + Pycharm
  • tensorflow-gpu==1.15.0
  • keras-gpu==2.1.5

 

06Mtcnn預測結果

人臉檢測是實現人臉識別的第一步,下期就講解如何藉助Mtcnn人臉檢測演算法和facenet演算法搭建人臉識別平臺,程式碼下載:更多有關python、深度學習和計算機程式設計和電腦知識的精彩內容,可以關注微信公眾號:碼農的後花園 , 如果覺得不錯的話,請給號主一個點贊吧! 感謝!

&n