本文中的知識來自於Mastering opencv with practical computer vision project一書。
本文實施的臉部跟蹤算法都是基於數據驅動的,主要包括兩個部分,訓練和測試。訓練就是通過臉部標記點的采樣數據,訓練得到一個標准的臉部模型,而測試部分就是把檢測到的臉部和標准臉部模型比較,求得眼睛,鼻子等臉部特征。具體來講,臉部跟蹤分為三個部分:shape model形狀模型,就是訓練數據表示為什么樣的形狀模型;feature detector特征檢測,檢測目標臉中的特征;fitting algorithm適應算法,就是匹配算法,匹配檢測到的目標特征點和訓練的形狀模型結果。
一、訓練數據准備
從http://www.milbo.org/muct/下載訓練數據集,該數據集包括3755張人臉圖像,以及人臉特征點標記文件。人臉特征點標記文件中,包括所有圖像的特征點標記,每副圖像76個特征點。解壓下載的壓縮文件后,圖像文件都在jpg目錄中,另外我們得到文件muct76-opencv.csv,該文件中保存的都是圖像的特征點標記。
打開文件muct76-opencv.csv,我們得到下面數據,第一列為圖像文件名,從第三列開始為76個特征點的x,y坐標。
name,tag,x00,y00,x01,y01,x02,y02,x03,y03,x04,y04,x05,y05,x06,y06,x07,y07,x08,y08,x09,y09,x10,y10,x11,y11,x12,y12,x13,y13,x14,y14,x15,y15,x16,y16,x17,y17,x18,y18,x19,y19,x20,y20,x21,y21,x22,y22,x23,y23,x24,y24,x25,y25,x26,y26,x27,y27,x28,y28,x29,y29,x30,y30,x31,y31,x32,y32,x33,y33,x34,y34,x35,y35,x36,y36,x37,y37,x38,y38,x39,y39,x40,y40,x41,y41,x42,y42,x43,y43,x44,y44,x45,y45,x46,y46,x47,y47,x48,y48,x49,y49,x50,y50,x51,y51,x52,y52,x53,y53,x54,y54,x55,y55,x56,y56,x57,y57,x58,y58,x59,y59,x60,y60,x61,y61,x62,y62,x63,y63,x64,y64,x65,y65,x66,y66,x67,y67,x68,y68,x69,y69,x70,y70,x71,y71,x72,y72,x73,y73,x74,y74,x75,y75
i000qa-fn,0000,201,348,201,381,202,408,209,435,224,461,241,483,264,498,292,501,319,493,338,470,353,448,363,423,367,395,366,371,357,344,355,316,340,311,325,318,309,328,327,324,342,317,217,328,231,323,250,327,269,333,251,334,233,331,229,345,240,337,262,349,242,352,241,344,346,337,330,330,318,341,334,344,330,336,280,344,278,381,264,399,273,406,293,409,316,399,321,392,304,376,296,342,279,402,310,399,251,431,268,427,284,425,293,425,302,423,316,425,329,426,320,442,309,451,295,454,278,452,263,442,277,440,293,442,313,437,313,429,293,432,277,431,293,436,295,395,234.5,341,251,343,252,350.5,235.5,348.5,338,333.5,324,335.5,326,342.5,340,340.5
...
比如第二行數據,即為圖像i000qa-fn.jpg的特征點標記,標記顯示出來即為下圖的效果:
二、得到yaml格式的數據文件
訓練臉部跟蹤算法的數據有四部分:
1、圖像
2、標記點
3、標記點的對稱索引
4、連通性索引
imnames向量中存放的是圖像文件的名字,imnames的size即為樣本圖像的數量。points中存放的是標記點,每副圖像對應76個標記點,所以它采用二維vector的方式定義。symmetry中存放的是points中點的索引,它指定points中那些點需要鏡像。
vector<int> symmetry; //對稱點索引,標指出那些特征點需要鏡像
vector<Vec2i> connections; //連通點索引,兩個索引指定2個點的連通關系。
vector<string> imnames; //圖像
vector<vector<Point2f> > points; //標記點
最后我們把訓練數據保存在yaml文件中,shapes的每一列表示一副圖像的76個特征點x、y坐標。
最后生成的數據文件為annotations.yaml內容為:
%YAML:1.0
ft object:
n_connections: 47
connections 0 0: 21
connections 0 1: 2
....
n_symmetry: 76
symmetry 0: 1
symmetry 1:
...
n_images: 2914
image 0: "..\\muct\\jpg\\i000qa-fn.jpg
...
shapes: !!opencv-matrix
rows: 152
cols: 2914
dt: f
data: [ 201., 157., 201., 187., 145., 182., 190., 152., 191., 162.,
110., 140., 118., 164., 166., 114., 135., 123., 168., 166.,
113., 143., 123., 168., 224., 183., 230., 221., 182., 226.
...
程序源代碼:工程FirstOpenCV39
程序運行后,會從muct76-opencv.csv中把標記點讀入到class ft_data中,之后會把它寫入annotations.yaml。然后提示我們用鼠標選取連通性,選取完后,按q鍵,會把連通信息保存到annotations.yaml中,之后進入選取需要對稱的標記點界面,我們可以用鼠標點擊需要鏡像的標記點,按q鍵后,保存到annotations.yaml文件中。
注意程序執行時帶的兩個參數為:-m ..\muct\jpg\ -d ..\muct\out\
其中-m指定輸入圖像的目錄,-d 指定輸出ymal文件的目錄。
我們在solution文件同層目錄建立muct目錄,里面包括子目錄jpg,存放圖片文件,子目錄muct-landmarks中包括文件muct76-opencv.csv,out子目錄為輸入yaml文件的目錄。