ユニファ開発者ブログ

ユニファ株式会社プロダクトデベロップメント本部メンバーによるブログです。

ウルトラマンと夏の自由研究 前編

こんにちは、Androidエンジニアのあいばです。
今年の始めから息子がウルトラマンにはまり一緒に見始めたのですが、ウルトラマンの数が私の想像の5倍くらいいて驚きました。
最近は毎年新しいTVシリーズが出ていたり、シン・ウルトラマンが公開されたり、本格的に海外展開を始めたりでウルトラ界隈がかなり盛り上がっているようですね!

今回は夏なので、ウルトラマン x Firebase ML で遊んだ内容を自由研究風にまとめたいと思います!

タイトル

Ultra detection

ど素人でもカスタムモデルを作成して

オブジェクト検出できるのか?!

自由研究のきっかけ

  • 4歳息子の影響で自分もウルトラマンにはまる
  • 夜な夜なウルトラマンを鑑賞しているうちに何か作らなければいけない気分になる

やりたいこと

  • スマホのカメラでウルトラマンのソフビを撮影し、ウルトラマン達を検出する。
  • ウルトラマン、ゾフィー、ウルトラマンジャックを区別できたらうれしい。

使うもの

  • Android Studio Chipmunk | 2021.2.1 Patch 1
  • AutoML Vision Edge
  • Jetpack Compose
  • CameraX
  • 家にあるウルトラマンのソフビ

手順

始める前に
  • Firebase プロジェクトまたは Google Cloud プロジェクトを用意していない場合は、まずFirebase コンソールでプロジェクトを作成しましょう。
1.トレーニングデータを収集
  • ソフビの撮影
    • 画像は、JPEG、PNG、GIF、BMP、ICOのいずれかの形式
    • 各画像は30MB以下
    • 各ラベルの例を少なくとも10個、できれば100個以上含める
    • 各ラベルに複数の角度、解像度、背景を含める
2. モデルをトレーニングする
  • トレーニングするモデルのタイプ(今回はオブジェクト検出)を選択しデータセットを作成したら、収集したトレーニングデータをインポート
  • 認識したいオブジェクトの周囲に境界ボックスを描画
    • こんなんで良いのかしら?と思いながら地道にラベルと境界ボックスを設定しました。
      ラベルと境界ボックスの設定
  • オプションを選択しトレーニングを開始
    生成されたモデルのパフォーマンスを管理するトレーニング設定
  • トレーニングが完了したらモデルのパフォーマンスメトリクスを確認
    • ここでモデルに最適な信頼度のしきい値を決定できます。
      モデルの評価
3. モデルをダウンロードしアプリにバンドル
  • TensorFlow Liteタスクライブラリの依存関係を追加
  • ダウンロードしたモデルを assets フォルダにコピー
  • ObjectDetectorオブジェクトを作成
// Initialization
val options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud Console to determine an appropriate value.
    .build()
val objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options)

モデルはクラウドで実行するオンライン予測用にデプロイすることもできます。デプロイしたモデルは 1 時間ごとに使用されるマシンの数に応じて課金されるので、料金ガイドをしっかり確認しGCP料金のアラート機能も設定しておきましょう。 私はうっかり設定を間違えてウルトラショックな事態になりました。

4. 入力画像の用意
  • CameraX のImageAnalysis ユースケースを利用。
  • ImageAnalysis.Analyzer インターフェースを実装してアナライザを作成
  • アナライザから受け取った ImageProxy からTensorImageを作成
val imageAnalysis = ImageAnalysis.Builder()
    .setTargetResolution(Size(1280, 720))
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
    .build()
imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer { imageProxy ->
    val rotationDegrees = imageProxy.imageInfo.rotationDegrees
     imageProxy.image?.let { mediaImage ->
            val bitmap = mediaImage.toBitmap()
            val image = TensorImage.fromBitmap(bitmap)
            // insert your code here.
            ...
     }
    // after done, release the ImageProxy object
    imageProxy.close()
})
5.ObjectDetector を実行する
  • TensorImageオブジェクトをObjectDetectorのdetect()メソッドに渡す。
val results = objectDetector.detect(image)

デモ

  • 個性が強めのウルトラマンはそれなりに分類できていましたが、ウルトラマン、ゾフィー、ウルトラマンジャックを分類することはできませんでした。
    シャイニングウルトラマンゼロ
    ウルトラマンゼロ
    ゾフィー、ジャック、ウルトラマン

さいごに

結構お手軽に(データの用意はそれなりに大変でしたが)オブジェクト検出を実装できて楽しかったのですが、もっと精度改善できそうだよな… と気になっていたところ、社内の専門家からSlackでアドバイスをもらいました。

どういうことだろう…?と思っていたら、なるほど!既にブログにありました!
ということで後編でこちらに挑戦してみようと思います!

tech.unifa-e.com


ユニファで一緒に働く仲間を募集しています!

unifa-e.com

参考

https://cloud.google.com/vision/automl/object-detection/docs/prepare
https://firebase.google.com/docs/ml/android/detect-objects-with-automl
https://developer.android.com/training/camerax/analyze?hl=ja