Android の画像生成ガイド

MediaPipe Image Generator タスクでは、テキスト プロンプトに基づいて画像を生成できます。このタスクでは、テキストから画像へのモデルを使用して、拡散手法で画像を生成します。

このタスクは、テキスト プロンプトを入力として受け入れます。また、オプションの条件画像も受け取ります。この条件画像は、モデルが拡張し、生成の参照として使用できます。画像生成ツールでは、トレーニング中または再トレーニング中にモデルに提供された特定のコンセプトに基づいて画像を生成することもできます。詳細については、LoRA でカスタマイズするをご覧ください。

この手順で説明されているコードサンプルは、GitHub で入手できます。このタスクの機能、モデル、構成オプションの詳細については、概要をご覧ください。

サンプルコード

MediaPipe Tasks のサンプルコードは、Android 用画像生成アプリの基本的な実装です。アプリは、独自の Android アプリの出発点として使用できます。または、既存のアプリを変更するときにアプリを参照できます。画像生成ツールのサンプルコードは GitHub でホストされています。

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

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

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

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

サンプルコードのローカル バージョンを作成したら、Android Studio にプロジェクトをインポートしてアプリを実行できます。手順については、Android の設定ガイドをご覧ください。

主要コンポーネント

次のファイルには、この画像生成サンプル アプリケーションの重要なコードが含まれています。

  • ImageGenerationHelper.kt: タスクを初期化し、画像生成を処理します。
  • DiffusionActivity.kt: プラグインまたは LoRA の重みが有効になっていない場合に、画像を生成します。
  • PluginActivity.kt: プラグイン モデルを実装します。これにより、ユーザーが条件画像を入力として提供できるようになります。
  • LoRAWeightActivity.kt: LoRA の重みにアクセスして処理します。LoRA の重みは、基盤モデルをカスタマイズして特定のコンセプトの画像を生成するために使用します。

セットアップ

このセクションでは、画像生成ツールを使用するように開発環境とコード プロジェクトをセットアップするための主な手順について説明します。プラットフォームのバージョン要件など、MediaPipe タスクを使用するための開発環境の設定に関する一般的な情報については、Android の設定ガイドをご覧ください。

依存関係

画像生成タスクでは、com.google.mediapipe:tasks-vision-image-generator ライブラリを使用します。この依存関係を Android アプリの build.gradle ファイルに追加します。

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

Android 12(API 31)以降を搭載したデバイスでは、ネイティブ OpenCL ライブラリの依存関係を AndroidManifest.xml に追加します。詳細については、uses-native-library タグのドキュメントをご覧ください。

一部の Android デバイスでは、追加のライブラリが必要になる場合があります。

<uses-native-library android:name="libOpenCL.so" android:required="false" />
<uses-native-library android:name="libOpenCL-car.so" android:required="false"/>
<uses-native-library android:name="libOpenCL-pixel.so" android:required="false" />

モデル

MediaPipe Image Generator タスクには、このタスクと互換性のあるトレーニング済みの基盤モデルが必要です。モデルをダウンロードしたら、必要な依存関係をインストールして、モデルを適切な形式に変換します。次に、変換されたモデルを Android デバイスにプッシュします。

画像生成ツールで利用可能なトレーニング済みモデルの詳細については、タスクの概要のモデル セクションをご覧ください。

基盤モデルをダウンロード

Image Generator では、モデル runwayml/stable-diffusion-v1-5 に基づいて、基盤モデルが runwayml/stable-diffusion-v1-5 EMA-only モデル形式と一致している必要があります。

依存関係をインストールしてモデルを変換する

$ pip install torch typing_extensions numpy Pillow requests pytorch_lightning absl-py

convert.py スクリプトを実行します。

$ python3 convert.py --ckpt_path <ckpt_path> --output_path <output_path>

変換されたモデルをデバイスにプッシュする

<output_path> フォルダの内容を Android デバイスにプッシュします。

$ adb shell rm -r /data/local/tmp/image_generator/ # Remove any previously loaded weights
$ adb shell mkdir -p /data/local/tmp/image_generator/
$ adb push <output_path>/. /data/local/tmp/image_generator/bins

プラグインモデルをダウンロードして LoRA の重みを追加する(省略可)

プラグイン モデルを使用する場合は、モデルをダウンロードする必要があるかどうかを確認します。追加のモデルが必要なプラグインの場合は、プラグイン モデルを APK にバンドルするか、オンデマンドでダウンロードする必要があります。プラグインモデルは軽量(約 23 MB)で、APK に直接バンドルできます。ただし、プラグイン モデルはオンデマンドでダウンロードすることをおすすめします。

LoRA でモデルをカスタマイズしている場合は、オンデマンドでダウンロードします。詳細については、LoRA 重みプラグイン モデルをご覧ください。

タスクを作成する

MediaPipe Image Generator タスクは、createFromOptions() 関数を使用してタスクをセットアップします。createFromOptions() 関数は、構成オプションの値を受け入れます。構成オプションの詳細については、構成オプションをご覧ください。

構成オプション

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

オプション名 説明 値の範囲
imageGeneratorModelDirectory モデルの重み付けが格納される画像生成モデルのディレクトリ。 PATH
loraWeightsFilePath LoRA 重みファイルのパスを設定します。省略可。モデルが LoRA でカスタマイズされている場合にのみ適用されます。 PATH
errorListener オプションのエラーリスナーを設定します。 N/A

タスクはプラグイン モデルもサポートしています。これにより、ユーザーはタスク入力に条件画像を含めることができます。この画像を基盤モデルで拡張し、生成の参照として使用できます。これらの条件画像には、顔のランドマーク、エッジの輪郭、深度推定値があります。モデルはこれらを、画像を生成するための追加のコンテキストと情報として使用します。

プラグイン モデルを基盤モデルに追加する場合は、プラグインのオプションも構成します。顔ランドマーク プラグインは faceConditionOptions、Canny Edge プラグインは edgeConditionOptions、Depth プラグインは depthConditionOptions を使用します。

Canny Edge のオプション

edgeConditionOptions で次のオプションを構成します。

オプション名 説明 値の範囲 デフォルト値
threshold1 ヒステリシス手順の 1 つ目のしきい値です。 Float 100
threshold2 ヒステリシス手順の 2 つ目のしきい値。 Float 200
apertureSize Sobel オペレーターの絞りサイズ。通常は 3 ~ 7 の範囲です。 Integer 3
l2Gradient デフォルトの L1 ノルムではなく、L2 ノルムを使用して画像勾配の大きさを計算するかどうか。 BOOLEAN False
EdgePluginModelBaseOptions プラグイン モデルのパスを設定する BaseOptions オブジェクト。 BaseOptions オブジェクト N/A

これらの構成オプションの仕組みの詳細については、Canny エッジ検出器をご覧ください。

顔ランドマークのオプション

faceConditionOptions で次のオプションを構成します。

オプション名 説明 値の範囲 デフォルト値
minFaceDetectionConfidence 顔検出が成功したとみなす最小信頼スコア。 Float [0.0,1.0] 0.5
minFacePresenceConfidence 顔ランドマーク検出における顔存在スコアの最小信頼スコア。 Float [0.0,1.0] 0.5
faceModelBaseOptions 条件画像を作成するモデルのパスを設定する BaseOptions オブジェクト。 BaseOptions オブジェクト N/A
FacePluginModelBaseOptions プラグイン モデルのパスを設定する BaseOptions オブジェクト。 BaseOptions オブジェクト N/A

これらの構成オプションの仕組みの詳細については、顔のランドマーク タスクをご覧ください。

奥行きオプション

depthConditionOptions で次のオプションを構成します。

