La tâche du générateur d'images MediaPipe vous permet de générer des images à partir d'une requête textuelle. Cette tâche utilise un modèle texte-vers-image pour générer des images à l'aide de techniques de diffusion.
La tâche accepte une requête textuelle en entrée, ainsi qu'une image de condition facultative que le modèle peut augmenter et utiliser comme référence pour la génération. Le générateur d'images peut également générer des images en fonction de concepts spécifiques fournis au modèle lors de l'entraînement ou du réentraînement. Pour en savoir plus, consultez Personnaliser avec LoRA.
L'exemple de code décrit dans ces instructions est disponible sur GitHub. Pour en savoir plus sur les fonctionnalités, les modèles et les options de configuration de cette tâche, consultez la section Présentation.
Exemple de code
L'exemple de code MediaPipe Tasks est une implémentation de base d'une application de générateur d'images pour Android. Vous pouvez utiliser l'application comme point de départ pour votre propre application Android ou vous y référer lorsque vous modifiez une application existante. L'exemple de code de l'image Generator est hébergé sur GitHub.
Télécharger le code
Les instructions suivantes vous expliquent comment créer une copie locale de l'exemple de code à l'aide de l'outil de ligne de commande git.
Pour télécharger l'exemple de code:
- Clonez le dépôt Git à l'aide de la commande suivante :
git clone https://github.com/google-ai-edge/mediapipe-samples
- Vous pouvez éventuellement configurer votre instance git pour qu'elle utilise un "checkout" clairsemé afin que vous n'ayez que les fichiers de l'application exemple Image Generator :
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_generation/android
Après avoir créé une version locale de l'exemple de code, vous pouvez importer le projet dans Android Studio et exécuter l'application. Pour obtenir des instructions, consultez le guide de configuration pour Android.
Composants clés
Les fichiers suivants contiennent le code essentiel de cet exemple d'application de génération d'images:
- ImageGenerationHelper.kt : initialise la tâche et gère la génération d'images.
- DiffusionActivity.kt : génère des images lorsque les plug-ins ou les poids LoRA ne sont pas activés.
- PluginActivity.kt : implémente les modèles de plug-in, ce qui permet aux utilisateurs de fournir une image de condition en entrée.
- LoRAWeightActivity.kt : accède aux poids LoRA et les gère, qui sont utilisés pour personnaliser les modèles de base et leur permettre de générer des images de concepts spécifiques.
Configuration
Cette section décrit les étapes clés à suivre pour configurer votre environnement de développement et vos projets de code spécifiquement pour utiliser Image Generator. Pour obtenir des informations générales sur la configuration de votre environnement de développement pour utiliser les tâches MediaPipe, y compris les exigences concernant les versions de la plate-forme, consultez le guide de configuration pour Android.
Dépendances
La tâche Image Generator utilise la bibliothèque com.google.mediapipe:tasks-vision-image-generator
. Ajoutez cette dépendance au fichier build.gradle
de votre application Android:
dependencies {
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
}
Pour les appareils équipés d'Android 12 (API 31) ou version ultérieure, ajoutez la dépendance de la bibliothèque OpenCL native. Pour en savoir plus, consultez la documentation sur la balise uses-native-library
.
Ajoutez les balises uses-native-library
suivantes au fichier 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" />
Modèle
La tâche du générateur d'images MediaPipe nécessite un modèle de base entraîné compatible avec cette tâche. Après avoir téléchargé un modèle, installez les dépendances requises et convertissez-le dans un format approprié. Transmettez ensuite le modèle converti vers l'appareil Android.
Pour en savoir plus sur les modèles entraînés disponibles pour Image Generator, consultez la section Modèles de la présentation de la tâche.
Télécharger le modèle de fondation
Le générateur d'images exige que le modèle de base corresponde au format de modèle runwayml/stable-diffusion-v1-5 EMA-only
, basé sur le modèle suivant : runwayml/stable-diffusion-v1-5.
Installer les dépendances et convertir le modèle
$ pip install torch typing_extensions numpy Pillow requests pytorch_lightning absl-py
Exécutez le script convert.py
:
$ python3 convert.py --ckpt_path <ckpt_path> --output_path <output_path>
Transférer le modèle converti sur l'appareil
Transférez le contenu du dossier <output_path>
sur l'appareil 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
Télécharger des modèles de plug-in et ajouter des poids LoRA (facultatif)
Si vous prévoyez d'utiliser un modèle de plug-in, vérifiez si le modèle doit être téléchargé. Pour les plug-ins qui nécessitent un modèle supplémentaire, les modèles de plug-in doivent être groupés dans l'APK ou téléchargés à la demande. Les modèles de plug-in sont légers (environ 23 Mo) et peuvent être groupés directement dans l'APK. Toutefois, nous vous recommandons de télécharger les modèles de plug-in à la demande.
Si vous avez personnalisé un modèle avec LoRA, téléchargez-le à la demande. Pour en savoir plus, consultez le modèle de plug-in des poids LoRA.
Créer la tâche
La tâche du générateur d'images MediaPipe utilise la fonction createFromOptions()
pour configurer la tâche. La fonction createFromOptions()
accepte des valeurs pour les options de configuration. Pour en savoir plus sur les options de configuration, consultez la section Options de configuration.
Options de configuration
Cette tâche propose les options de configuration suivantes pour les applications Android:
Nom de l'option | Description | Plage de valeurs |
---|---|---|
imageGeneratorModelDirectory |
Répertoire du modèle de générateur d'images qui stocke les poids du modèle. | PATH |
loraWeightsFilePath |
Définit le chemin d'accès au fichier de poids LoRA. Facultatif et ne s'applique que si le modèle a été personnalisé avec LoRA. | PATH |
errorListener |
Définit un écouteur d'erreur facultatif. | N/A |
La tâche est également compatible avec les modèles de plug-in, ce qui permet aux utilisateurs d'inclure des images de condition dans l'entrée de la tâche, que le modèle de fondation peut augmenter et utiliser comme référence pour la génération. Ces images de condition peuvent être des repères faciaux, des contours de bord et des estimations de profondeur, que le modèle utilise comme contexte et informations supplémentaires pour générer des images.
Lorsque vous ajoutez un modèle de plug-in au modèle de base, configurez également les options du plug-in. Le plug-in de repères du visage utilise faceConditionOptions
, le plug-in de bordure Canny utilise edgeConditionOptions
et le plug-in de profondeur utilise depthConditionOptions
.
Options de Canny
Configurez les options suivantes dans edgeConditionOptions
.
Nom de l'option | Description | Plage de valeurs | Valeur par défaut |
---|---|---|---|
threshold1 |
Premier seuil de la procédure d'hystérésis. | Float |
100 |
threshold2 |
Deuxième seuil pour la procédure d'hystérésis. | Float |
200 |
apertureSize |
Taille de l'ouverture pour l'opérateur Sobel. La plage habituelle est comprise entre 3 et 7. | Integer |
3 |
l2Gradient |
Indique si la norme L2 est utilisée pour calculer l'amplitude du gradient d'image au lieu de la norme L1 par défaut. | BOOLEAN |
False |
EdgePluginModelBaseOptions |
Objet BaseOptions qui définit le chemin d'accès au modèle du plug-in. |
Objet BaseOptions |
N/A |
Pour en savoir plus sur le fonctionnement de ces options de configuration, consultez la section Détecteur de bords Canny.
Options de points de repère du visage
Configurez les options suivantes dans faceConditionOptions
.
Nom de l'option | Description | Plage de valeurs | Valeur par défaut |
---|---|---|---|
minFaceDetectionConfidence |
Score de confiance minimal pour que la détection de visage soit considérée comme réussie. | Float [0.0,1.0] |
0.5 |
minFacePresenceConfidence |
Score de confiance minimal du score de présence de visage dans la détection des points de repère du visage. | Float [0.0,1.0] |
0.5 |
faceModelBaseOptions |
Objet BaseOptions qui définit le chemin d'accès au modèle qui crée l'image de la condition. |
Objet BaseOptions |
N/A |
FacePluginModelBaseOptions |
Objet BaseOptions qui définit le chemin d'accès au modèle du plug-in. |
Objet BaseOptions |
N/A |
Pour en savoir plus sur le fonctionnement de ces options de configuration, consultez la section Tâche de repère du visage.
Options de profondeur
Configurez les options suivantes dans depthConditionOptions
.
Nom de l'option | Description | Plage de valeurs | Valeur par défaut |
---|---|---|---|
depthModelBaseOptions |
Objet BaseOptions qui définit le chemin d'accès au modèle qui crée l'image de la condition. |
Objet BaseOptions |
N/A |
depthPluginModelBaseOptions |
Objet BaseOptions qui définit le chemin d'accès au modèle du plug-in. |
Objet BaseOptions |
N/A |
Créer uniquement avec le modèle de base
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Créer avec des plug-ins
Si vous appliquez un modèle de plug-in facultatif, définissez les options de base du modèle de plug-in avec setPluginModelBaseOptions
. Si le modèle de plug-in nécessite un modèle téléchargé supplémentaire pour créer l'image de la condition, spécifiez le chemin d'accès dans BaseOptions
.
Point de repère du visage
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)
Profondeur
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)
Créer avec des pondérations LoRA
Si vous incluez des poids LoRA, utilisez le paramètre loraWeightsFilePath
pour indiquer l'emplacement du chemin.
val options = ImageGeneratorOptions.builder()
.setLoraWeightsFilePath(weightsPath)
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Préparer les données
Le générateur d'images accepte les entrées suivantes:
- prompt (obligatoire): requête textuelle décrivant l'image à générer.
- iterations (obligatoire): nombre total d'itérations pour générer l'image. Un bon point de départ est 20.
- seed (obligatoire): graine aléatoire utilisée lors de la génération d'images.
- condition image (facultatif): image utilisée par le modèle comme référence pour la génération. Ne s'applique que lorsque vous utilisez un modèle de plug-in.
- type de condition (facultatif): type de modèle de plug-in utilisé avec la tâche. Ne s'applique que lorsque vous utilisez un modèle de plug-in.
Entrées avec uniquement le modèle de base
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
Saisies avec des plug-ins
Si vous appliquez un modèle de plug-in facultatif, utilisez également le paramètre conditionType
pour choisir le modèle de plug-in et le paramètre sourceConditionImage
pour générer l'image de la condition.
Nom de l'option | Description | Valeur |
---|---|---|
conditionType |
Modèle de plug-in appliqué au modèle de base. | {"FACE", "EDGE", "DEPTH"} |
sourceConditionImage |
Image source utilisée pour créer l'image de la condition. | Objet MPImage |
Si vous utilisez un modèle de plug-in, utilisez createConditionImage
pour créer l'image de la condition:
fun createConditionImage(
inputImage: MPImage,
conditionType: ConditionType
): Bitmap {
val result =
imageGenerator.createConditionImage(inputImage, conditionType)
return BitmapExtractor.extract(result)
}
Après avoir créé l'image de condition, incluez-la en tant qu'entrée avec l'invite, la valeur initiale et le nombre d'itérations.
imageGenerator.setInputs(
prompt,
conditionalImage,
conditionType,
iteration,
seed
)
Entrées avec pondérations LoRA
Si vous utilisez des poids LoRA, assurez-vous que le jeton figure dans la requête textuelle si vous souhaitez générer une image avec le concept spécifique représenté par les poids.
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
Exécuter la tâche
Utilisez la méthode generate()
pour générer une image à l'aide des entrées fournies dans la section précédente. Une seule image est générée.
Générer uniquement avec le modèle 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
}
Générer avec des plug-ins
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
}
Générer avec des pondérations LoRA
Le processus de génération d'images avec un modèle personnalisé avec des poids LoRA est semblable à celui d'un modèle de base standard. Assurez-vous que le jeton est inclus dans l'invite et exécutez le même code.
fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
}
Génération itérative
Le générateur d'images peut également générer les images intermédiaires générées à chaque itération, comme défini dans le paramètre d'entrée iterations
. Pour afficher ces résultats intermédiaires, appelez la méthode setInputs
, puis appelez execute()
pour exécuter chaque étape. Définissez le paramètre showResult
sur true
pour afficher les résultats intermédiaires.
fun execute(showResult: Boolean): Bitmap {
val result = imageGenerator.execute(showResult)
val bitmap =
BitmapExtractor.extract(result.generatedImage())
return bitmap
}
Gérer et afficher les résultats
Le générateur d'images renvoie un ImageGeneratorResult
, qui inclut l'image générée, un code temporel de l'heure de fin et l'image conditionnelle si une telle image a été fournie en entrée.
val bitmap = BitmapExtractor.extract(result.generatedImage())
L'image suivante a été générée à partir des entrées suivantes, en utilisant uniquement un modèle de base.
Entrées :
- Invite: "un raton laveur de dessin animé coloré portant un chapeau à larges bords et tenant un bâton en marchant dans la forêt, animé, vue en trois quarts, peinture"
- Graine: 312687592
- Itérations: 20
Image générée: