Android 向け画像埋め込みガイド

MediaPipe Image Embedder タスクでは、画像データを数値表現に変換 モデルの比較など、ML 関連の画像処理タスクを 類似度を検出できます。ここでは、 Android アプリでの画像埋め込み。

機能、モデル、構成オプションの詳細については、 概要をご覧ください。

サンプルコード

MediaPipe Tasks のサンプルコードは、画像エンベディングの単純な実装です。 アプリこの例では、物理的な Android デバイスのカメラを使用して、 継続的に画像を埋め込んだり、保存された画像ファイルに対してエンべディングを実行 確認できます。

独自の Android アプリの出発点としてアプリを使用することも、アプリ自体に言及することもできます。 変更する際の注意点があります。画像埋め込みコードのサンプルコードは GitHub

コードをダウンロードする

次の手順では、サンプルのローカルコピーを作成する方法を示します。 git コマンドライン ツールを使用してコードを実行します。

<ph type="x-smartling-placeholder">

サンプルコードをダウンロードするには:

  1. 次のコマンドを使用して Git リポジトリのクローンを作成します。
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. 必要に応じて、スパース チェックアウトを使用するように Git インスタンスを構成し、 Image Embedder サンプルアプリのファイルのみが含まれるためです。
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_embedder/android
    

サンプルコードのローカル バージョンを作成したら、プロジェクトをインポートできます。 アプリを実行します。手順については、セットアップ ガイド: Android

主要コンポーネント

次のファイルには、この画像埋め込みツールの例に不可欠なコードが含まれています。 アプリケーション:

  • ImageEmbedderHelper.kt: 画像埋め込みを初期化し、モデルとデリゲートを処理します。 選択します。
  • MainActivity.kt: アプリを実装し、ユーザー インターフェース コンポーネントを作成します。

セットアップ

このセクションでは、開発環境をセットアップする主な手順と Image Embedder を使用する例を示します。設定に関する一般的な情報については、 MediaPipe タスクを使用するための開発環境(プラットフォーム バージョンを含む) 詳しくは、設定ガイド Android

<ph type="x-smartling-placeholder">

依存関係

画像埋め込みツールは com.google.mediapipe:tasks-vision ライブラリを使用します。こちらの build.gradle ファイルに依存関係を追加します。 次のコードを使用して、必要な依存関係をインポートします。

dependencies {
    ...
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

モデル

MediaPipe Image Embedder タスクには、この変換と互換性のあるトレーニング済みモデルが必要 タスクを実行します。画像エンベディングで使用可能なトレーニング済みモデルについて詳しくは、以下をご覧ください。 タスクの概要のモデル セクションをご覧ください。

モデルを選択してダウンロードし、プロジェクト ディレクトリに保存します。

<dev-project-root>/src/main/assets

ModelAssetPath パラメータ内でモデルのパスを指定します。 setupImageEmbedder() 関数の ImageEmbedderHelper.kt ファイル:

BaseOptions.Builder.setModelAssetPath() メソッドを使用してパスを指定する 使用されます。このメソッドは、次のコードサンプルで参照されています。 。

タスクを作成する

タスクを作成するには、createFromOptions 関数を使用します。「 createFromOptions 関数は、埋め込み機能を設定する構成オプションを受け入れます。 。構成オプションの詳細については、構成 概要をご覧ください。

画像埋め込みタスクは、静止画像、動画ファイル、 ストリーミング動画にも対応しています対応する実行モードを指定する必要があります。 入力データ型を指定します。対応するタブを選択してください タスクの作成方法と推論の実行方法を確認できます。

画像

ImageEmbedderOptions options =
  ImageEmbedderOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setQuantize(true)
    .setRunningMode(RunningMode.IMAGE)
    .build();
imageEmbedder = ImageEmbedder.createFromOptions(context, options);
    

動画

ImageEmbedderOptions options =
  ImageEmbedderOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setQuantize(true)
    .setRunningMode(RunningMode.VIDEO)
    .build();
imageEmbedder = ImageEmbedder.createFromOptions(context, options);
    

ライブ配信

ImageEmbedderOptions options =
  ImageEmbedderOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setQuantize(true)
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setResultListener((result, inputImage) -> {
         // Process the embedding result here.
    })
    .build();
imageEmbedder = ImageEmbedder.createFromOptions(context, options);
    

コードの実装例では、ユーザーが処理を切り替えることができます。 あります。このアプローチでは、タスク作成コードがより複雑になるため、 選択することもできますこのコードは setupImageEmbedder() 関数を ImageEmbedderHelper.kt 表示されます。

構成オプション

このタスクには、Android アプリ用に次の構成オプションがあります。

オプション名 説明 値の範囲 デフォルト値
runningMode タスクの実行モードを設定します。3 つの モード:

IMAGE: 単一画像入力のモード。

VIDEO: 動画のデコードされたフレームのモード。

LIVE_STREAM: 入力のライブ配信のモード カメラからのデータなどです。このモードでは、resultListener は 結果を受け取るリスナーを設定するために呼び出されます。 使用できます。
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
l2_normalize 返された特徴ベクトルを L2 ノルムで正規化するかどうか。 このオプションは、モデルにネイティブ L2_NORMALIZATION TFLite 演算ほとんどの場合はこれがすでに行われており、 そのため、L2 正規化は TFLite 推論によって実現され、 指定します。 Boolean False
quantize 返されたエンベディングを、次を使用してバイトに量子化するかどうか スカラー量子化です。エンベディングは暗黙的にユニットノルムであると想定され、 したがって、どのディメンションも [-1.0, 1.0] の範囲の値を持つことが保証されます。使用 そうでない場合は l2_normalize オプションを使用します。 Boolean False
resultListener エンベディング結果を受け取る結果リスナーを設定します。 非同期で行われます。 モードです。実行モードが LIVE_STREAM に設定されている場合にのみ使用できます なし 未設定
errorListener オプションのエラーリスナーを設定します。 なし 未設定

データの準備

画像埋め込みは、画像、動画ファイル、ライブ ストリーム動画に対応しています。タスク サイズ変更、回転、値を含むデータ入力の前処理を処理 説明します。

入力画像またはフレームを com.google.mediapipe.framework.image.MPImage オブジェクトを使用してから Image Embedder タスク。

画像

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load an image on the user’s device as a Bitmap object using BitmapFactory.

// Convert an Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(bitmap).build();
    

動画

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load a video file on the user's device using MediaMetadataRetriever

// From the video’s metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them
// to calculate the timestamp of each frame later.

// Loop through the video and load each frame as a Bitmap object.

// Convert the Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

ライブ配信

import com.google.mediapipe.framework.image.MediaImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Create a CameraX’s ImageAnalysis to continuously receive frames
// from the device’s camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

// For each Android’s ImageProxy object received from the ImageAnalysis,
// extract the encapsulated Android’s Image object and convert it to
// a MediaPipe’s Image object.
android.media.Image mediaImage = imageProxy.getImage()
Image mpImage = new MediaImageBuilder(mediaImage).build();
    

このサンプルコードでは、データの準備を ImageEmbedderHelper.kt 表示されます。

タスクを実行する

実行モードに対応する embed 関数を呼び出して、トリガーできます。 説明します。Image Embedder API は、入力に対してエンベディング ベクトルを返す 追加します。

画像

ImageEmbedderResult embedderResult = imageEmbedder.embed(image);
    

動画

// Calculate the timestamp in milliseconds of the current frame.
long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count;

// Run inference on the frame.
ImageEmbedderResult embedderResult =
    imageEmbedder.embedForVideo(image, frameTimestampMs);
    

ライブ配信


// Run inference on the frame. The embedding results will be available
// via the `resultListener` provided in the `ImageEmbedderOptions` when
// the image embedder was created.
imageEmbedder.embedAsync(image, frameTimestampMs);
    

次の点にご留意ください。

  • 動画モードまたはライブ配信モードで実行する場合は、 入力フレームのタイムスタンプを画像エンベディング タスクに渡します。
  • 画像モードまたは動画モードで実行すると、Image Embedder タスクが 入力画像の処理が完了するまで、現在のスレッドをブロックします。 クリックします。現在のスレッドをブロックしないようにするには、 使用します。
  • ライブ ストリーム モードで実行している場合、画像埋め込みタスクはブロックされない すぐに戻ります。このメソッドは、 完了するたびに、その検出結果が 表示されます。画像エンベディングがリクエストされたときに embedAsync 関数が呼び出された場合 タスクが別のフレームの処理でビジー状態の場合、タスクは新しい入力フレームを無視します。

このコード例では、embed 関数が ImageEmbedderHelper.kt 表示されます。

結果の処理と表示

推論を実行すると、画像エンベディング タスクは ImageEmbedderResult を返します。 エンベディングのリストを含むオブジェクト(浮動小数点または スカラー量子化)によって定義されます。

このタスクからの出力データの例を次に示します。

ImageEmbedderResult:
  Embedding #0 (sole embedding head):
    float_embedding: {0.0, 0.0, ..., 0.0, 1.0, 0.0, 0.0, 2.0}
    head_index: 0

この結果は、次の画像を埋め込むことで取得されました。

2 つのエンベディングの類似度を比較できます。 ImageEmbedder.cosineSimilarity 関数を使用します。詳細については、次のコードをご覧ください。 例です。

// Compute cosine similarity.
double similarity = ImageEmbedder.cosineSimilarity(
  result.embeddingResult().embeddings().get(0),
  otherResult.embeddingResult().embeddings().get(0));