オプション名 説明 値の範囲 デフォルト値
depthModelBaseOptions 条件画像を作成するモデルのパスを設定する BaseOptions オブジェクト。 BaseOptions オブジェクト N/A
depthPluginModelBaseOptions プラグイン モデルのパスを設定する BaseOptions オブジェクト。 BaseOptions オブジェクト N/A

基盤モデルのみを使用して作成する

val options = ImageGeneratorOptions.builder()
    .setImageGeneratorModelDirectory(modelPath)
    .build()

imageGenerator = ImageGenerator.createFromOptions(context, options)

プラグインを使用して作成する

オプションのプラグイン モデルを適用する場合は、setPluginModelBaseOptions を使用してプラグイン モデルの基本オプションを設定します。プラグイン モデルで条件イメージを作成するためにダウンロードされた追加のモデルが必要な場合は、BaseOptions にパスを指定します。

顔のランドマーク

val options = ImageGeneratorOptions.builder()
    .setImageGeneratorModelDirectory(modelPath)
    .build()

val faceModelBaseOptions = BaseOptions.builder()
    .setModelAssetPath("face_landmarker.task")
    .build()

val facePluginModelBaseOptions = BaseOptions.builder()
    .setModelAssetPath("face_landmark_plugin.tflite")
    .build()

val faceConditionOptions = FaceConditionOptions.builder()
    .setFaceModelBaseOptions(faceModelBaseOptions)
    .setPluginModelBaseOptions(facePluginModelBaseOptions)
    .setMinFaceDetectionConfidence(0.3f)
    .setMinFacePresenceConfidence(0.3f)
    .build()

val conditionOptions = ConditionOptions.builder()
    .setFaceConditionOptions(faceConditionOptions)
    .build()

imageGenerator =
    ImageGenerator.createFromOptions(context, options, conditionOptions)
    

キャニーエッジ

val options = ImageGeneratorOptions.builder()
    .setImageGeneratorModelDirectory(modelPath)
    .build()

val edgePluginModelBaseOptions = BaseOptions.builder()
    .setModelAssetPath("canny_edge_plugin.tflite")
    .build()

val edgeConditionOptions = EdgeConditionOptions.builder()
    .setThreshold1(100.0f)
    .setThreshold2(100.0f)
    .setApertureSize(3)
    .setL2Gradient(false)
    .setPluginModelBaseOptions(edgePluginModelBaseOptions)
    .build()

val conditionOptions = ConditionOptions.builder()
    .setEdgeConditionOptions(edgeConditionOptions)
    .build()

imageGenerator =
    ImageGenerator.createFromOptions(context, options, conditionOptions)
    

掘り下げた分析

val options = ImageGeneratorOptions.builder()
    .setImageGeneratorModelDirectory(modelPath)
    .build()

val depthModelBaseOptions = BaseOptions.builder()
    .setModelAssetPath("depth_model.tflite")
    .build()

val depthPluginModelBaseOptions = BaseOptions.builder()
    .setModelAssetPath("depth_plugin.tflite")
    .build()

val depthConditionOptions =
    ConditionOptions.DepthConditionOptions.builder()
        .setDepthModelBaseOptions(depthModelBaseOptions)
        .setPluginModelBaseOptions(depthPluginModelBaseOptions)
        .build()

val conditionOptions = ConditionOptions.builder()
    .setDepthConditionOptions(depthConditionOptions)
    .build()

imageGenerator =
    ImageGenerator.createFromOptions(context, options, conditionOptions)
    

LoRA の重みを使用して作成する

LoRA の重みを含める場合は、loraWeightsFilePath パラメータを使用してパスのロケーションを指定します。

val options = ImageGeneratorOptions.builder()
    .setLoraWeightsFilePath(weightsPath)
    .setImageGeneratorModelDirectory(modelPath)
    .build()

imageGenerator = ImageGenerator.createFromOptions(context, options)

データの準備

