FaceDetectorのオプションまとめ

2018/04/16

AndroidではMobile Vision APIの一つとして顔検出のAPIが提供されています。

Mobile Vision APIはGoogle Play servicesの一部として提供されるので

dependencies {
  compile 'com.google.android.gms:play-services-vision:10.2.0'
}

みたいにして使います。

で、何も考えずに使ったら思ったほどの精度が出なかったので、設定できるオプションを一通り確認してみました。

FaceDetectorのオプション

setClassificationType(int classificationType)

smiling(笑っているかどうか)やeyes open(目を開いているかどうか)などの追加情報を取得するかどうか。

  • NO_CLASSIFICATIONS: 追加情報を取得しない
  • ALL_CLASSIFICATIONS: 追加情報を取得する

setLandmarkType(int landmarkType)

ランドマーク(目や鼻などのパーツ)を検知するかどうか。 検知すると追加の処理時間がかかる代わりに姿勢推定の精度が上がります。(つまり、顔認識の精度が上がるっぽい)

  • NO_LANDMARKS: ランドマークを検知しない
  • ALL_LANDMARKS: ランドマークを検知する

setMinFaceSize(float proportionalMinFaceSize)

検出する顔の最小値を設定します。数値は「画像の幅に対して最小となる顔の幅がどのくらいか」を表します。 例えば0.1を設定すると検出できる顔は画像の幅の10%より大きいもののみとなります(それより小さいと顔として認識しなくなります)

ただ、この数値は厳密な閾値ではなく、10%より少しだけ小さい顔も認識するとのこと。

この処理は精度とパフォーマンスのトレードオフになります。 値を小さくするとより小さな顔を検知できる分、処理に時間がかかります。

既定値はprominentFaceOnlyがfalseの場合は0.1、prominentFaceOnlyがtrueの場合は0.35です。

setMode(int mode)

顔認証の処理速度と検出精度のどちらを優先するか。両者はトレードオフの関係にあります。

  • FAST_MODE: 処理速度を優先する
  • ACCURATE_MODE: 検出精度を優先する

setProminentFaceOnly(boolean prominentFaceOnly)

検知の対象を一番目立つ顔のみとするかどうか。

  • true: 一番目立つ顔のみを認識する
  • false: 認識した全ての顔情報を取得する

setTrackingEnabled(boolean trackingEnabled)

検知をトラッキングし続けるか。

  • true: 連続で認識を続ける(カメラや動画をインプットにしたリアルタイム検出を行う場合)
  • false: 認識は一度だけ(静止画の場合)

採用した組み合わせ

今回の用途は「速度より精度重視、メインの顔だけを検知したい」というものだったので以下のようにしてみました。

FaceDetector detector = new FaceDetector.Builder(context)
    .setClassificationType(FaceDetector.NO_CLASSIFICATIONS)
    .setLandmarkType(FaceDetector.ALL_LANDMARKS)
    .setMinFaceSize(0.05f)
    .setMode(FaceDetector.ACCURATE_MODE)
    .setProminentFaceOnly(true)
    .setTrackingEnabled(false)
    .build();

このオプション構成にすると検知精度が実感できるレベルで向上。速度低下も許容範囲でした。 ただ、逆に検知できなくなった写真もあって一筋縄ではいかないなあ、と。

最適の結果が欲しい場合は、実際に使う(もしくは使われそうな)写真を集めて、実際の結果を見ながら調整する必要がありそうです。 今回はそこまで頑張らないのでここまででいったん打ち止め。

参考URL




関連(するかもしれない)記事


おススメ