MediaPipe を使用した Android でのオンデバイスでの画像生成

1. はじめに

MediaPipe とは

MediaPipe Solutions を使用すると、アプリに機械学習(ML)ソリューションを適用できます。このソリューションが提供するフレームワークでは、事前構築済みの処理パイプラインを構成し、魅力的で有用な出力を即座にユーザーに配信できます。これらのソリューションの多くは、MediaPipe Model Maker を使用してカスタマイズし、デフォルト モデルを更新することもできます。

テキストから画像の生成は、MediaPipe Solutions が提供するいくつかの ML タスクの一つです。

この Codelab では、ほぼベアな Android アプリから始め、複数のステップを進めて、Android デバイスで新しい画像を直接生成できるようにします。

学習内容

  • MediaPipe Tasks を使用して、テキストから画像の生成をローカルの Android アプリで実装する方法。

必要なもの

  • Android Studio のインストール バージョン(この Codelab は Android Studio Giraffe を使用して記述、テストされています)。
  • 8 GB 以上の RAM を搭載した Android デバイス。
  • Android 開発に関する基本的な知識と、あらかじめ記述されている Python スクリプトを実行する能力。

2. MediaPipe Tasks を Android アプリに追加する

Android スターター アプリをダウンロードする

この Codelab では、まず、画像生成の基本バージョンで使用する UI で構成される既製のサンプルを使用します。開始用アプリは、こちらの公式 MediaPipe サンプル リポジトリにあります。リポジトリのクローンを作成するか、[コード] >ZIP をダウンロード。

アプリを Android Studio にインポートする

  1. Android Studio を開きます。
  2. [Welcome to Android Studio] 画面で、右上にある [Open] を選択します。

a0b5b070b802e4ea.png

  1. リポジトリのクローンを作成またはダウンロードした場所に移動し、codelabs/image_generation_basic/android/start ディレクトリを開きます。
  2. この段階では、MediaPipe Tasks の依存関係がまだ追加されていないため、アプリはコンパイルできません