Image Generator は以下の入力を受け入れます。

  • prompt(必須): 生成する画像を説明するテキスト プロンプト。
  • iterations(必須): 画像を生成するための反復処理の合計数。20 から始めることをおすすめします。
  • seed(必須): 画像生成時に使用されるランダムなシード。
  • 条件画像(省略可): モデルが生成の参照として使用する画像。プラグイン モデルを使用する場合にのみ適用されます。
  • condition type(省略可): タスクで使用されるプラグイン モデルのタイプ。 プラグイン モデルを使用する場合にのみ適用されます。

基盤モデルのみによる入力

fun setInput(prompt: String, iteration: Int, seed: Int) {
    imageGenerator.setInputs(prompt, iteration, seed)
}

プラグインを使用した入力

オプションのプラグイン モデルを適用する場合は、conditionType パラメータを使用してプラグイン モデルを選択し、sourceConditionImage パラメータを使用して条件画像を生成します。

オプション名 説明
conditionType 基盤モデルに適用されるプラグイン モデル。 {"FACE", "EDGE", "DEPTH"}
sourceConditionImage 条件画像の作成に使用されるソース画像。 MPImage オブジェクト

プラグイン モデルを使用している場合は、createConditionImage を使用して条件画像を作成します。

fun createConditionImage(
    inputImage: MPImage,
    conditionType: ConditionType
): Bitmap {
    val result =
        imageGenerator.createConditionImage(inputImage, conditionType)
    return BitmapExtractor.extract(result)
}

条件画像を作成したら、プロンプト、シード、反復回数とともに入力として に含めます。

imageGenerator.setInputs(
    prompt,
    conditionalImage,
    conditionType,
    iteration,
    seed
)

LoRA の重みを持つ入力

LoRA の重み付けを使用する場合、重み付けで表される特定のコンセプトを含む画像を生成する場合は、トークンがテキスト プロンプトに含まれていることを確認してください。

fun setInput(prompt: String, iteration: Int, seed: Int) {
    imageGenerator.setInputs(prompt, iteration, seed)
}

タスクを実行する

generate() メソッドを使用して、前のセクションで提供された入力から画像を生成します。これにより、単一の画像が生成されます。

基盤モデルのみで生成する

fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
    val result = imageGenerator.generate(prompt, iteration, seed)
    val bitmap = BitmapExtractor.extract(result?.generatedImage())
    return bitmap
}

プラグインで生成

fun generate(
    prompt: String,
    inputImage: MPImage,
    conditionType: ConditionType,
    iteration: Int,
    seed: Int
): Bitmap {
    val result = imageGenerator.generate(
        prompt,
        inputImage,
        conditionType,
        iteration,
        seed
    )
    val bitmap = BitmapExtractor.extract(result?.generatedImage())
    return bitmap
}

LoRA の重みを使用して生成する

LoRA の重みでカスタマイズしたモデルで画像を生成するプロセスは、標準の基盤モデルを使用するプロセスと似ています。プロンプトにトークンが含まれていることを確認し、同じコードを実行します。

fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
    val result = imageGenerator.generate(prompt, iteration, seed)
    val bitmap = BitmapExtractor.extract(result?.generatedImage())
    return bitmap
}

反復生成

画像生成ツールは、iterations 入力パラメータで定義されているように、反復処理ごとに生成された中間画像を出力することもできます。これらの中間結果を表示するには、setInputs メソッドを呼び出してから、execute() を呼び出して各ステップを実行します。中間結果を表示するには、showResult パラメータを true に設定します。

fun execute(showResult: Boolean): Bitmap {
    val result = imageGenerator.execute(showResult)

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

    return bitmap
}

結果を処理して表示する

Image Generator は ImageGeneratorResult を返します。これには、生成された画像、完了時刻のタイムスタンプ、条件画像(入力として提供されている場合)が含まれます。

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

次の画像は、基盤モデルのみを使用して、次の入力から生成されました。

入力:

  • プロンプト: 「つばの広い帽子をかぶったカラフルなアライグマが棒を持ち、森の中を歩く、3/4 のアニメーション、絵画」
  • シード: 312687592
  • 反復回数: 20

生成された画像: