1. 始める前に
Google レンズのデモをご覧になったことはありますか。デモでは、スマートフォンのカメラを対象物に向けて、オンラインで購入できる場所を検索できます。同じ機能をアプリに追加する方法を知りたい場合は、この Codelab が最適です。モバイルアプリに商品画像検索機能を組み込む方法を学習する学習プログラムの一環です。
この Codelab では、商品画像検索機能を構築するための最初のステップ(画像内のオブジェクトを検出して、検索するオブジェクトをユーザーが選択できるようにする方法)を学びます。この機能を作成するには、ML Kit オブジェクトの検出とトラッキングを使用します。
Vision API Product Search を使用して商品検索バックエンドを構築する方法など、残りのステップについては、学習プログラムをご覧ください。
作成するアプリの概要
|
学習内容
- ML Kit SDK を Android アプリに統合する方法
- ML Kit のオブジェクト検出とトラッキング API
必要なもの
- Android Studio の最新バージョン(v4.1.2 以降)
- Android Studio Emulator または Android の実機
- サンプルコード
- Kotlin での Android 開発に関する基本的な知識
この Codelab は ML Kit に重点を置いています。その他のコンセプトとコードブロックは学習していないため、そのままコピーして貼り付けられるようにしています。
2. セットアップする
コードをダウンロードする
次のリンクをクリックして、この Codelab のコードをすべてダウンロードします。
ダウンロードした zip ファイルを解凍すると、これにより、必要なリソースがすべて含まれたルートフォルダ(odml-pathways-main
)が展開されます。この Codelab に必要なのは product-search/codelab1/android
サブディレクトリにあるソースのみです。
mlkit-android リポジトリの object-detection サブディレクトリには、次の 2 つのディレクトリがあります。
- starter - この Codelab で作成する開始コード。
- final - 完成したサンプルアプリの完全なコード。
3. ML Kit の Object Detection and Tracking API をプロジェクトに追加する
Android Studio にアプリをインポートする
まず、starter アプリを Android Studio にインポートします。
Android Studio に移動し、[Import Project](Gradle、Eclipse ADT など)を選択して、先ほどダウンロードしたソースコードの starter フォルダを選択します。
ML Kit オブジェクトの検出とトラッキングの依存関係を追加する
ML Kit の依存関係を使用すると、ML Kit ODT SDK をアプリに統合できます。
プロジェクトの app/build.gradle
ファイルに移動し、依存関係がすでに存在することを確認します。
build.gradle
dependencies {
// ...
implementation 'com.google.mlkit:object-detection:16.2.4'
}
プロジェクトと Gradle ファイルを同期する
アプリですべての依存関係を使用できるようにするには、この時点でプロジェクトを Gradle ファイルと同期する必要があります。
Android Studio のツールバーで、[Sync Project with Gradle Files]()を選択します。
(このボタンが無効になっている場合は、リポジトリ全体ではなく、starter/app/build.gradle のみをインポートしてください)。
4. スターター アプリを実行する
これで、プロジェクトを Android Studio にインポートし、ML Kit のオブジェクト検出とトラッキングの依存関係を追加できました。これで、アプリを初めて実行する準備ができました。
Android デバイスを USB 経由でホストに接続するか、Android Studio エミュレータを起動して、Android Studio ツールバーの実行アイコン()をクリックします。
アプリを実行して操作する
Android デバイスでアプリが起動するはずです。ボイラープレート コードを使用して、写真をキャプチャするか、プリセットの画像を選択し、この Codelab で作成するオブジェクト検出およびトラッキング パイプラインにフィードします。コードを記述する前に、アプリを少し操作してみましょう。
まず、下部にあるボタン()では、
- デバイス/エミュレータに組み込まれているカメラアプリを起動する
- カメラアプリで写真を撮影する
- スターター アプリでキャプチャした画像を受信する
- 画像を表示する
[写真を撮る] をお試しください] ボタンを離します。画面の指示に沿って写真を撮影し、写真を承認して、スターター アプリ内に表示されることを確認します。
次に、3 つのプリセット画像から選択できます。Android Emulator で実行している場合は、これらのイメージを後で使用してオブジェクト検出コードをテストできます。
- 3 つのプリセット画像から画像を選択します。
- 大きなビューに画像が表示されることを確認します。
5. デバイス上のオブジェクト検出を追加する
このステップでは、スターター アプリに画像内のオブジェクトを検出する機能を追加します。前のステップで確認したように、スターター アプリには、デバイス上のカメラアプリで写真を撮影するためのボイラープレート コードが含まれています。アプリには 3 つのプリセット画像もあり、Android Emulator で Codelab を実行する場合にオブジェクト検出を試せます。
プリセット画像から画像を選択するか、カメラアプリで写真を撮影すると、ボイラープレート コードがその画像を Bitmap
インスタンスにデコードして画面に表示し、画像に対して runObjectDetection
メソッドを呼び出します。
このステップでは、runObjectDetection
メソッドにコードを追加して、オブジェクト検出を行います。
デバイス上のオブジェクト検出を設定して画像に対して実行する
ML Kit ODT は、3 つの簡単なステップで 3 つの API を設定
- 画像を準備:
InputImage
- 検出オブジェクトの作成:
ObjectDetection.getClient(options)
- 上の 2 つのオブジェクトを接続します:
process(image)
これらはファイル MainActivity.kt
の関数 **runObjectDetection(bitmap: Bitmap)
**で実行します。
/**
* ML Kit Object Detection Function
*/
private fun runObjectDetection(bitmap: Bitmap) {
}
今のところ、この関数は空です。ML Kit ODT を統合する手順に進みましょう。途中で、必要なインポートを追加するよう求めるメッセージが Android Studio に表示されます。
com.google.mlkit.vision.common.InputImage
com.google.mlkit.vision.objects.ObjectDetection
com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions
ステップ 1: InputImage を作成する
ML Kit には、Bitmap
から InputImage
を作成するシンプルな API が用意されています。次に、InputImage
を ML Kit API にフィードします。
// Step 1: create ML Kit's InputImage object
val image = InputImage.fromBitmap(bitmap, 0)
runObjectDetection(bitmap:Bitmap)
の先頭に上記のコードを追加します。
ステップ 2: 検出機能インスタンスを作成する
ML Kit は Builder デザイン パターンに従い、構成をビルダーに渡して、その構成から検出器を取得します。構成するオプションは 3 つあります(太字の部分が Codelab で使用されています)。
- 検出機能モード(単一画像またはストリーム)
- 検出モード(単一または 複数 のオブジェクト検出)
- 分類モード(オンまたはオフ)
この Codelab は、単一画像(複数オブジェクト検出とそうしましょう。
// Step 2: acquire detector object
val options = ObjectDetectorOptions.Builder()
.setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE)
.enableMultipleObjects()
.enableClassification()
.build()
val objectDetector = ObjectDetection.getClient(options)
ステップ 3: 画像を検出項目にフィードする
オブジェクトの検出と分類は非同期処理です。
- 検出機能に画像を送信する(
process()
を使用) - この検出機能はとても役に立っています。
- コールバックを介して結果を報告します。
次のコードではこれを行います(fun runObjectDetection(bitmap:Bitmap)):
内の既存のコードにコピーして追加します)。
// Step 3: feed given image to detector and setup callback
objectDetector.process(image)
.addOnSuccessListener {
// Task completed successfully
debugPrint(it)
}
.addOnFailureListener {
// Task failed with an exception
Log.e(TAG, it.message.toString())
}
完了すると、検出機能によって以下が通知されます。
- 検出されたオブジェクトの合計数
- 検出された各オブジェクトは、
trackingId
: フレーム間のトラッキングに使用する整数(この Codelab では使用しません)boundingBox
: オブジェクトの境界ボックス- 検出されたオブジェクトのラベルの
labels:
リスト(分類が有効になっている場合のみ) index
(このラベルのインデックスを取得します)text
(「ファッション関連商品」、「食品」、「日用品」、「場所」、「植物」を含む、このラベルのテキストを取得します)confidence
(0.0 ~ 1.0 の浮動小数点数、1.0 の場合は 100%)
このコードでは debugPrint()
を使用して、検出された結果が Logcat に出力されていることにお気づきでしょうか。これを MainActivity
クラスに追加します。
private fun debugPrint(detectedObjects: List<DetectedObject>) {
detectedObjects.forEachIndexed { index, detectedObject ->
val box = detectedObject.boundingBox
Log.d(TAG, "Detected object: $index")
Log.d(TAG, " trackingId: ${detectedObject.trackingId}")
Log.d(TAG, " boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")
detectedObject.labels.forEach {
Log.d(TAG, " categories: ${it.text}")
Log.d(TAG, " confidence: ${it.confidence}")
}
}
}
これで、検出に画像を受け入れる準備が整いました。
Android Studio ツールバーの実行アイコン()をクリックして、Codelab を実行します。プリセットの画像を選択するか写真を撮って、IDE 内の logcat ウィンドウ()を確認します。次のように表示されます。
D/MLKit Object Detection: Detected object: 0
D/MLKit Object Detection: trackingId: null
D/MLKit Object Detection: boundingBox: (481, 2021) - (2426,3376)
D/MLKit Object Detection: categories: Fashion good
D/MLKit Object Detection: confidence: 0.90234375
D/MLKit Object Detection: Detected object: 1
D/MLKit Object Detection: trackingId: null
D/MLKit Object Detection: boundingBox: (2639, 2633) - (3058,3577)
D/MLKit Object Detection: Detected object: 2
D/MLKit Object Detection: trackingId: null
D/MLKit Object Detection: boundingBox: (3, 1816) - (615,2597)
D/MLKit Object Detection: categories: Home good
D/MLKit Object Detection: confidence: 0.75390625
これは検出器が以下の 3 つの物体を検出したことを意味します。
- カテゴリは「ファッション グッド」と「家庭用品」です。
- 2 番目のクラスは不明なクラスであるため、カテゴリは返されません。
trackingId
なし(単一画像検出モードであるため)boundingBox
の長方形内の位置(例: (481, 2021) – (2426, 3376))- 検出項目は、1 件目がファッション アイテム(90%)であるとかなり確信しています(「ドレス」)
技術的には、ML Kit オブジェクト検出を機能させるには、これだけで十分です。おつかれさまでした
UI 側では、まだ開始の段階にありますが、境界ボックスを描画するなど、UI で検出された結果を活用してエクスペリエンスを改善できます。次のステップは、検出結果を可視化することです。
6. 検出結果の後処理
これまでのステップでは、シンプルで迅速な検出結果を logcat に出力しました。
このセクションでは、画像内の結果を利用します。
- 画像上に境界ボックスを描画する
- 境界ボックス内にカテゴリ名と信頼度を描画する
可視化ユーティリティを理解する
Codelab には、検出結果を可視化するためのボイラープレート コードが用意されています。これらのユーティリティを利用して、可視化コードをシンプルにします。
class ImageClickableView
。これは、検出結果の可視化と操作に便利なユーティリティを提供する画像ビュークラスです。fun drawDetectionResults(results: List<DetectedObject>)
このメソッドでは、検出された各オブジェクトの中心に白い円が描画されます。fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit))
これは、ユーザーがタップしたオブジェクトのみを含む切り抜かれた画像を受け取るコールバックです。この切り抜かれた画像は、後の Codelab で画像検索バックエンドに送信して、視覚的に類似した結果を取得します。この Codelab では、まだこの方法を使用しません。
ML Kit の検出結果を表示する
可視化ユーティリティを使用して、ML Kit オブジェクトの検出結果を入力画像の上に表示します。
debugPrint()
を呼び出す場所に移動し、その下に次のコード スニペットを追加します。
runOnUiThread {
viewBinding.ivPreview.drawDetectionResults(it)
}
実行する
Android Studio ツールバーの実行アイコン()をクリックします。
アプリが読み込まれたら、カメラアイコン付きのボタンを押し、被写体にカメラを向けて写真を撮り、(カメラ アプリで)写真を受け入れます。プリセット画像を簡単にタップすることもできます。検出結果が表示されます。ボタンをもう一度押すか、別の画像を選択して数回繰り返して、最新の ML Kit ODT を試してみましょう。
7. 完了
ML Kit を使用してオブジェクト検出機能をアプリに追加しました。
- 3 つの API と 3 つのステップ
- 入力画像を作成
- 検出項目を作成
- 検出機能に画像を送信
これだけで運用を開始できます。
学習した内容
- ML Kit のオブジェクト検出とトラッキングを Android アプリに追加する方法
- ML Kit でデバイス上のオブジェクト検出とトラッキングを使用して画像内のオブジェクトを検出する方法
次のステップ
- 検出されたオブジェクトを商品検索バックエンドに送信して検索結果を表示する方法については、こちらの Codelab をお試しください。
- ML Kit ODT で、画像とライブ動画で検出と検出を体験分類精度とパフォーマンス
- カスタムモデルのトレーニング方法については、オブジェクト検出を使ってみるの学習プログラムをご覧ください。
- オブジェクト検出のライブカメラと静止画像に関するマテリアル デザインの推奨事項を確認する
- 独自の Android アプリに ML Kit ODT を適用する