Guía de generación de imágenes para Android

La tarea MediaPipe Image Generator te permite generar imágenes basadas en una instrucción de texto. Esta tarea usa un modelo de texto a imagen para generar imágenes con técnicas de difusión.

La tarea acepta una instrucción de texto como entrada, junto con una imagen de condición opcional que el modelo puede aumentar y usar como referencia para la generación. Generador de imágenes también puede generar imágenes basadas en conceptos específicos proporcionados al modelo durante o reentrenamiento. Para obtener más información, consulta personalizar con LoRA

La muestra de código descrita en estas instrucciones está disponible en GitHub: Para obtener más información sobre las capacidades, los modelos y las opciones de configuración para completar esta tarea, consulta la Descripción general.

Ejemplo de código

El código de ejemplo de tareas de MediaPipe es una implementación básica de un generador de imágenes para Android. Puedes usar la app como punto de partida para tu propio dispositivo Android. app o hacer referencia a ella cuando modifiques una existente. Ejemplo del generador de imágenes código se aloja en GitHub:

Descarga el código

En las siguientes instrucciones, se muestra cómo crear una copia local del ejemplo con la herramienta de línea de comandos git.

Para descargar el código de ejemplo, haz lo siguiente:

  1. Clona el repositorio de Git con el siguiente comando:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. De forma opcional, configura tu instancia de Git para que use un método de confirmación de la compra disperso solo los archivos de la app de ejemplo de Generador de imágenes:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_generator/android
    

Después de crear una versión local del código de ejemplo, puedes importar el proyecto en Android Studio y ejecutar la app. Para obtener instrucciones, consulta la Guía de configuración de Android

Componentes clave

Los siguientes archivos contienen el código crucial para este ejemplo de generación de imágenes. aplicación:

  • ImageGenerationHelper.kt: Inicializa la tarea y controla la generación de imágenes.
  • DiffusionActivity.kt: Genera imágenes cuando los complementos o las ponderaciones de LoRA no están habilitados.
  • PluginActivity.kt: Implementa los modelos de complementos, que permiten a los usuarios proporcionar una condición. imagen como entrada.
  • LoRAWeightActivity.kt: Accede a las ponderaciones de LoRA y las maneja para personalizar las bases de datos y permitirles generar imágenes de conceptos específicos.

Configuración

En esta sección, se describen los pasos clave para configurar tu entorno de desarrollo y en sus proyectos de código específicamente para usar Image Generator. Para obtener información general configurar tu entorno de desarrollo para usar tareas de MediaPipe, como requisitos de la versión de la plataforma, consulta la Guía de configuración de Android

Dependencias

La tarea Generador de imágenes usa com.google.mediapipe:tasks-vision-image-generator. Agrega esta dependencia en el archivo build.gradle de tu app para Android:

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

Para dispositivos con Android 12 (nivel de API 31) o versiones posteriores, agrega la biblioteca nativa de OpenCL dependencia a AndroidManifest.xml. Para obtener más información, consulta la documentación sobre el uses-native-library etiqueta.

Es posible que algunos dispositivos Android también requieran bibliotecas adicionales:

<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" />

Modelo

La tarea Generador de imágenes MediaPipe requiere un modelo de base entrenado que sea compatible con esta tarea. Después de descargar un modelo, instala las dependencias necesarias y y convertir tu modelo en un formato adecuado. Luego, envía el código modelo al dispositivo Android.

Si deseas obtener más información sobre los modelos entrenados disponibles para el generador de imágenes, consulta la tarea Descripción general de la sección Modelos.

Descargar el modelo de base

El generador de imágenes requiere que el modelo de base coincida con runwayml/stable-diffusion-v1-5 EMA-only, según lo siguiente modelo: runwayml/stable-diffusion-v1-5.

Instala dependencias y convierte el modelo

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

Ejecuta el convert.py secuencia de comandos:

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

Envía el modelo convertido al dispositivo

Envía el contenido de la carpeta <output_path> al dispositivo 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

Descarga modelos de complementos y agrega pesos LoRA (opcional)

Si piensas usar un modelo de complemento, verifica si el modelo debe descargarse. En el caso de los complementos que requieren un modelo adicional, el complemento los modelos deben estar agrupados en el APK o descargarse a pedido. Modelos de complementos son ligeros (~23 MB) y se pueden agrupar directamente en el APK. Sin embargo, se recomendó descargar modelos de complementos a pedido.

Si personalizaste un modelo con LoRA, descargarlos a pedido. Para ver más consulta el modelo de complemento de las ponderaciones de LoRA.

Crea la tarea

La tarea del generador de imágenes MediaPipe usa la función createFromOptions() para configurar la tarea. La función createFromOptions() acepta valores para la configuración opciones de estado. Para obtener más información sobre las opciones de configuración, consulta Configuración de la aplicación.

Opciones de configuración

Esta tarea tiene las siguientes opciones de configuración para apps para Android:

Nombre de la opción Descripción Rango de valores
imageGeneratorModelDirectory El directorio del modelo del generador de imágenes en el que se almacenan los pesos del modelo. PATH
loraWeightsFilePath Configura la ruta de acceso al archivo de ponderaciones de LoRA. Opcional y solo aplicable si se personalizó el modelo con LoRA. PATH
errorListener Configura un objeto de escucha de errores opcional. N/A

La tarea también admite modelos de complementos, que permiten a los usuarios incluir imágenes de condiciones. en la entrada de la tarea, que el modelo de base puede ampliar y usar como referencia para generarla. Estas imágenes de afecciones pueden ser puntos de referencia de rostros, contornos de bordes y estimaciones de profundidad, que el modelo usa como información y contexto adicionales para generar imágenes.

Cuando agregues un modelo de complemento al modelo de base, también debes configurar el complemento opciones de estado. El complemento del punto de referencia Face usa faceConditionOptions, la interfaz de Canny. El complemento usa edgeConditionOptions, y el de Depth usa depthConditionOptions

Opciones perimetrales inteligentes

Configura las siguientes opciones en edgeConditionOptions.

Nombre de la opción Descripción Rango de valores Valor predeterminado
threshold1 Primer umbral para el procedimiento de histéresis. Float 100
threshold2 Es el segundo umbral para el procedimiento de histéresis. Float 200
apertureSize Tamaño de apertura del operador Sobel. El rango habitual es de 3 a 7. Integer 3
l2Gradient Si se usa la norma L2 para calcular la magnitud del gradiente de la imagen, en lugar de la norma L1 predeterminada. BOOLEAN False
EdgePluginModelBaseOptions El objeto BaseOptions que establece la ruta para el modelo del complemento. Objeto BaseOptions N/A

Para obtener más información sobre cómo funcionan estas opciones de configuración, consulta Detector de bordes Canny.

Opciones de puntos de referencia faciales

Configura las siguientes opciones en faceConditionOptions.

Nombre de la opción Descripción Rango de valores Valor predeterminado
minFaceDetectionConfidence La puntuación de confianza mínima para la detección de rostro correctamente. Float [0.0,1.0] 0.5
minFacePresenceConfidence La puntuación de confianza mínima de la presencia facial en la detección de puntos de referencia faciales. Float [0.0,1.0] 0.5
faceModelBaseOptions El objeto BaseOptions que establece la ruta para el modelo que crea la imagen de la condición. Objeto BaseOptions N/A
FacePluginModelBaseOptions El objeto BaseOptions que establece la ruta para el modelo del complemento. Objeto BaseOptions N/A

Para obtener más información sobre cómo funcionan estas opciones de configuración, consulta la Tarea Face Landmarker.

Opciones de profundidad

Configura las siguientes opciones en depthConditionOptions.

Nombre de la opción Descripción Rango de valores Valor predeterminado
depthModelBaseOptions El objeto BaseOptions que establece la ruta para el modelo que crea la imagen de la condición. Objeto BaseOptions N/A
depthPluginModelBaseOptions El objeto BaseOptions que establece la ruta para el modelo del complemento. Objeto BaseOptions N/A

Crea solo con el modelo de base

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

imageGenerator = ImageGenerator.createFromOptions(context, options)

Crea con complementos

Si estás aplicando un modelo de complemento opcional, establece las opciones de base para el de complementos con setPluginModelBaseOptions. Si el modelo de complemento requiere un modelo descargado adicional para crear la imagen de condición, especifica la ruta de acceso en BaseOptions

Punto de referencia facial

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 Edge

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)
    

Profundidad

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)
    

Crear con pesos de LoRA

Si incluyes ponderaciones de LoRA, usa el parámetro loraWeightsFilePath para apuntan a la ubicación de la ruta.

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

imageGenerator = ImageGenerator.createFromOptions(context, options)

Preparar los datos

El generador de imágenes acepta las siguientes entradas:

  • prompt (obligatorio): Es la instrucción de texto que describe la imagen que se generará.
  • Iteraciones (obligatorio): Es el total de iteraciones para generar la imagen. R un buen punto de partida es 20.
  • seed (obligatorio): El valor inicial aleatorio que se usa durante la generación de la imagen.
  • Imagen de condición (opcional): Es la imagen que usa el modelo como referencia. generación. Solo se aplica cuando se usa un modelo de complemento.
  • condition type (opcional): Es el tipo de modelo de complemento que se usa con la tarea. Solo se aplica cuando se usa un modelo de complemento.

Entradas solo con el modelo de base

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

Entradas con complementos

Si aplicas un modelo de complemento opcional, también usa conditionType. para elegir el modelo del complemento y el parámetro sourceConditionImage para generar la imagen de condición.

Nombre de la opción Descripción Valor
conditionType El modelo de complemento aplicado al modelo de base. {"FACE", "EDGE", "DEPTH"}
sourceConditionImage La imagen de origen que se usó para crear la imagen de condición. Objeto MPImage

Si usas un modelo de complemento, usa createConditionImage para crear el imagen de estado:

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

Después de crear la imagen de condición, inclúyela como entrada junto con el instrucción, valor inicial y cantidad de iteraciones.

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

Entradas con ponderaciones de LoRA

Si usas ponderaciones de LoRA, asegúrate de que el token esté en el mensaje de texto si pretendes generar una imagen con el concepto específico representado por el los pesos.

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

Ejecuta la tarea

Usa el método generate() para generar una imagen con las entradas proporcionadas en la sección anterior. Esto produce una sola imagen generada.

Genera solo con el modelo de base

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

Genera con complementos

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
}

Genera con pesos de LoRA

El proceso de generar imágenes con un modelo personalizado con pesos LoRA es similar al proceso con un modelo de base estándar. Asegúrate de que el token esté incluida en el mensaje y ejecutes el mismo código.

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

Generación iterativa

El generador de imágenes también puede generar las imágenes intermedias durante cada iteración, como se define en el parámetro de entrada iterations. Para ver estas resultados intermedios, llama al método setInputs y, luego, a execute() para ejecutar en cada paso. Establece el parámetro showResult en true para mostrar el valor intermedio. resultados.

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

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

    return bitmap
}

Cómo controlar y mostrar resultados

El generador de imágenes muestra un ImageGeneratorResult, que incluye el elemento imagen, una marca de tiempo de la hora de finalización y la imagen condicional, si existe se proporcionó como entrada.

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

La siguiente imagen se generó a partir de las siguientes entradas, con solo un de base.

Entradas:

  • Instrucción: "Un mapache colorido de dibujos animados con un sombrero de ala ancha flexible sosteniendo un palo por el bosque, con una vista animada de tres cuartos, pintura"
  • Origen: 312687592
  • Iteraciones: 20

Imagen generada: