1. 始める前に
Google レンズのデモを見ましたか?このデモでは、スマートフォンのカメラを対象物に向け、オンラインで購入できる場所を確認できます。 同じ機能をアプリに追加する方法については、この Codelab をご覧ください。商品画像検索機能をモバイルアプリに組み込む方法を説明する学習プログラムの一部です。
この Codelab では、商品画像検索機能を構築する最初の手順である、画像内のオブジェクトを検出して、検索したいオブジェクトをユーザーが選択できるようにする方法を学びます。ML Kit オブジェクトの検出とトラッキングを使用して、この機能を構築します。
Vision API Product Search を使用した商品検索バックエンドの作成方法など、残りの手順については、学習パスウェイをご覧ください。
作成するアプリの概要
|
学習内容
- ML Kit SDK を Android アプリに統合する方法
- ML Kit オブジェクトの検出とトラッキング API
必要なもの
- 最新バージョンの Android Studio(v4.1.2 以降)
- Android Studio エミュレータまたは物理 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 にアプリをインポートする
まず、スターター アプリを 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 ツールバーの [Run]()をクリックします。
アプリを実行して実行する
アプリが Android デバイスで起動します。このライブラリにはボイラープレート コードが含まれています。このコードを使用して、写真撮影やプリセット画像の選択を行い、この Codelab で作成するオブジェクト検出およびトラッキング パイプラインにフィードできます。コードを記述する前に、アプリの詳細を確認します。
まず、画面下部にボタン()が表示されます。
- デバイスまたはエミュレータに統合されたカメラアプリを起動する
- カメラアプリで写真を撮影する
- キャプチャした画像をスターター アプリで受信する
- 画像を表示する
[写真を撮影] ボタンを試します。画面の指示に沿って写真を撮影し、写真を承認して、スターター アプリ内に表示されます。
次に、3 つのプリセット画像から選択できます。Android Emulator で実行している場合は、後でこれらの画像を使用してオブジェクト検出コードをテストできます。
- 3 つのプリセット画像から画像を選択します。
- 画像が大きな画像で表示されることを確認します。
5. デバイス上のオブジェクト検出を追加する
このステップでは、スターター アプリに画像内のオブジェクトを検出する機能を追加します。前のステップで説明したように、スターター アプリには、デバイスのカメラアプリで写真を撮るためのボイラープレート コードが含まれています。アプリには、Android Emulator で Codelab を実行している場合に、オブジェクト検出を試行できる 3 つのプリセット画像があります。
プリセット画像から、またはカメラアプリで写真を撮影して画像を選択すると、ボイラープレート コードがその画像を Bitmap
インスタンスにデコードし、画面に表示します。その際、runObjectDetection
メソッドを使用する。
このステップでは、runObjectDetection
メソッドにオブジェクトを追加してオブジェクト検出を行います。
画像上のオンデバイス オブジェクト検出を設定して実行する
ML Kit ODT を設定する 3 つの API の 3 つの簡単なステップ
- 画像の準備:
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 はビルダー設計パターンに従います。構成をビルダーに渡し、そこからビルダーを取得します。構成方法は 3 つあります(太字の項目は Codelab で使用します)。
- 検出モード(単一の画像 またはストリーミング)の手続き
- 検出モード(単一または 複数 オブジェクト検出)の手続き
- 分類モード(オン またはオフ)
この Codelab は、1 つの画像に対して行います。複数のオブジェクトの検出と分類を行います。
// 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 のツールバーで [Run]()をクリックして、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))- 最初の検出項目が「ファッション アイテム」(90%)であることを確実に判断できます(ドレスです)。
技術的には、ML Kit のオブジェクト検出を動作させるために必要な作業はこれだけです。 これで完了です。
はい。UI 側では、まだ作業を開始していますが、より良い 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 のツールバーで [Run]()をクリックします。
アプリが読み込まれたら、カメラアイコン付きのボタンを押す、カメラを被写体に向ける、写真を撮影する、写真を撮影する(カメラアプリで)など、プリセットの画像を簡単にタップできます。検出結果が表示されます。もう一度ボタンを押すか、別の画像を選択して数回繰り返すと、最新の ML Kit の ODT を体験できます。
7. 完了
ML Kit を使用して、アプリにオブジェクト検出機能を追加しました。
- 3 つの API で 3 つのステップ
- 入力画像の作成
- 検出項目を作成
- 検出機能に画像を送信
セットアップは完了です。
学習した内容
- ML Kit のオブジェクト検出とトラッキングを Android アプリに追加する方法
- ML Kit でデバイスのオブジェクト検出とトラッキングを使用して画像内のオブジェクトを検出する方法
次の手順
- 検出されたオブジェクトを商品検索バックエンドに送信し、検索結果を表示する方法については、こちらの Codelab をお試しください。
- ML Kit の ODT でさらに多くの画像とライブ動画を使用して、検出と分類の精度とパフォーマンスをご確認ください
- オブジェクト検出をさらに行う学習パスウェイで、カスタムモデルのトレーニング方法を学習する。
- オブジェクト検出のライブカメラと静的画像のマテリアル デザインに関する推奨事項を確認する
- ML Kit の ODT を独自の Android アプリに適用