アプリを修正し、build.gradle ファイルに移動して [// Step 1 - Add dependency] まで下にスクロールして、アプリを実行させます。次に、次の行を追加し、Android Studio の上部にあるバナーに表示される [Sync Now] ボタンをクリックします。

// Step 1 - Add dependency
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'

同期が完了したら、Android Studio の右上にある緑色の実行矢印(7e15a9c9e1620fe7.png)をクリックして、すべてが正しく開いてインストールされていることを確認します。アプリが開き、2 つのラジオボタンと [INITIALIZE] というボタンの画面が表示されます。このボタンをクリックすると、すぐに別の UI が表示されます。UI はテキスト プロンプトとその他のオプションで構成され、[生成] ボタンと並んでいます。

83c31de8e8a320ee.png 78b8765e832024e3.png

残念ながら、これはスターター アプリの範囲です。このアプリを完成させ、デバイスで新しい画像の生成を開始する方法を学びましょう。

3. 画像生成ツールの設定

この例では、画像生成作業の大部分は ImageGenerationHelper.kt ファイルで行われます。このファイルを開くと、imageGenerator という変数がクラスの先頭にあるのがわかります。これは、画像生成アプリで手間のかかる処理を行う Task オブジェクトです。

このオブジェクトのすぐ下に、初期化 ImageGenerator() という関数があり、次のコメントが付いています。// ステップ 2 - 画像生成ツールの初期化ご想像のとおり、ここで ImageGenerator オブジェクトを初期化します。この関数本体を次のコードに置き換えて、画像生成モデルのパスを設定し、ImageGenerator オブジェクトを初期化します。

// Step 2 - initialize the image generator
val options = ImageGeneratorOptions.builder()
    .setImageGeneratorModelDirectory(modelPath)
    .build()

imageGenerator = ImageGenerator.createFromOptions(context, options)

その下には、setInput() という名前の別の関数があります。これは 3 つのパラメータを受け入れます。1 つは、生成された画像の定義に使用される prompt 文字列、新しい画像の生成中にタスクが通る iteration の回数、seed 値です。同じシードを使用して同じ画像を生成するときに、同じプロンプトに基づいて画像の新しいバージョンを作成します。この関数の目的は、中間ステップを表示する画像を作成するときに、画像生成ツールにこれらの初期パラメータを設定することです。

setInput() の本文(「ステップ 3 - 入力を受け入れる」というコメントが表示されます)を次の行に置き換えます。

// Step 3 - accept inputs
imageGenerator.setInputs(prompt, iteration, seed)

次の 2 つのステップで、生成が行われます。generate() 関数は setInput と同じ入力を受け入れますが、中間ステップの画像を返さないワンショット呼び出しとして画像を作成します。この関数の本文(「ステップ 4 - 反復処理を表示せずに生成」というコメントを含む)を次のように置き換えることができます。

// Step 4 - generate without showing iterations
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap

このタスクは同期的に行われるので、バックグラウンド スレッドから関数を呼び出す必要があります。これについては、この Codelab で後ほど詳しく説明します。

このファイルの最後のステップとして、Execute() 関数(ステップ 5 というラベル付き)を入力します。このメソッドは、ImageGenerator の Execute() 関数で実行される生成の単一ステップで中間画像を返すべきかどうかを示すパラメータを受け取ります。関数本体を次のコードに置き換えます。

// Step 5 - generate with iterations
val result = imageGenerator.execute(showResult)

if (result == null || result.generatedImage() == null) {
    return Bitmap.createBitmap(512, 512, Bitmap.Config.ARGB_8888)
        .apply {
            val canvas = Canvas(this)
            val paint = Paint()
            paint.color = Color.WHITE
            canvas.drawPaint(paint)
        }
}

val bitmap =
    BitmapExtractor.extract(result.generatedImage())

return bitmap

ヘルパー ファイルについては以上です。次のセクションでは、この例のロジックを処理する ViewModel ファイルに入力します。

4. アプリを統合する

MainViewModel ファイルは、このサンプルアプリに関連する UI の状態やその他のロジックを処理します。早速開いてみましょう。

ファイルの先頭に「ステップ 6 - モデルパスを設定する」というコメントが表示されています。ここで、画像生成に必要なモデルファイルをどこで見つけられるかをアプリに指示します。この例では、値を /data/local/tmp/image_generator/bins/ に設定します。

// Step 6 - set model path
private val MODEL_PATH = "/data/local/tmp/image_generator/bins/"

そこから、generateImage() 関数まで下にスクロールします。この関数の下にはステップ 7 とステップ 8 の両方があります。これらはそれぞれ、返された反復処理またはゼロで画像を生成するために使用されます。これらのオペレーションはどちらも同期的に行われるため、コルーチンにラップされていることがわかります。// ステップ 7 - イテレーションを表示せずに生成するコードブロックを、ImageGenerationHelper ファイルから generate() を呼び出す次のコードブロックに置き換えることから始めることができます。

// Step 7 - Generate without showing iterations
val result = helper?.generate(prompt, iteration, seed)
_uiState.update {
    it.copy(outputBitmap = result)
}

手順 8 は少し複雑です。run() 関数は、画像生成のすべてのステップではなく 1 つのステップのみを実行するため、各ステップをループで個別に呼び出す必要があります。また、現在のステップをユーザーに表示するかどうかも決定する必要があります。最後に、現在のイテレーションを表示する必要がある場合は、UI 状態を更新します。そのすべてを今すぐに実現できます。

// Step 8 - Generate with showing iterations
helper?.setInput(prompt, iteration, seed)
for (step in 0 until iteration) {
    isDisplayStep =
        (displayIteration > 0 && ((step + 1) % displayIteration == 0))
    val result = helper?.execute(isDisplayStep)

    if (isDisplayStep) {
        _uiState.update {
            it.copy(
                outputBitmap = result,
                generatingMessage = "Generating... (${step + 1}/$iteration)",
            )
        }
    }
}

この時点で、アプリをインストールし、画像生成ツールを初期化し、テキスト プロンプトに基づいて新しい画像を作成できることが推奨されています

ただし、画像生成ツールを初期化しようとするとアプリがクラッシュします。モデルファイルをデバイスにコピーする必要があるからです。動作が確認されているサードパーティ製モデルについての最新情報を取得し、この MediaPipe タスク用に変換してデバイスにコピーする方法については、公式ドキュメントのこちらのセクションをご覧ください。

ファイルを開発デバイスに直接コピーするだけでなく、実行時に必要なファイルをユーザーのデバイスに直接ダウンロードするように Firebase Storage を設定することもできます。

5. アプリをデプロイしてテストする

これで、テキスト プロンプトを受け取り、デバイス上で新しい画像を生成できるアプリが完成しました。先へ進んで、アプリを物理的な Android デバイスにデプロイしてテストします。ただし、8 GB 以上のメモリを搭載したデバイスでテストすることをおすすめします。

  1. Android Studio ツールバーの実行アイコン(7e15a9c9e1620fe7.png)をクリックしてアプリを実行します。
  2. 生成ステップの種類(最終または反復処理)を選択して、[INITIALIZE] ボタンを押します。
  3. 次の画面で必要なプロパティを設定し、[生成] ボタンをクリックしてツールで表示される内容を確認します。

e46cfaeb9d3fc235.gif

6. 完了

これで完了です。この Codelab では、デバイスでのテキストから画像の生成を Android アプリに追加する方法を学習しました。

次のステップ

画像生成タスクでは、他にも以下のようなことができます。

  • ベース画像を使用し、プラグインを介して生成された画像を構造化したり、Vertex AI を使用して独自の追加の LoRA 重みをトレーニングしたりできます。
  • Firebase Storage を使用すると、ADB ツールを必要とせずに、デバイス上でモデルファイルを取得できます。

この試験運用版のタスクで皆様が素晴らしい成果を出せるのを楽しみにしています。MediaPipe チームからのさらなる Codelab やコンテンツにもご期待ください。