需求
啟動攝像頭,在預覽視頻流中識別人臉,并標注人臉框;當用戶按下拍照按鈕,將人臉部分裁剪出來,現(xiàn)實在ImageView中。

解決方案
開發(fā)環(huán)境:android studio、ecplise
1.人臉標注功能可采用第三方依賴庫實現(xiàn),如谷歌自帶的FaceDetector、Face++、科大訊飛等。當拍照按鈕被按下,先把整張圖像保存下來,再啟動系統(tǒng)自帶的CROP應用,指引用戶手動定位到人臉區(qū)域并截圖。
? ?缺點:操作復雜,用戶需進行4次點擊操作;整個流程下來耗時約7秒。
2.采用開源庫open cv,該已封裝好人臉檢測功能,可自動將人臉區(qū)域標注出來,當用戶按下拍照按鈕,直接將人臉數(shù)據(jù)轉(zhuǎn)換為bitmap,即可顯示。
? ?缺點:open cv對安卓系統(tǒng)的兼容性還不是很好,相應的so庫需要手動編譯。版本也較多,不同版本之間的也有一定的差異性。
明顯看得出,第二方案優(yōu)于第一方案,花了好一些時間,填了好些坑才把功能調(diào)通了。下面把整個debug過程記錄下來,供他人參考。
1.文件下載
第一想法,是去官網(wǎng)opencv.org/下,目前官網(wǎng)提供的最新版本是3.2,是寄存在Github上,可能是由于國外服務器的原因,我電腦沒翻墻,就總是下載不了,也沒啥錯誤提示?,F(xiàn)在我把文件上傳到了百度云盤,方便大家下載:pan.baidu.com/s/1qYyfxzI
文件的結(jié)構(gòu)我就不去分析了,網(wǎng)上很多這方面的資料。
2.so庫編譯
官網(wǎng)提供的文件里面并沒有包含android可調(diào)用的so庫文件,只提供了相應的頭文件、編譯文件。關(guān)于這點,我也是挺疑惑的,為何官網(wǎng)不直接編譯好so文件,同時也保留相應的頭文件、編譯文件,有特殊需求的再去重新編譯。
實現(xiàn)ndk編譯,需要先搭建好編譯環(huán)境(搭建方法,百度一下,要多詳細有多詳細)。打開cmd,進入到項目(我這里用的是face-detection)結(jié)構(gòu)下的jni文件夾,如:

輸入 ndk-build 執(zhí)行后,libs下(我用的是ecplise)便會多出一個文件:

3.排除錯誤
將項目和sdk都導入到ecplise中,會提示camera2這個類找不到。查了一下,這個類是從Android5.0之后才引入的,但opencv sdk默認的編譯版本是4.0.這點上,感覺官方真的好坑。解決起來也很容易,修改project.properties文件中的target=android-21
解決以上錯誤后,項目就可以跑起來了,但如果沒有第2步編譯的so文件,應用一啟動就會蹦了,log只看到某個類加載不了。在這里卡了好一段時間,官方既不提供so庫,log提示又沒有明確說明是由于某個動態(tài)庫未加載。
4.去除manager
在使用某個功能時,需要先安裝一個manager.apk應用,官方將某些服務封裝到了manager.apk里面。無疑,這是一個很雞肋的操作。
其實要解決起來也很簡單,在官網(wǎng)下載的文件中,找到sdk-->native-->libs-->armeabi-v7(這是我的設備架構(gòu),大家需要根據(jù)自己的設備來選擇不同的文件夾)-->libopencv_java3.so ? 將該文件拷貝至項目下,clean一下,再運行,就可以脫離manager.apk正常運行了。
5.數(shù)據(jù)格式轉(zhuǎn)換
face-detection項目跑起來后,也只是捕捉到了人臉數(shù)據(jù)。我們需要將rect類型的數(shù)據(jù)轉(zhuǎn)換為bitmap,但官網(wǎng)并沒有提供現(xiàn)有的方式進行轉(zhuǎn)換,只能講rect先轉(zhuǎn)為mat,再轉(zhuǎn)換為bitmap,相關(guān)函數(shù)為:
rect-->mat? Utils.matToBitmap(Rect roi)
mat-->bitmap Utils.matToBitmap(Mat mat, Bitmap bitmap);
總結(jié)
以上看似簡單的幾個步驟,實際上花了將近一周的時間,現(xiàn)在回頭想想,根源是對opencv實現(xiàn)流程不熟悉,套用慣性思維去對待。下意識總覺著,官方下載下來的東西都是可以直接跑的。這次算是長見識了。如對上述項目源碼有需要的,可以將郵箱留言,我會第一時間給你發(fā)過去。opencv還有很多強大的功能,后期有時間慢慢研究。