ENGINEER BLOG

ENGINEER BLOG

CameraXとML Kitで顔検出してみる

こんにちは、イノベーション本部の朝日です。

今回は、Androidの新しいカメラAPI CameraXML Kitを使って顔検出をするアプリを作ってみたいと思います。

直前まで、ML Kit for Firebaseで作っていたのですが、ML Kitのマイグレーションガイドを読んでいたら、

  • オンデバイスのAPIはML Kit
  • クラウドベースのAPIはFirebase Machine Learning

というように分かれて、オンデバイスのML Kit for Firebaseは今後非推奨になるという記載があったので、急遽ML Kitベースに切り替えました。

環境

  • Android Studio 4.0
  • CameraX 1.0.0-beta03
  • ML Kit 16.0.0

を使用しています。 CameraX、ML Kit共にベータリリースなので内容は変わる可能性があります。

CameraXアプリの作成

CameraXの部分は、スタートガイドがわかりやすいので、そのまま使うことで省略します。

Face Detection (ML Kit)の組み込み

先ほど作成した、CameraX Appの、Image Analysis部分をML KitのFace Detectionに置き換えてみたいと思います。

ドキュメントを参考に実装していきます。

build.gradleの変更

app/build.gradleのdependenciesに下記の記述を追加します。

//app/build.gradle
    dependencies {
      // Use this dependency to bundle the model with your app
      implementation 'com.google.mlkit:face-detection:16.0.0'
    }   

Analyzerクラスの作成

CameraXのスタートガイドで作成したLuminosityAnalyzerの要領で、MainActivity.ktにFaceAnalyzerクラスを追加します。

//MainActivity.kt
private class FaceAnalyzer(private var listener: (Int) -> Unit) : ImageAnalysis.Analyzer {
    private val detector = FaceDetection.getClient()

    @ExperimentalGetImage
    override fun analyze(imageProxy: ImageProxy) {

        val mediaImage = imageProxy.image ?: return
        val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)

        detector.process(image)
            .addOnSuccessListener { faces ->
                listener(faces.size)
            }
            .addOnFailureListener { e ->
                Log.e("FaceAnalyzer", "Face detection failure.", e)
            }
            .addOnCompleteListener {
                imageProxy.close()
            }
    }
}

使用するAnalyzerの変更

CameraX app作成中に追加した、startCamera内の

//MainActivity.kt
            imageAnalyzer = ImageAnalysis.Builder()
                    .build()
                    .also {
                        it.setAnalyzer(cameraExecutor, LuminosityAnalyzer { luma ->
                            Log.d(TAG, "Average luminosity: $luma")
                        })
                    }

の部分をFaceAnalyzerを使うように変更します。

ついでに、ログに出力するだけだとつまらないので、顔の検出/非検出でTAKE PHOTOボタンの表示/非表示を切り替えるように変更してみます。

//MainActivity.kt
            imageAnalyzer = ImageAnalysis.Builder()
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor, FaceAnalyzer {faces ->
                        Log.d(TAG, "Face detected: $faces")
                        camera_capture_button.setEnabled(faces > 0)
                    })
                }

以上で完成です!

img1

さいごに

CameraXを使うことで、カメラを活用したアプリが簡単に作成できることがわかりました。

Image Analysis部分をML Kitの他の機能やFirebase Machine Learningに置き換えることで色々と応用ができそうですね。