接上一篇,一切順利的話,你從github上clone下來的整個工程應該已經成功編譯並生成dll和exe文件了;同時,ImageMagic程序亦能夠打開並編輯圖像了,如此,證明接下來的操練你不會有任何障礙。開篇序文已經說過,工具庫緣起人臉識別。我開博后的第一個系列講了TensorFlow下的人臉識別,寫完之后就覺得方向錯了,那個系列采用的方案其實更適合物體檢測、分類,而不是人臉識別。所以,基於歷史原因,我決定這個系列還是從人臉識別開始,讓諸君看看改進后的方案到底是怎樣的。首先聲明,改進后的方案參考了如下一篇博文:
https://blog.csdn.net/mr_curry/article/details/52443126
方案的基本原理及核心算法參照該博文實現,並不是本人原創,要感謝該篇博文的作者。只不過有些遺憾的是,該作者並沒有在blog上提供完整代碼(少了一個函數),且提供的代碼亦存在些許錯誤;同時,對同一張圖片的多次預測結果並不一致,存在計算結果溢出的情形。雖如此,但還是要感謝博文作者,核心算法很明了,且有效,再次感謝!我在原文的核心算法基礎上,按照我自己的設計原則做了重構和編碼,除了算法原理,代碼和結構與原文完全不同,請諸君注意。
我自己的學習習慣是——先看效果,然后再決定是否跟進研究此項技術,我想諸君大抵以如此。故,我們先運行一下程序看看效果如何。事先聲明,如果你在接下來的操作中出現任何問題,請回頭閱讀該系列第一篇文章,確定完全達成第一篇的目標后再來這里。前文已經說過,EXE工程“WhoYouAre”即為圖像級的人臉識別應用,因此,你應當在工程的輸出目錄“MachineVisionLib\x64\bin”下看到該應用程序的可執行文件:“WhoYouAre.exe”,如下圖:

在該文件夾空白處,按住鍵盤“Shift”鍵不要松開,然后鼠標右鍵菜單選擇“在此處打開命令窗口(W)”,如此,我們進入windows控制台:

為了將來能夠看到完整的控制台輸出信息,建議你鼠標左鍵點擊控制台窗口左上角的圖標,在彈出的菜單中打開“屬性”窗口,將控制台“布局”設置大一些,最好能夠占滿整個屏幕,這樣你才能看到完整的程序輸出信息。設置完畢后,請在控制台輸入:
WhoYouAre
控制台會輸出該程序的Usage信息:

看着有很多選擇,其實就人臉注冊和人臉識別兩項功能而已。這么多的選擇只是為了編碼方便,因為視頻文件、視頻流和圖像(照片)在實際處理上均有些許不同,需要單獨處理,所以選擇看起來就比較多了:
WhoYouAre.exe add 使用照片注冊人臉
WhoYouAre.exe predict 使用照片進行預測,控制台輸出預測結果(人名和概率)
WhoYouAre.exe ocvcamera 通過捕獲USB/WEB攝像頭的實時視頻進行人臉識別,參數值為攝像頭序號,播放器為OCV自帶播放器——ffmpeg
WhoYouAre.exe ocvvideo 通過視頻流進行預測,參數值為視頻地址,可以是本地的視頻文件或rtsp地址,播放器依然是OCV自帶播放器
WhoYouAre.exe vlcvideo_rtsp_predict 通過捕獲rtsp實時視頻進行人臉識別,參數值為rtsp地址,播放器為libvlc播放器
WhoYouAre.exe vlcvideo_predict 通過本地視頻文件進行人臉識別,參數值為本地視頻文件名
WhoYouAre.exe vlcvideo_rtsp_catchface 通過rtsp視頻流檢測人臉並注冊到人臉庫,參數值為rtsp視頻流地址
WhoYouAre.exe vlcvideo_catchface 通過本地視頻文件檢測人臉並注冊到人臉庫,參數值為本地視頻文件名
這些選項中,幾個視頻預測選項在CPU模式下存在卡頓、掉幀的問題,主要是因為人臉檢測與識別處理花費了太長的時間;GPU模式下,GTX 1050Ti顯卡加速測試,幀率(FPS)高於15幀時視頻播放開始呈現太空漫步狀態,動作明顯變慢,識別性能同樣表現不佳。至於時間到底耗費在了哪些處理上,我會在后面的篇幅中詳細講解,讓我們先看看圖片預測的效果。
在第一篇clone的工程中,“x64\bin\FACE-PICS”文件夾下是我做測試的圖片,除了兩個國外的電影明星,其他三人均是牛人,特別是黃老和袁老,更是民族的脊梁,吾輩之楷模。我們第一步要做的工作就是要先將他們注冊到我們的系統中。首先,在“x64\bin”文件夾下建立“PERSONS”文件夾,保存人臉特征數據:

然后,控制台輸入如下指令:
WhoYouAre add .\FACE-PICS\HuangXuHua.jpg "Huang Xu Hua"
回車執行,我們會看到控制台輸出了一大串信息,這些信息包括DNN網絡結構以及預訓練模型被加載時的調試輸出信息。一切順利的話,我們會在這一大串信息的尾部看到黃老被成功添加到系統中的提示信息:

此時,“PERSONS”文件夾下面會出現“Huang Xu Hua.xml”文件,這個文件保存的就是黃老臉部的特征數據:

該文件的主要內容就是2622個臉部特征值,浮點數:

而在“x64\bin”下面則多了一個“FACEDB_STATISTIC.xml”文件,它是系統的統計文件,用於記錄系統已注冊的人臉數量以及人名長度。它存在的意義就是為了簡化算法實現,節省系統資源。關於它的使用方法,我會在講解算法實現時再說。至此,第一個人臉已注冊完畢。當然,只注冊一個人臉是遠遠不夠的,要想測試算法的可靠性,接下來我們還需要將其余幾人注冊到系統中,最終的注冊結果如下:

統計文件“FACEDB_STATISTIC.xml”的內容變成了這樣:

統計文件的內容很直觀,我們總共添加了5個人,人名總長度67個字節。
人臉注冊完畢,接下來該是試試效果了。控制台輸入如下指令:
WhoYouAre predict .\FACE-PICS\YuanLongPing-1.jpg
回車執行,我們會看到和注冊時類似的輸出信息,稍等幾秒, 我們同樣會在控制台輸出信息的尾部看到預測結果:

在已經存在5個人的人臉庫中,程序還是順利找到了袁老,相似度為0.869506,基本上相似度超過85%就可以確定是這個人了。上圖中還有兩個數據需要關注(紅色箭頭所指處),這兩個數據統計的是本次人臉識別花費的時間,其中1009.4ms統計的是總時間,782.14ms統計的是DNN網絡提取臉部特征數據花費的時間。從數據上看,時間花費很可觀,基本上1秒識別一張。當然,必須告訴你的是,這是CPU模式下的時間統計,那么GPU模式下會怎么樣呢?很簡單,將程序切換到GPU模式下(關於如何切換到GPU模式,請看上一篇),再執行一次看看效果:

時間明顯變小,1秒至少能處理4張了。需要特別提醒的是,這個時間其實還可以再縮小,因為在這里我使用的人臉檢測函數是ShiQi.Yu老師的libfacedetection,它在檢測人臉時耗時很大,caffe的人臉檢測預訓練模型要比這小很多,因此視頻檢測我就使用了caffe預訓練模型。如果你有時間,可以把這部分代碼調整為預訓練模型方式。不過,無論何種方式,CPU與GPU模式在識別性能上的差距均非常明顯,特別是在視頻識別上,兩者差距異常明顯。
為了直觀感受視頻識別的性能問題,現在需要把自己注冊到系統中了。有兩種方式注冊自己:一種是使用自己的照片,按照上面介紹的步驟注冊人臉;第二種是通過攝像頭錄制一段視頻或直接捕獲攝像頭視頻流,然后在控制台輸入如下指令:
WhoYouAre vlcvideo_catchface xx.avi
或
WhoYouAre.exe vlcvideo_rtsp_catchface rtsp://xx.xx.xx/h264/ch1
直接注冊人臉。第一種方式不再贅述,關於第二種方式,操作其實很簡單。首先,WhoYouAre不支持USB/WEB攝像頭的直接注冊,僅支持rtsp流的直接注冊。如果你手頭只有USB/WEB攝像頭,那么需要先錄制一段包含你的人臉的視頻,然后輸入第一條指令(xx.avi換成你的視頻文件名)即可進行人臉注冊。如果你有網絡攝像頭,則輸入第二條指令即可。當然,別忘了將rtsp地址換成你自己的地址。無論你使用哪條指令,WhoYouAre程序都會彈出播放界面,並將檢測到的人臉用矩形框框出。你可以根據框出的人臉清晰度來判定是否滿足注冊要求,如滿足,則立即按鍵盤“回車”鍵。此時,框出的人臉會被截取到一個單獨窗口中顯示,繼續“回車”則當前這張人臉將被注冊到系統中:

其實整個人臉注冊操作就是找到人臉后的兩個“回車”,之后,我們會在控制台看到相應的輸出信息:

提示“Face-0”已被添加到人臉庫中。此時我們還需要將這個“Face-0”改為正確的名字,打開“x64\bin\PERSONS”文件夾,找到“Face-0.xml”,將其重新命名為你自己的名字即可,比如“Neo.xml”。然后,再回頭修改“x64\bin”目錄下的“FACEDB_STATISTIC.xml”文件,將“PERSONNAME_TOTAL_LENGTH”標簽下的人名總長度改為修改后的長度。比如原來是74個字節,名字改為“Neo”后,比“Face-0”少了3個字節,那么人名總長度就要減去3個字節,變為71。這樣,就完成了視頻人臉注冊的過程。
接下來我們就測測視頻識別的性能表現如何。先是CPU模式,控制台輸入如下指令:
WhoYouAre ocvvideo xx.avi
回車,程序執行后我們注意觀察控制台輸出,會發DNN網絡的特征提取時間比較長,大約在600-700毫秒之間:

也就是說,只要視頻幀中檢測到人臉,那么這一幀的畫面就要在人眼中存留600-700毫秒,然后才能切換到下一幀,這樣的延時會帶來怎樣的播放效果呢:

果然,視頻中的美女變成了“樹懶”,表情變化過程看得那叫一個真吶!同樣,我們使用libvlc播放器(指令:WhoYouAre vlcvideo_predict xx.avi)耗費的時間與OCV自帶播放器差不多,也是在600-700毫秒之間。只不過當我們使用rtsp流進行人臉識別時,OCV播放器就表現很差了(指令:WhoYouAre ocvvideo rtsp地址),基本上會出現連續掉幀的情形,同時,控制台輸出也慘不忍睹:

此時不僅播放都成問題,別說實時識別人臉了,所以實時視頻流識別我們需要采用libvlc播放器(指令:WhoYouAre vlcvideo_predict rtsp地址),本地視頻文件識別兩種播放器均可。那么,GPU模式下視頻識別的效果如何呢?首先將程序切換到GPU模式,然后再次輸入“WhoYouAre.exe ocvvideo xx.avi”,程序執行結果如下圖所示:

動作依然明顯變緩,只不過比CPU模式要好很多,至少不是“樹懶”了。那么問題來了,GPU模式都這樣的話,時間到底去哪兒了呢?我們來看一下播放上述視頻時控制台的輸出:

程序在兩個地方計時,一個是總的預測時間(Time spent of predict),另一個是DNN網絡提取特征的時間(Execution time of caffe net Forward())。每一幀的總預測時間包含了特征提取時間,很明顯特征提取時間在其中占比很小,甚至可以忽略不計。但總時間始終維持在在60-80毫秒之間,而我播放的這個視頻的幀率為24,也就是每幀間隔40毫秒多一點,超過這個時間就會使得視頻呈慢動作狀態。顯然,我們看到的播放效果與計算結果一致——預測時間太長了,使得正常的視頻播放都變慢了。那么這個時間到底花費在了哪里呢?其實,時間花費在了人臉檢測、Dlib庫68個人臉特征點提取上,至於這兩個地方具體花費了多少時間需要我們在源文件的相應位置添加性能監測代碼才可。關於這一點,我將在后面講解人臉識別模塊的編碼實現時詳細描述,本文不再細究。
