Mit der Aufgabe „MediaPipe Image Generator“ können Sie Bilder anhand eines Text-Prompts generieren. Bei dieser Aufgabe werden mithilfe eines Text-zu-Bild-Modells Bilder mithilfe von Diffusionstechniken generiert.
Die Aufgabe nimmt einen Textprompt als Eingabe sowie ein optionales Bedingungsbild entgegen, das das Modell ergänzen und als Referenz für die Generierung verwenden kann. Der Bildgenerator kann auch Bilder basierend auf bestimmten Konzepten generieren, die dem Modell während des Trainings oder der Umschulung zur Verfügung gestellt wurden. Weitere Informationen finden Sie unter Mit LoRA anpassen.
Der in dieser Anleitung beschriebene Code ist auf GitHub verfügbar. Weitere Informationen zu den Funktionen, Modellen und Konfigurationsoptionen dieser Aufgabe finden Sie in der Übersicht.
Codebeispiel
Der Beispielcode für MediaPipe Tasks ist eine grundlegende Implementierung einer Bildgenerator-App für Android. Sie können die App als Ausgangspunkt für Ihre eigene Android-App verwenden oder sich an ihr orientieren, wenn Sie eine vorhandene App ändern. Der Beispielcode für den Bildgenerator wird auf GitHub gehostet.
Code herunterladen
In der folgenden Anleitung wird beschrieben, wie Sie mit dem Befehlszeilentool git eine lokale Kopie des Beispielcodes erstellen.
So laden Sie den Beispielcode herunter:
- Klonen Sie das Git-Repository mit dem folgenden Befehl:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Optional können Sie Ihre Git-Instanz für die Verwendung einer spärlichen Überprüfung konfigurieren, sodass nur die Dateien für die Beispielanwendung „Image Generator“ vorhanden sind:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_generation/android
Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie das Projekt in Android Studio importieren und die App ausführen. Eine Anleitung dazu finden Sie im Einrichtungsleitfaden für Android.
Schlüsselkomponenten
Die folgenden Dateien enthalten den wichtigsten Code für diese Beispielanwendung zur Bildgenerierung:
- ImageGenerationHelper.kt: Hier wird die Aufgabe initialisiert und die Bildgenerierung verwaltet.
- DiffusionActivity.kt: Erzeugt Bilder, wenn Plug-ins oder LoRA-Gewichte nicht aktiviert sind.
- PluginActivity.kt: Implementiert die Plug-in-Modelle, mit denen Nutzer ein Bedingungsbild als Eingabe angeben können.
- LoRAWeightActivity.kt: Hier werden die LoRA-Gewichte abgerufen und verarbeitet, mit denen Basismodelle angepasst und Bilder bestimmter Konzepte generiert werden können.
Einrichtung
In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten Ihrer Entwicklungsumgebung und Codeprojekte beschrieben, die speziell für die Verwendung des Bildgenerators vorgesehen sind. Allgemeine Informationen zum Einrichten Ihrer Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich Anforderungen an die Plattformversion, finden Sie im Einrichtungsleitfaden für Android.
Abhängigkeiten
Für die Aufgabe „Bildgenerator“ wird die com.google.mediapipe:tasks-vision-image-generator
-Bibliothek verwendet. Fügen Sie der Datei build.gradle
Ihrer Android-App diese Abhängigkeit hinzu:
dependencies {
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
}
Fügen Sie für Geräte mit Android 12 (API 31) oder höher die Abhängigkeit von der nativen OpenCL-Bibliothek hinzu. Weitere Informationen finden Sie in der Dokumentation zum Tag uses-native-library
.
Fügen Sie der Datei AndroidManifest.xml
die folgenden uses-native-library
-Tags hinzu:
<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" />
Modell
Für die MediaPipe-Aufgabe „Bildgenerator“ ist ein trainiertes Basismodell erforderlich, das mit dieser Aufgabe kompatibel ist. Nachdem Sie ein Modell heruntergeladen haben, installieren Sie die erforderlichen Abhängigkeiten und konvertieren Sie das Modell in ein geeignetes Format. Übertragen Sie dann das konvertierte Modell auf das Android-Gerät.
Weitere Informationen zu verfügbaren trainierten Modellen für den Bildgenerator finden Sie in der Aufgabenübersicht im Abschnitt „Modelle“.
Basismodell herunterladen
Der Bildgenerator erfordert, dass das Basismodell dem runwayml/stable-diffusion-v1-5 EMA-only
-Modellformat entspricht, das auf dem folgenden Modell basiert: runwayml/stable-diffusion-v1-5.
Abhängigkeiten installieren und das Modell konvertieren
$ pip install torch typing_extensions numpy Pillow requests pytorch_lightning absl-py
Führen Sie das Skript convert.py
aus:
$ python3 convert.py --ckpt_path <ckpt_path> --output_path <output_path>
Konvertiertes Modell an das Gerät senden
Übertragen Sie den Inhalt des Ordners <output_path>
auf das Android-Gerät.
$ 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
Plug-in-Modelle herunterladen und LoRA-Gewichte hinzufügen (optional)
Wenn Sie ein Plug-in-Modell verwenden möchten, prüfen Sie, ob das Modell heruntergeladen werden muss. Bei Plug-ins, für die ein zusätzliches Modell erforderlich ist, müssen die Plug-in-Modelle entweder im APK gebündelt oder bei Bedarf heruntergeladen werden. Plug-in-Modelle sind klein (~23 MB) und können direkt im APK gebündelt werden. Wir empfehlen jedoch, Plug-in-Modelle bei Bedarf herunterzuladen.
Wenn Sie ein Modell mit LoRA angepasst haben, können Sie es auf Anfrage herunterladen. Weitere Informationen finden Sie im Plug-in-Modell für LoRA-Gewichte.
Aufgabe erstellen
Für die Aufgabe „MediaPipe Image Generator“ wird die Funktion createFromOptions()
verwendet, um die Aufgabe einzurichten. Die Funktion createFromOptions()
akzeptiert Werte für die Konfigurationsoptionen. Weitere Informationen zu Konfigurationsoptionen finden Sie unter Konfigurationsoptionen.
Konfigurationsoptionen
Für diese Aufgabe sind die folgenden Konfigurationsoptionen für Android-Apps verfügbar:
Option | Beschreibung | Wertebereich |
---|---|---|
imageGeneratorModelDirectory |
Das Modellverzeichnis des Bildgenerators, in dem die Modellgewichte gespeichert werden. | PATH |
loraWeightsFilePath |
Legt den Pfad zur LoRA-Gewichtsdatei fest. Optional und nur anwendbar, wenn das Modell mit LoRA angepasst wurde. | PATH |
errorListener |
Legt einen optionalen Fehler-Listener fest. | N/A |
Die Aufgabe unterstützt auch Plug-in-Modelle, mit denen Nutzer Bedingungsbilder in die Aufgabeneingabe einfügen können, die das Basismodell ergänzen und als Referenz für die Generierung verwenden kann. Diese Anhaltspunkte können Gesichtsmerkmale, Kantenkonturen und Tiefenschätzungen sein, die das Modell als zusätzlichen Kontext und Informationen zum Generieren von Bildern verwendet.
Wenn Sie dem Foundation-Modell ein Plug-in-Modell hinzufügen, konfigurieren Sie auch die Plug-in-Optionen. Für das Plug-in für Gesichtsmarkierungen wird faceConditionOptions
, für das Canny-Eckpunkt-Plug-in edgeConditionOptions
und für das Tiefen-Plug-in depthConditionOptions
verwendet.
Canny-Edge-Optionen
Konfigurieren Sie in edgeConditionOptions
die folgenden Optionen.
Option | Beschreibung | Wertebereich | Standardwert |
---|---|---|---|
threshold1 |
Erster Grenzwert für das Hystereseverfahren. | Float |
100 |
threshold2 |
Zweiter Grenzwert für das Hystereseverfahren. | Float |
200 |
apertureSize |
Blendengröße für den Sobel-Operator. Der typische Bereich liegt zwischen 3 und 7. | Integer |
3 |
l2Gradient |
Gibt an, ob die L2-Norm anstelle der Standard-L1-Norm zum Berechnen der Bildgradientenmagnitude verwendet wird. | BOOLEAN |
False |
EdgePluginModelBaseOptions |
Das BaseOptions -Objekt, das den Pfad für das Plug-in-Modell festlegt. |
BaseOptions Objekt |
N/A |
Weitere Informationen zur Funktionsweise dieser Konfigurationsoptionen finden Sie unter Canny-Kantenerkennung.
Optionen für Gesichts-Landmarks
Konfigurieren Sie die folgenden Optionen in faceConditionOptions
.
Option | Beschreibung | Wertebereich | Standardwert |
---|---|---|---|
minFaceDetectionConfidence |
Der Mindestwert für die Konfidenz, damit die Gesichtserkennung als erfolgreich gilt. | Float [0.0,1.0] |
0.5 |
minFacePresenceConfidence |
Die minimale Konfidenz der Punktzahl für die Gesichtspräsenz bei der Gesichts-Landmark-Erkennung. | Float [0.0,1.0] |
0.5 |
faceModelBaseOptions |
Das BaseOptions -Objekt, das den Pfad für das Modell festlegt, das das Zustandsbild erstellt. |
BaseOptions Objekt |
N/A |
FacePluginModelBaseOptions |
Das BaseOptions -Objekt, das den Pfad für das Plug-in-Modell festlegt. |
BaseOptions Objekt |
N/A |
Weitere Informationen zur Funktionsweise dieser Konfigurationsoptionen finden Sie unter Aufgabe „Gesichtsmarkierungen“.
Optionen für die Tiefe
Konfigurieren Sie in depthConditionOptions
die folgenden Optionen.
Option | Beschreibung | Wertebereich | Standardwert |
---|---|---|---|
depthModelBaseOptions |
Das BaseOptions -Objekt, das den Pfad für das Modell festlegt, das das Zustandsbild erstellt. |
BaseOptions Objekt |
N/A |
depthPluginModelBaseOptions |
Das BaseOptions -Objekt, das den Pfad für das Plug-in-Modell festlegt. |
BaseOptions Objekt |
N/A |
Nur mit dem Foundation Model erstellen
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Mit Plug-ins erstellen
Wenn Sie ein optionales Plug-in-Modell anwenden, legen Sie die Basisoptionen für das Plug-in-Modell mit setPluginModelBaseOptions
fest. Wenn für das Plug-in-Modell ein zusätzliches heruntergeladenes Modell zum Erstellen des Zustandsbilds erforderlich ist, geben Sie den Pfad in BaseOptions
an.
Gesichts-Landmark
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-Effekt
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)
Tiefe
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)
Mit LoRA-Gewichten erstellen
Wenn Sie LoRA-Gewichte angeben, verwenden Sie den Parameter loraWeightsFilePath
, um auf den Pfadstandort zu verweisen.
val options = ImageGeneratorOptions.builder()
.setLoraWeightsFilePath(weightsPath)
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Daten vorbereiten
Der Bildgenerator akzeptiert die folgenden Eingaben:
- prompt (erforderlich): Der Text-Prompt, der das zu generierende Bild beschreibt.
- iterations (erforderlich): Die Gesamtzahl der Iterationen zum Generieren des Bilds. 20 ist ein guter Ausgangspunkt.
- seed (erforderlich): Der Zufallszahlengenerator, der bei der Bildgenerierung verwendet wird.
- condition image (optional): Das Bild, das das Modell als Referenz für die Generierung verwendet. Gilt nur, wenn ein Plug-in-Modell verwendet wird.
- condition type (optional): Der Typ des Plug-in-Modells, das für die Aufgabe verwendet wird. Gilt nur, wenn ein Plug-in-Modell verwendet wird.
Eingaben mit nur dem Basismodell
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
Eingaben mit Plug-ins
Wenn Sie ein optionales Plug-in-Modell anwenden, verwenden Sie auch den Parameter conditionType
, um das Plug-in-Modell auszuwählen, und den Parameter sourceConditionImage
, um das Zustandsbild zu generieren.
Option | Beschreibung | Wert |
---|---|---|
conditionType |
Das Plug-in-Modell, das auf das Fundamentmodell angewendet wird. | {"FACE", "EDGE", "DEPTH"} |
sourceConditionImage |
Das Quellbild, das zum Erstellen des Zustandsbilds verwendet wurde. | MPImage Objekt |
Wenn Sie ein Plug-in-Modell verwenden, erstellen Sie das Bedingungsbild mit createConditionImage
:
fun createConditionImage(
inputImage: MPImage,
conditionType: ConditionType
): Bitmap {
val result =
imageGenerator.createConditionImage(inputImage, conditionType)
return BitmapExtractor.extract(result)
}
Nachdem Sie das Bedingungsbild erstellt haben, geben Sie es zusammen mit dem Prompt, dem Seed und der Anzahl der Iterationen als Eingabe an.
imageGenerator.setInputs(
prompt,
conditionalImage,
conditionType,
iteration,
seed
)
Eingaben mit LoRA-Gewichten
Wenn Sie LoRA-Gewichte verwenden, muss das Token im Text-Prompt enthalten sein, wenn Sie ein Bild mit dem durch die Gewichte dargestellten Konzept generieren möchten.
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
Aufgabe ausführen
Verwenden Sie die Methode generate()
, um ein Bild mit den im vorherigen Abschnitt bereitgestellten Eingaben zu generieren. Dadurch wird ein einzelnes generiertes Bild erstellt.
Nur mit dem Basismodell generieren
fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
}
Mit Plug-ins generieren
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
}
Mit LoRA-Gewichten generieren
Das Generieren von Bildern mit einem Modell, das mit LoRA-Gewichten angepasst wurde, ähnelt dem Prozess mit einem Standard-Fundamentmodell. Achten Sie darauf, dass das Token im Prompt enthalten ist, und führen Sie denselben Code aus.
fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
}
Iterative Generierung
Der Bildgenerator kann die generierten Zwischenbilder auch während jeder Iteration ausgeben, wie im Eingabeparameter iterations
definiert. Wenn Sie diese Zwischenergebnisse sehen möchten, rufen Sie die Methode setInputs
und dann execute()
auf, um die einzelnen Schritte auszuführen. Legen Sie den Parameter showResult
auf true
fest, um Zwischenergebnisse anzuzeigen.
fun execute(showResult: Boolean): Bitmap {
val result = imageGenerator.execute(showResult)
val bitmap =
BitmapExtractor.extract(result.generatedImage())
return bitmap
}
Ergebnisse verarbeiten und anzeigen
Der Bildgenerator gibt einen ImageGeneratorResult
zurück, der das generierte Bild, einen Zeitstempel für den Zeitpunkt des Abschlusses und das bedingte Bild enthält, falls eines als Eingabe angegeben wurde.
val bitmap = BitmapExtractor.extract(result.generatedImage())
Das folgende Bild wurde mit den folgenden Eingaben und nur einem Basismodell generiert.
Eingaben:
- Prompt: „Ein farbenfroher Cartoon-Racoon mit einem breiten Schlapphut, der einen Stock hält und durch den Wald geht, animiert, Dreiviertelprofil, Malerei“
- Seed: 312687592
- Iterationen: 20
Generiertes Bild