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. El Generador de imágenes también puede generar imágenes basadas en conceptos específicos que se le proporcionan al modelo durante el entrenamiento o el reentrenamiento. Para obtener más información, consulta Personaliza con LoRA.
El código de muestra que se describe en estas instrucciones está disponible en GitHub. Para obtener más información sobre las capacidades, los modelos y las opciones de configuración de esta tarea, consulta la Descripción general.
Ejemplo de código
El código de ejemplo de MediaPipe Tasks es una implementación básica de una app de Image Generator para Android. Puedes usar la app como punto de partida para tu propia app para Android o consultarla cuando modifiques una app existente. El código de ejemplo de Image Generator se aloja en GitHub.
Descarga el código
En las siguientes instrucciones, se muestra cómo crear una copia local del código de ejemplo con la herramienta de línea de comandos git.
Para descargar el código de ejemplo, sigue estos pasos:
- Clona el repositorio de Git con el siguiente comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
- De manera opcional, configura tu instancia de Git para que use la extracción dispersa, de modo que solo tengas los archivos de la app de ejemplo de Image Generator:
cd mediapipe-samples git sparse-checkout init --cone git sparse-checkout set examples/image_generation/android
Después de crear una versión local del código de ejemplo, puedes importar el proyecto a Android Studio y ejecutar la app. Para obtener instrucciones, consulta la Guía de configuración para Android.
Componentes clave
Los siguientes archivos contienen el código fundamental para esta aplicación de ejemplo de generación de imágenes:
- ImageGenerationHelper.kt: Inicializa la tarea y controla la generación de imágenes.
- DiffusionActivity.kt: Genera imágenes cuando no se habilitan los complementos o los pesos de LoRA.
- PluginActivity.kt: Implementa los modelos de complementos, lo que permite a los usuarios proporcionar una imagen de condición como entrada.
- LoRAWeightActivity.kt: Accede a los pesos de LoRA y los controla, que se usan para personalizar los modelos de base 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 proyectos de código específicamente para usar Image Generator. Si deseas obtener información general para configurar tu entorno de desarrollo para usar las tareas de MediaPipe, incluidos los requisitos de versión de la plataforma, consulta la guía de configuración para Android.
Dependencias
La tarea Image Generator usa la biblioteca com.google.mediapipe:tasks-vision-image-generator. Agrega esta dependencia al archivo build.gradle de tu app para Android:
dependencies {
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
}
Para dispositivos con Android 12 (API 31) o versiones posteriores, agrega la dependencia de la biblioteca nativa de OpenCL. Para obtener más información, consulta la documentación sobre la etiqueta uses-native-library.
Agrega las siguientes etiquetas uses-native-library al archivo 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" />
Modelo
La tarea MediaPipe Image Generator requiere un modelo fundamental entrenado que sea compatible con esta tarea. Después de descargar un modelo, instala las dependencias necesarias y conviértelo a un formato adecuado. Luego, envía el modelo convertido al dispositivo Android.
Para obtener más información sobre los modelos entrenados disponibles para el Generador de imágenes, consulta la sección Modelos del resumen de la tarea.
Descarga el modelo de base
El Generador de imágenes requiere que el modelo de base coincida con el formato del modelo stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only, según el siguiente modelo: stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only.
Instala dependencias y convierte el modelo
$ pip install torch typing_extensions numpy Pillow requests pytorch_lightning absl-py
Ejecuta la secuencia de comandos convert.py:
$ 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 de LoRA (opcional)
Si planeas usar un modelo de complemento, verifica si el modelo se debe descargar. En el caso de los complementos que requieren un modelo adicional, los modelos de complementos deben incluirse en el APK o descargarse a pedido. Los modelos de complementos son ligeros (alrededor de 23 MB) y se pueden incluir directamente en el APK. Sin embargo, recomendamos descargar los modelos de complementos a pedido.
Si personalizaste un modelo con LoRA, descárgalo a pedido. Para obtener más información, consulta el modelo de complemento de los pesos de LoRA.
Crea la tarea
La tarea MediaPipe Image Generator usa la función createFromOptions() para configurar la tarea. La función createFromOptions() acepta valores para las opciones de configuración. Para obtener más información sobre las opciones de configuración, consulta Opciones de configuración.
Opciones de configuración
Esta tarea tiene las siguientes opciones de configuración para las apps para Android:
| Nombre de la opción | Descripción | Rango de valores |
|---|---|---|
imageGeneratorModelDirectory |
Es el directorio del modelo de generador de imágenes que almacena los pesos del modelo. | PATH |
loraWeightsFilePath |
Establece la ruta de acceso al archivo de pesos de LoRA. Es opcional y solo se aplica si el modelo se personalizó con LoRA. | PATH |
errorListener |
Establece un objeto de escucha de errores opcional. | N/A |
La tarea también admite modelos de complementos, lo que permite a los usuarios incluir imágenes de condiciones en la entrada de la tarea, que el modelo base puede aumentar y usar como referencia para la generación. Estas imágenes de condición pueden ser marcas faciales, contornos de bordes y estimaciones de profundidad, que el modelo usa como contexto e información adicionales para generar imágenes.
Cuando agregues un modelo de complemento al modelo de base, también configura las opciones del complemento. El complemento Face landmark usa faceConditionOptions, el complemento Canny edge usa edgeConditionOptions y el complemento Depth usa depthConditionOptions.
Opciones de Canny edge
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 la apertura para el operador de Sobel. El rango habitual es de 3 a 7. | Integer |
3 |
l2Gradient |
Indica 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 de acceso al 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 de 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 |
Es la puntuación de confianza mínima para que la detección de rostros se considere exitosa. | Float [0.0,1.0] |
0.5 |
minFacePresenceConfidence |
Es la puntuación de confianza mínima de la presencia del rostro en la detección de puntos de referencia faciales. | Float [0.0,1.0] |
0.5 |
faceModelBaseOptions |
Objeto BaseOptions que establece la ruta de acceso al modelo que crea la imagen de condición. |
Objeto BaseOptions |
N/A |
FacePluginModelBaseOptions |
El objeto BaseOptions que establece la ruta de acceso al 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 |
Objeto BaseOptions que establece la ruta de acceso al modelo que crea la imagen de condición. |
Objeto BaseOptions |
N/A |
depthPluginModelBaseOptions |
El objeto BaseOptions que establece la ruta de acceso al 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 aplicas un modelo de complemento opcional, establece las opciones básicas para el modelo de complemento 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)
Borde de 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)
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)
Crea con pesos de LoRA
Si incluyes pesos de LoRA, usa el parámetro loraWeightsFilePath para indicar la ubicación de la ruta de acceso.
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á.
- iterations (obligatorio): Es la cantidad total de iteraciones para generar la imagen. Un buen punto de partida es 20.
- seed (obligatorio): Es la semilla aleatoria que se usa durante la generación de imágenes.
- Imagen de condición (opcional): Es la imagen que el modelo usa como referencia para la 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 básico
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 el parámetro conditionType para elegir el modelo de complemento y el parámetro sourceConditionImage para generar la imagen de condición.
| Nombre de la opción | Descripción | Valor |
|---|---|---|
conditionType |
Es el modelo de complemento que se aplica al modelo de base. | {"FACE", "EDGE", "DEPTH"} |
sourceConditionImage |
Es 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 la imagen de condición:
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 la instrucción, la semilla y la cantidad de iteraciones.
imageGenerator.setInputs(
prompt,
conditionalImage,
conditionType,
iteration,
seed
)
Entradas con pesos de LoRA
Si usas pesos de LoRA, asegúrate de que el token esté en la instrucción de texto si deseas generar una imagen con el concepto específico que representan 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 contenido 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 contenido 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
}
Cómo generar contenido con pesos de LoRA
El proceso de generar imágenes con un modelo personalizado con pesos de LoRA es similar al proceso con un modelo base estándar. Asegúrate de que el token se incluya en la instrucción y ejecuta 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 estos resultados intermedios, llama al método setInputs y, luego, llama a execute() para ejecutar cada paso. Establece el parámetro showResult en true para mostrar los resultados intermedios.
fun execute(showResult: Boolean): Bitmap {
val result = imageGenerator.execute(showResult)
val bitmap =
BitmapExtractor.extract(result.generatedImage())
return bitmap
}
Cómo controlar y mostrar los resultados
El Generador de imágenes devuelve un objeto ImageGeneratorResult, que incluye la imagen generada, una marca de tiempo de la hora de finalización y la imagen condicional, si se proporcionó una como entrada.
val bitmap = BitmapExtractor.extract(result.generatedImage())
La siguiente imagen se generó a partir de las siguientes entradas, solo con un modelo fundamental.
Entradas:
- Instrucción: "Un mapache de dibujos animados colorido con un sombrero de ala ancha y flexible sosteniendo un palo mientras camina por el bosque, animado, vista de tres cuartos, pintura"
- Semilla: 312687592
- Iteraciones: 20
Imagen generada: