コンソールへ移動

ML Kit を使用して顔を検出する(Android)

ML Kit を使用すると、端末モデルまたはクラウドモデルで画像や動画内の顔を検出できます。それぞれのアプローチの利点については、概要をご覧ください。

準備

  1. Firebase プロジェクトを設定します。
    1. Firebase プロジェクトをまだ用意していない場合は、Firebase コンソールで Firebase プロジェクトを作成します。モバイルアプリに関連付けられた既存の Google プロジェクトがある場合は、[Google プロジェクトをインポート] をクリックします。それ以外の場合は、[プロジェクトを追加] をクリックします。
    2. [Android アプリに Firebase を追加] をクリックし、設定手順に沿って操作します。既存の Google プロジェクトをインポートする場合、このステップは自動的に行われることがあります。その場合は、構成ファイルをダウンロードするだけでかまいません。
    3. プロンプトが表示されたら、アプリのパッケージ名を入力します。必ずアプリで使用しているパッケージ名を入力してください。パッケージ名を設定できるのは、アプリを Firebase プロジェクトに追加するときだけです。
    4. google-services.json ファイルをダウンロードします。構成ファイルはいつでも再ダウンロードできます。
    5. このファイルをプロジェクトのモジュール フォルダ(通常は app/)にコピーしていない場合は、コピーします。
  2. EAP の連絡先から受け取った SDK を抽出します。
    unzip -d $SDK_DIR 3p_sdk.m2repo.zip
    
  3. SDK および Google サービス プラグインの抽出先となるディレクトリを、プロジェクト レベルの build.gradle に追加します。
    buildscript {
      // ...
      dependencies {
          // ...
          classpath 'com.google.gms:google-services:3.2.0' // google-services plugin
      }
    }
    
    allprojects {
      repositories {
        // Add this
        maven {
          url "$SDK_DIR"
        }
        // This should already be here
        jcenter()
    
        ...
      }
    }
    
  4. 次に、ML Kit の依存関係を含めて、アプリレベルの build.gradle ファイルに apply plugin 行を追加します。

    dependencies {
      // ...
      compile 'com.google.firebase:firebase-core:12.8.0-SNAPSHOT'
      compile 'com.google.firebase:firebase-ml-vision:12.8.0-SNAPSHOT'
    }
    
    // ADD THIS AT THE BOTTOM OF THE FILE
    apply plugin: 'com.google.gms.google-services'
    

これで、端末モデルまたはクラウドベース モデルを使用して顔を検出する準備ができました。

端末上での顔検出

顔検出器を設定する

画像に顔検出を適用する前に顔検出器のデフォルト設定のいずれかを変更する場合は、FirebaseVisionFaceDetectorOptions オブジェクトを使用して設定を指定します。次の設定を変更できます。

設定
検出モード FAST_MODE(デフォルト)| ACCURATE_MODE

顔を検出する際に速度を優先するか精度を優先するか。

ランドマークを検出する NO_LANDMARKS(デフォルト)| ALL_LANDMARKS

顔の「ランドマーク」(目、耳、鼻、頬、口)を識別するかどうか。

顔を分類する NO_CLASSIFICATIONS(デフォルト)| ALL_CLASSIFICATIONS

顔を「ほほ笑んでいる」や「目を開けている」などのカテゴリに分類するかどうか。

顔の最小サイズ float(デフォルト: 0.1f

画像を基準とした、検出する顔の最小サイズ。

顔トラッキングを有効にする false(デフォルト)| true

複数の画像間で顔をトラッキングするために使用できる ID を顔に割り当てるかどうか。

たとえば、すべてのデフォルト設定を変更するには、次の例のように FirebaseVisionFaceDetectorOptions オブジェクトをビルドします。

FirebaseVisionFaceDetectorOptions options =
    new FirebaseVisionFaceDetectorOptions.Builder()
        .setModeType(FirebaseVisionFaceDetectorOptions.ACCURATE_MODE)
        .setLandmarkType(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
        .setClassificationType(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
        .setMinFaceSize(0.2f)
        .setTrackingEnabled(true)
        .build();

顔検出器を実行する

画像内の顔を認識するには、画像を ByteBuffer オブジェクトとして FirebaseVisionFaceDetectordetectInBuffer メソッドに渡すか、画像を android.graphics.Bitmap オブジェクトとして detectInImage メソッドに渡します。

  1. FirebaseVisionFaceDetector のインスタンスを取得します。

    FirebaseVisionFaceDetector detector = FirebaseVision.getInstance()
        .getVisionFaceDetector(options);
    
  2. 画像のメタデータを含む FirebaseVisionImageMetadata オブジェクトを作成します。

    画像を ByteBuffer として渡す場合は、画像の高さ、幅、カラー エンコード形式、および向きを指定する必要があります。

    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
        .setWidth(1280)
        .setHeight(720)
        .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
        .setRotation(FirebaseVisionImageMetadata.ROTATION_0)
        .build();
    

    画像を Bitmap として渡す場合は、画像の向きを指定するだけで済みます。

    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
        .setRotation(FirebaseVisionImageMetadata.ROTATION_0)
        .build();
    
  3. 最後に、画像を detectInBuffer または detectInImage メソッドに渡します。

    Task<SparseArray<FirebaseVisionFace>> result =
        detector.detectInImage(image, metadata)  // or detectInBuffer(buffer, metadata)
        .addOnSuccessListener(
            this,
            new OnSuccessListener<SparseArray<FirebaseVisionFace>>() {
              @Override
              public void onSuccess(SparseArray<FirebaseVisionFace> faces) {
                // Task completed successfully
                // ...
              }
            })
        .addOnFailureListener(
            this,
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Task failed with an exception
                // ...
              }
            });
    

検出された顔に関する情報を取得する

顔認識オペレーションが成功すると、FirebaseVisionFace オブジェクトの配列が成功リスナーに渡されます。各 FirebaseVisionFace オブジェクトは画像内で検出された顔を表します。顔ごとに、入力画像の境界座標と、検出するように顔検出器に設定した他の情報を取得できます。次に例を示します。

for(int i = 0; i < faces.size(); i++) {
  FirebaseVisionFace face = faces.valueAt(i);

  Rect bounds = face.getBoundingBox();
  if (face.hasHeadEulerAngleY()) {
    float rotY = face.getHeadEulerAngleY();  // Head is rotated to the right rotY degrees
  }
  if (face.hasHeadEulerAngleZ()) {
    float rotZ = face.getHeadEulerAngleZ();  // Head is rotated upward rotZ degrees
  }

  // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
  // nose available):
  if (face.hasLeftEarPosition()) {
    PointF leftEarPos = face.getLeftEarPosition();
  }
  if (face.hasNoseBasePosition()) {
    PointF nosePos = face.getNoseBasePosition();
  }

  // If classification was enabled:
  if (face.hasSmilingProbability()) {
    float smileProb = face.getSmilingProbability();
  }
  if (face.hasRightEyeOpenProbability()) {
    float rightEyeOpenProb = face.getRightEyeOpenProbability();
  }

  // If face tracking was enabled:
  if (face.hasTrackingId()) {
    int id = face.getTrackingId();
  }
}

クラウドでの顔検出

顔検出器を設定する

デフォルトでは、Cloud 検出ツールは STABLE バージョンのモデルを使用して、最大 10 件の結果を返します。これらの設定のいずれかを変更する必要がある場合は、FirebaseVisionCloudDetectorOptions オブジェクトを使用して指定します。

たとえば、デフォルト設定を両方とも変更するには、次の例のように FirebaseVisionCloudDetectorOptions オブジェクトをビルドします。

FirebaseVisionCloudDetectorOptions options =
    new FirebaseVisionCloudDetectorOptions.Builder()
        .setModelType(FirebaseVisionCloudDetectorOptions.LATEST_MODEL)
        .setMaxResults(15)
        .build();

デフォルト設定を使用するには、次の手順で FirebaseVisionCloudDetectorOptions.DEFAULT を使用します。

顔検出器を実行する

画像内の顔を認識するには、画像を ByteBuffer オブジェクトとして FirebaseVisionCloudFaceDetectordetectInBuffer メソッドに渡すか、画像を android.graphics.Bitmap オブジェクトとして detectInImage メソッドに渡します。

  1. FirebaseVisionCloudFaceDetector のインスタンスを取得します。

    FirebaseVisionCloudFaceDetector detector = FirebaseMachineLearning.getInstance()
        .getVisionFaceDetector(options);
    
  2. 画像のメタデータを含む FirebaseVisionImageMetadata オブジェクトを作成します。

    画像を ByteBuffer として渡す場合は、画像の高さ、幅、カラー エンコード形式、および向きを指定する必要があります。

    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
        .setWidth(1280)
        .setHeight(720)
        .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
        .setRotation(FirebaseVisionImageMetadata.ROTATION_0)
        .build();
    

    画像を Bitmap として渡す場合は、画像の向きを指定するだけで済みます。

    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
        .setRotation(FirebaseVisionImageMetadata.ROTATION_0)
        .build();
    
  3. 最後に、画像を detectInBuffer または detectInImage メソッドに渡します。

    Task<SparseArray<FirebaseVisionCloudFace>> result =
        detector.detectInImage(image, metadata)  // or detectInBuffer(buffer, metadata)
        .addOnSuccessListener(
            this,
            new OnSuccessListener<SparseArray<FirebaseVisionCloudFace>>() {
              @Override
              public void onSuccess(SparseArray<FirebaseVisionCloudFace> faces) {
                // Task completed successfully
                // ...
              }
            })
        .addOnFailureListener(
            this,
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Task failed with an exception
                // ...
              }
            });
    

検出された顔に関する情報を取得する

顔認識オペレーションが成功すると、FirebaseVisionCloudFace オブジェクトの配列が成功リスナーに渡されます。各 FirebaseVisionCloudFace オブジェクトは画像内で検出された顔を表します。顔ごとに、入力画像の境界座標、カメラに対する回転、認識された顔のパーツの位置を取得できます。次に例を示します。

for(int i = 0; i < faces.size(); i++) {
  FirebaseVisionFace face = faces.valueAt(i);

  // Face position and rotation
  Rect bounds = face.getBoundingBox();
  float rotY = face.getHeadEulerAngleY();  // Head is rotated to the right rotY degrees
  float rotZ = face.getHeadEulerAngleZ();  // Head is rotated upward rotZ degrees

  // Facial features
  PointF leftEarPos = face.getLeftEarPosition();
  PointF nosePos = face.getNoseBasePosition();

  // Face classification
  float sorrowProb = face.getSorrowProbability();
  float rightEyeOpenProb = face.getRightEyeOpenProbability();
}