适用于 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-samples
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_generation/android
    

创建示例代码的本地版本后,您可以将项目导入 Android Studio 并运行应用。如需相关说明,请参阅 Android 设置指南

关键组件

以下文件包含此图片生成示例应用的关键代码:

设置

本部分介绍了设置开发环境和代码项目以专门使用图片生成器的关键步骤。如需了解有关设置开发环境以使用 MediaPipe 任务的一般信息(包括平台版本要求),请参阅 Android 设置指南

依赖项

Image Generator 任务使用 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 库依赖项。如需了解详情,请参阅有关 uses-native-library 标记的文档。

将以下 uses-native-library 标记添加到 AndroidManifest.xml 文件中:

<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 设备。

如需详细了解图片生成器可用的预训练模型,请参阅任务概览的模型部分

下载基础模型

图片生成器要求基础模型符合 stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only 模型格式,具体基于以下模型:stable-diffusion-v1-5/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 中或按需下载。插件模型轻巧(约 23MB),可以直接捆绑在 APK 中。不过,我们建议按需下载插件模型。

如果您使用 LoRA 自定义了模型,则可以按需下载它们。如需了解详情,请参阅 LoRA 权重插件模型

创建任务

MediaPipe Image Generator 任务使用 createFromOptions() 函数来设置任务。createFromOptions() 函数接受配置选项的值。如需详细了解配置选项,请参阅配置选项

配置选项

此任务针对 Android 应用具有以下配置选项:

选项名称 说明 值范围
imageGeneratorModelDirectory 存储模型权重的图片生成器模型目录。 PATH
loraWeightsFilePath 设置 LoRA 权重文件的路径。可选,仅在模型通过 LoRA 进行自定义时适用。 PATH
errorListener 设置可选的错误监听器。 N/A

该任务还支持插件模型,让用户可以在任务输入中添加条件图片,基础模型可以扩充这些图片并将其用作生成参考。这些条件图片可以是面部地标、边缘轮廓和深度估计值,模型会将其用作额外的上下文和信息来生成图片。

向基础模型添加插件模型时,还要配置插件选项。人脸地标插件使用 faceConditionOptions,Canny 边缘插件使用 edgeConditionOptions,深度插件使用 depthConditionOptions

Canny 边缘检测选项

edgeConditionOptions 中配置以下选项。

选项名称 说明 值范围 默认值
threshold1 滞后过程的第一个阈值。 Float 100
threshold2 滞后过程的第二个阈值。 Float 200
apertureSize Sobel 算子的孔径大小。典型范围为 3-7。 Integer 3
l2Gradient 是否使用 L2 范数(而非默认的 L1 范数)来计算图像梯度幅度。 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)
    

Canny 边缘检测器

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)

准备数据

图片生成器接受以下输入内容:

  • 提示(必需):描述要生成的图片的文本提示。
  • 迭代次数(必需):生成图片的总迭代次数。一个不错的起点是 20。
  • seed(必需):图片生成期间使用的随机种子。
  • 条件图片(可选):模型在生成时用作参考的图片。仅在使用插件模型时适用。
  • 条件类型(可选):与任务搭配使用的插件模型类型。 仅在使用插件模型时适用。

仅包含基础模型的输入

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
}

处理和显示结果

图片生成器会返回一个 ImageGeneratorResult,其中包含生成的图片、完成时间的时间戳,以及条件图片(如果已作为输入提供)。

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

下图是仅使用基础模型,根据以下输入内容生成的。

输入:

  • 提示:“一只戴着软塌塌的宽边帽、拿着棍子在森林中行走的彩色卡通浣熊,动画,四分之三视角,绘画”
  • 种子:312687592
  • 迭代次数:20

生成的图片

根据提示生成的浣熊图片