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. Image Generator también puede generar imágenes basadas en conceptos específicos que se proporcionan al modelo durante el entrenamiento o el reentrenamiento. Para obtener más información, consulta Personaliza con LoRA.
El ejemplo de código 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 está alojado 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 de git.
Para descargar el código de ejemplo, haz lo siguiente:
- 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 usar el checkout disperso, 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 los complementos o los pesos de LoRA no están habilitados.
- 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. Para obtener información general sobre cómo configurar tu entorno de desarrollo para usar 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
uses-native-library
etiqueta.
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 de base 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 Image Generator, consulta la sección Modelos de la descripción general de la tarea.
Descarga el modelo de base
Image Generator requiere que el modelo de base coincida con el
stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only formato del modelo, basado en el siguiente
modelo:
stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only.
Instala las dependencias y convierte el modelo
$ pip install torch typing_extensions numpy Pillow requests pytorch_lightning absl-py
Ejecuta la
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 los modelos de complementos y agrega pesos de LoRA (opcional)
Si deseas 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 livianos (~23 MB) y se pueden incluir directamente en el APK. Sin embargo, te recomendamos que descargues 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 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 apps para Android:
| Nombre de la opción | Descripción | Rango de valores |
|---|---|---|
imageGeneratorModelDirectory |
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 condición en la entrada de la tarea, que el modelo de base puede aumentar y usar como referencia para la generación. Estas imágenes de condición pueden ser puntos de referencia 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 de puntos de referencia faciales usa faceConditionOptions, el complemento de bordes de Canny usa edgeConditionOptions y el complemento de profundidad usa depthConditionOptions.
Opciones de bordes de Canny
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 |
Segundo umbral para el procedimiento de histéresis. | Float |
200 |
apertureSize |
Tamaño de la apertura para el operador de Sobel. El rango habitual está entre 3 y 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
para el modelo de 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 |
La puntuación de confianza mínima para que la detección de rostros se considere considerada exitosa. | Float [0.0,1.0] |
0.5 |
minFacePresenceConfidence |
La puntuación de confianza mínima de la puntuación de 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 de acceso
para el modelo que crea la imagen de condición. |
Objeto BaseOptions |
N/A |
FacePluginModelBaseOptions |
El objeto BaseOptions que establece la ruta de acceso
para el modelo de 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 de acceso
para el modelo que crea la imagen de condición. |
Objeto BaseOptions |
N/A |
depthPluginModelBaseOptions |
El objeto BaseOptions que establece la ruta de acceso
para el modelo de 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 base para el modelo de complemento con setPluginModelBaseOptions. Si el modelo de complemento requiere un modelo adicional descargado para crear la imagen de condición, especifica la ruta de acceso en BaseOptions.
Puntos de referencia faciales
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 apuntar a 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
Image Generator acepta las siguientes entradas:
- prompt (obligatorio): Es la instrucción de texto que describe la imagen que se generará.
- iterations (obligatorio): Son las iteraciones totales 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.
- condition image (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 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 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 |
El modelo de complemento aplicado al modelo de base. | {"FACE", "EDGE", "DEPTH"} |
sourceConditionImage |
La imagen de origen que se usa 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 representado por 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 generación de imágenes con un modelo personalizado con pesos de LoRA es similar al proceso con un modelo de base estándar. Asegúrate de que el token esté incluido 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
Image Generator también puede generar las imágenes intermedias generadas 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, 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
}
Controla y muestra los resultados
Image Generator muestra un ImageGeneratorResult, que incluye la imagen generada, una marca de tiempo de la hora de finalización y la imagen condicional si se proporcionó como entrada.
val bitmap = BitmapExtractor.extract(result.generatedImage())
La siguiente imagen se generó a partir de las siguientes entradas, usando solo un modelo de base.
Entradas:
- Instrucción: "a colorful cartoon raccoon wearing a floppy wide brimmed hat holding a stick walking through the forest, animated, three-quarter view, painting"
- Semilla: 312687592
- Iteraciones: 20
Imagen generada: