Android API 人臉檢測(Face Detect)
通過兩個主要的API,Android提供了一個直接在點陣圖上進行臉部檢測的方法,這兩個API分別是 android.media.FaceDetector和android.media.FaceDetector.Face,已經包含在Android官方API中。向大家介紹了這些API。
所謂人臉檢測就是指從一副圖片或者一幀視訊中標定出所有人臉的位置和尺寸。人臉檢測是人臉識別系統中的一個重要環節,也可以獨立應用於視訊監控。在數字媒體日益普及的今天,利用人臉檢測技術還可以幫助我們從海量圖片資料中快速篩選出包含人臉的圖片。 在目前的數碼相機中,人臉檢測可以用來完成自動對焦,即“臉部對焦”。“臉部對焦”是在自動曝光和自動對焦發明後,二十年來最重要的一次攝影技術革新。家用數碼相機,佔絕大多數的照片是以人為拍攝主體的,這就要求相機的自動曝光和對焦以人物為基準。
構建一個人臉檢測的Android Activity
你可以構建一個通用的Android Activity,我們擴充套件了基類ImageView,成為MyImageView,而我們需要進行檢測的包含人臉的點陣圖檔案必須是565格式,API才能正常工作。被檢測出來的人臉需要一個置信測度(confidence measure),這個措施定義在android.media.FaceDetector.Face.CONFIDENCE_THRESHOLD。
最重要的方法實現在setFace(),它將FaceDetector物件例項化,同時呼叫findFaces,結果存放在faces裡,人臉的中點轉移到MyImageView。程式碼如下:
- publicclass TutorialOnFaceDetect1 extends Activity {
- private MyImageView mIV;
- private Bitmap mFaceBitmap;
- privateint mFaceWidth = 200;
- privateint mFaceHeight = 200;
- privatestaticfinalint MAX_FACES = 1;
- privatestatic String TAG = "TutorialOnFaceDetect";
- @Override
- publicvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mIV = new MyImageView(this);
- setContentView(mIV, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
- // load the photo
- Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.face3);
- mFaceBitmap = b.copy(Bitmap.Config.RGB_565, true);
- b.recycle();
- mFaceWidth = mFaceBitmap.getWidth();
- mFaceHeight = mFaceBitmap.getHeight();
- mIV.setImageBitmap(mFaceBitmap);
- // perform face detection and set the feature points setFace();
- mIV.invalidate();
- }
- publicvoid setFace() {
- FaceDetector fd;
- FaceDetector.Face [] faces = new FaceDetector.Face[MAX_FACES];
- PointF midpoint = new PointF();
- int [] fpx = null;
- int [] fpy = null;
- int count = 0;
- try {
- fd = new FaceDetector(mFaceWidth, mFaceHeight, MAX_FACES);
- count = fd.findFaces(mFaceBitmap, faces);
- } catch (Exception e) {
- Log.e(TAG, "setFace(): " + e.toString());
- return;
- }
- // check if we detect any faces
- if (count > 0) {
- fpx = newint[count];
- fpy = newint[count];
- for (int i = 0; i < count; i++) {
- try {
- faces[i].getMidPoint(midpoint);
- fpx[i] = (int)midpoint.x;
- fpy[i] = (int)midpoint.y;
- } catch (Exception e) {
- Log.e(TAG, "setFace(): face " + i + ": " + e.toString());
- }
- }
- }
- mIV.setDisplayPoints(fpx, fpy, count, 0);
- }
- }
接下來的程式碼中,我們在MyImageView中新增setDisplayPoints() ,用來在被檢測出的人臉上標記渲染。圖1展示了一個標記在被檢測處的人臉上處於中心位置。
- // set up detected face features for display
- publicvoid setDisplayPoints(int [] xx, int [] yy, int total, int style) {
- mDisplayStyle = style;
- mPX = null;
- mPY = null;
- if (xx != null && yy != null && total > 0) {
- mPX = newint[total];
- mPY = newint[total];
- for (int i = 0; i < total; i++) {
- mPX[i] = xx[i];
- mPY[i] = yy[i];
- }
- }
- }
圖1:單一人臉檢測
多人臉檢測
通過FaceDetector可以設定檢測到人臉數目的上限。比如設定最多隻檢測10張臉:
- privatestaticfinalint MAX_FACES = 10;
圖2展示檢測到多張人臉的情況。
圖2:多人人臉檢測
定位眼睛中心位置
Android人臉檢測返回其他有用的資訊,例同時會返回如eyesDistance,pose,以及confidence。我們可以通過eyesDistance來定位眼睛的中心位置。
下面的程式碼中,我們將setFace()放在doLengthyCalc()中。同時圖3展示了定位眼睛中心位置的效果。
- publicclass TutorialOnFaceDetect extends Activity {
- private MyImageView mIV;
- private Bitmap mFaceBitmap;
- privateint mFaceWidth = 200;
- privateint mFaceHeight = 200;
- privatestaticfinalint MAX_FACES = 10;
- privatestatic String TAG = "TutorialOnFaceDetect";
- privatestaticboolean DEBUG = false;
- protectedstaticfinalint GUIUPDATE_SETFACE = 999;
- protected Handler mHandler = new Handler(){
- // @Override
- publicvoid handleMessage(Message msg) {
- mIV.invalidate();
- super.handleMessage(msg);
- }
- };
- @Override
- publicvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mIV = new MyImageView(this);
- setContentView(mIV, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
- // load the photo
- Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.face3);
- mFaceBitmap = b.copy(Bitmap.Config.RGB_565, true);
- b.recycle();
- mFaceWidth = mFaceBitmap.getWidth();
- mFaceHeight = mFaceBitmap.getHeight();
- mIV.setImageBitmap(mFaceBitmap);
- mIV.invalidate();
- // perform face detection in setFace() in a background thread
- doLengthyCalc();
- }
- publicvoid setFace() {
- FaceDetector fd;
- FaceDetector.Face [] faces = new FaceDetector.Face[MAX_FACES];
- PointF eyescenter = new PointF();
- float eyesdist = 0.0f;
- int [] fpx = null;
- int [] fpy = null;
- int count = 0;
- try {
- fd = new FaceDetector(mFaceWidth, mFaceHeight, MAX_FACES);
- count = fd.findFaces(mFaceBitmap, faces);
- } catch (Exception e) {
- Log.e(TAG, "setFace(): " + e.toString());
- return;
- }
- // check if we detect any faces
- if (count > 0) {
- fpx = newint[count * 2];
- fpy = newint[count * 2];
- for (int i = 0; i < count; i++) {
- try {
- faces[i].getMidPoint(eyescenter);
- eyesdist = faces[i].eyesDistance();
- // set up left eye location
- fpx[2 * i] = (int)(eyescenter.x - eyesdist / 2);
- fpy[2 * i] = (int)eyescenter.y;
- // set up right eye location
- fpx[2 * i + 1] = (int)(eyescenter.x + eyesdist / 2);
- fpy[2 * i + 1] = (int)eyescenter.y;
- if (DEBUG) {
- Log.e(TAG, "setFace(): face " + i + ": confidence = " + faces[i].confidence()
- + ", eyes distance = " + faces[i].eyesDistance()
- + ", pose = ("+ faces[i].pose(FaceDetector.Face.EULER_X) + ","
- + faces[i].pose(FaceDetector.Face.EULER_Y) + ","
- + faces[i].pose(FaceDetector.Face.EULER_Z) + ")"
- + ", eyes midpoint = (" + eyescenter.x + "," + eyescenter.y +")");
- }
- } catch (Exception e) {
- Log.e(TAG, "setFace(): face " + i + ": " + e.toString());
- }
- }
- }
- mIV.setDisplayPoints(fpx, fpy, count * 2, 1);
- }
- privatevoid doLengthyCalc() {
- Thread t = new Thread() {
- Message m = new Message();
- publicvoid run() {
- try {
- setFace();
- m.what = TutorialOnFaceDetect.GUIUPDATE_SETFACE;
- TutorialOnFaceDetect.this.mHandler.sendMessage(m);
- } catch (Exception e) {
- Log.e(TAG, "doLengthyCalc(): " + e.toString());
- }
- }
- };
- t.start();
- }
- }
圖3:定位眼睛中心位置
色彩 vs. 灰度
通常來講,人臉檢測成功取決於搜尋人臉高對比度區域,實際效果來看色彩和灰度的差距不會太遠。不過很多學者仍在致力於證明色彩比灰度更靠譜。經過在對示例圖片的驗證,發現Android APIs返回的結果非常接近,似乎APIs意圖忽略掉不同顏色通道的因素。請看圖4(BTW,獨自一人在陰暗環境下請謹慎觀看):
圖4:灰度人臉檢測看起來會稍微有點恐怖
總結
介紹了簡單的Android人臉檢測APIs,並通過例項進行了演示。以上的軟體包均可在官網上下載,方便大家將其import到Eclipse中。最後提供一些有益的忠告:
- 很多應用對人臉檢測其實都有著潛在的重要需求,例如去紅眼、計算人頭數、自動對焦人臉、新增人臉特效等等。
- 這個世界上存在有非常多的人臉資料庫,有意者請點選此處。
- 在實時的人臉檢測過程中,Android的表現的會有一點點差強人意。
相關文章
- canvas+face-api人臉實時檢測CanvasAPI
- Android人臉檢測介紹Android
- 人臉檢測工具face_recognition的安裝與應用
- APISpace的 人臉檢測API 它來啦~API
- 人臉檢測識別,人臉檢測,人臉識別,離線檢測,C#原始碼C#原始碼
- 用Azure上Cognitive Service的Face API識別人臉API
- 使用Python結合Face++ API識別人臉PythonAPI
- 人臉檢測 二
- [計算機視覺]人臉應用:人臉檢測、人臉對比、五官檢測、眨眼檢測、活體檢測、疲勞檢測計算機視覺
- 人臉活體檢測
- 前端人臉檢測指南前端
- 人臉檢測的harr檢測函式函式
- 人臉檢測(detection)與人臉校準(alignment)
- opencv視訊人臉檢測OpenCV
- OpenCV 人臉檢測自學(3)OpenCV
- 人臉活體檢測人臉識別:眨眼+張口
- 如何評價美顏api中人臉識別和人臉檢測的準確度?API
- 人臉檢測榜單WIDER FACE最新排名:創新奇智AInnoFace演算法奪冠IDEAI演算法
- 【人臉偽造檢測後門攻擊】Imperceptible Face Forgery Attack via Adversarial Semantic Mask
- iOS 人臉關鍵點檢測iOS
- FaceDetector 人臉檢測追蹤demo
- win10 下的YOLOv3 訓練 wider_face 資料集檢測人臉Win10YOLOIDE
- 人臉識別之人臉檢測的重要性
- IOS人臉識別開發入門教程--人臉檢測篇iOS
- 目前最強效能的人臉檢測演算法(Wider Face Dataset)演算法IDE
- Python人臉識別微笑檢測Python
- 視訊人臉檢測——OpenCV版(三)OpenCV
- 圖片人臉檢測——OpenCV版(二)OpenCV
- JavaScript人臉檢測的實現方法JavaScript
- [譯] 提取圖片中的文字、人臉或者條形碼 —— 形狀檢測APIAPI
- 40多個關於人臉檢測/識別的API、庫和軟體API
- 重磅!目前最強效能的人臉檢測演算法(Wider Face Dataset)演算法IDE
- 活體檢測API對接php語言方式-人臉靜態/動態活體檢測免費APIPHP
- 從零玩轉人臉識別之RGB人臉活體檢測
- OpenCv人臉檢測技術-(實現抖音特效-給人臉戴上墨鏡)OpenCV特效
- 3分鐘內實現人臉檢測
- 人臉識別檢測專案實戰
- 圖片人臉檢測——Dlib版(四)