Androidプログラマへの道 〜 Moonlight 明日香 〜 - 顔を検出する
画像(静止画)から顔を検出するには, ファイスディテクタ(FaceDetector)クラスを利用する.

顔の検出

  • src/MainActivity.java
    • BitmapFactory#decodeFileメソッドで, 画像ファイルを読み込む.
   注1) RGB565形式(16bit)で読み込む.
   注2) 画像の横サイズは偶数でないと, 顔検出がエラーとなる.
    • detectFaceメソッド
      • FaceDetectorのインスタンスを取得する.
      • FaceDetector#findFacesメソッドで, 顔検出を実行する.
      • 顔の情報を取得する.
メソッド備考
Face#confidence顔としての確信度0.0〜1.0の値
Face#eyesDistance目と目の間の距離
Face#getMidPoint顔の中央の座標
Face#poseXYZ軸に対する顔の傾き0.0しか返ってこない
package com.moonlight_aska.android.facedetect01;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PointF;
import android.media.FaceDetector;
import android.media.FaceDetector.Face;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.ImageView;

public class MainActivity extends Activity {
  private final int MAX_FACE_NUM = 3;
  private Face[] mFaces = new Face[MAX_FACE_NUM];
  private ImageView mView = null;
  private Bitmap mBmpRes = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 画像読み込み
    String path = Environment.getExternalStorageDirectory().getPath() + "/sample/photo.jpg";
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Config.RGB_565;
    Bitmap bmpOrg = BitmapFactory.decodeFile(path, options);
    mBmpRes = bmpOrg.copy(Config.RGB_565, true);
    if (bmpOrg != null) {
      Log.v("FaceDetector", "Size width =" + bmpOrg.getWidth() + ", height =" + bmpOrg.getHeight());
      // 顔検出
      detectFace(bmpOrg);
      // 検出結果表示
      mView = (ImageView)findViewById(R.id.imgview);
      mView.setImageBitmap(mBmpRes);
    }
  }

  private void detectFace(Bitmap img) {
    FaceDetector detector = new FaceDetector(img.getWidth(), img.getHeight(), MAX_FACE_NUM);
    int num = detector.findFaces(img, mFaces);
    if (num == 0) {
      Log.v("FaceDetector", "not found!");
    }
    else {
      Log.v("FaceDetector", num + " faces");
    }
    for(int i=0; i<num; i++) {
      PointF mid = new PointF();
      mFaces[i].getMidPoint(mid);
      Log.v("FaceDetector", "confidence = " + mFaces[i].confidence());
      Log.v("FaceDetector", "eyes distance = " + mFaces[i].eyesDistance());
      Log.v("FaceDetector", "mid point = (" + mid.x + "," + mid.y + ")");
      Log.v("FaceDetector", "pose = (" + mFaces[i].pose(Face.EULER_X) +
          "," + mFaces[i].pose(Face.EULER_Y) +
          "," + mFaces[i].pose(Face.EULER_Z) + ")" );
      setMark(mFaces[i]);
    }
  }

  private void setMark(Face face) {
    Canvas canvas = new Canvas(mBmpRes);
    Paint paint = new Paint();
    paint.setColor(Color.RED);
    paint.setStyle(Style.STROKE);
    paint.setStrokeWidth(5);

    PointF mid = new PointF();
    face.getMidPoint(mid);
    canvas.drawCircle(mid.x, mid.y, face.eyesDistance(), paint);
  }
}
  • 動作例
Nexus 7 / Android 4.4.4

(出典:瀬間詠里花オフィシャルブログより)