Mit der MediaPipe Image Generator-Aufgabe können Sie Bilder auf Grundlage eines Text-Prompts generieren. Bei dieser Aufgabe wird ein Text-zu-Bild-Modell verwendet, um Bilder mithilfe von Diffusionstechniken zu generieren.
Für die Aufgabe wird ein Text-Prompt als Eingabe akzeptiert, zusammen mit einem optionalen Bedingungsbild, das das Modell erweitern und als Referenz für die Generierung verwenden kann. Mit Image Generator können auch Bilder auf Grundlage bestimmter Konzepte generiert werden, die dem Modell während des Trainings oder erneuten Trainings zur Verfügung gestellt wurden. Weitere Informationen finden Sie unter Mit LoRA anpassen.
Das in dieser Anleitung beschriebene Codebeispiel 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 einfache Implementierung einer Image Generator-App für Android. Sie können die App als Ausgangspunkt für Ihre eigene Android-App verwenden oder sich daran orientieren, wenn Sie eine vorhandene App ändern. Der Beispielcode für den Image Generator ist auf GitHub verfügbar.
Code herunterladen
In der folgenden Anleitung wird beschrieben, wie Sie mit dem git-Befehlszeilentool 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 so konfigurieren, dass nur die Dateien für die Beispiel-App „Image Generator“ heruntergeladen werden:
cd mediapipe-samples 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 entscheidenden Code für diese Beispielanwendung zur Bildgenerierung:
- ImageGenerationHelper.kt: Initialisiert die Aufgabe und verarbeitet die Bildgenerierung.
- DiffusionActivity.kt: Generiert Bilder, wenn keine Plug-ins oder LoRA-Gewichtungen aktiviert sind.
- PluginActivity.kt: Implementiert die Plug-in-Modelle, mit denen Nutzer ein Bedingungsbild als Eingabe bereitstellen können.
- LoRAWeightActivity.kt: Greift auf die LoRA-Gewichtungen zu und verarbeitet sie. Diese werden verwendet, um Foundation-Modelle anzupassen und Bilder mit bestimmten Konzepten zu generieren.
Einrichtung
In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten Ihrer Entwicklungsumgebung und Ihrer Codeprojekte für die Verwendung von Image Generator beschrieben. Allgemeine Informationen zum Einrichten Ihrer Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich der Anforderungen an die Plattformversion, finden Sie im Einrichtungshandbuch für Android.
Abhängigkeiten
Für die Aufgabe „Bildgenerator“ wird die com.google.mediapipe:tasks-vision-image-generator-Bibliothek verwendet. Fügen Sie diese Abhängigkeit der Datei build.gradle in Ihrer Android-App 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 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 Image Generator-Aufgabe ist ein trainiertes Foundation Model erforderlich, das mit dieser Aufgabe kompatibel ist. Nach dem Herunterladen eines Modells müssen Sie die erforderlichen Abhängigkeiten installieren und das Modell in ein geeignetes Format konvertieren. Übertragen Sie das konvertierte Modell dann auf das Android-Gerät.
Weitere Informationen zu den verfügbaren trainierten Modellen für Image Generator finden Sie im Abschnitt „Modelle“ der Aufgabenübersicht.
Basismodell herunterladen
Für den Image Generator muss das Foundation Model dem stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only-Modellformat entsprechen, basierend auf dem folgenden Modell: stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only.
Abhängigkeiten installieren und 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 auf das Gerät übertragen
Ü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-Gewichtungen 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. Plugin-Modelle sind klein (~23 MB) und können direkt in das APK eingebunden werden. Wir empfehlen jedoch, Plug-in-Modelle bei Bedarf herunterzuladen.
Wenn Sie ein Modell mit LoRA angepasst haben, können Sie es bei Bedarf herunterladen. Weitere Informationen finden Sie unter LoRA-Gewichte.
Aufgabe erstellen
Für die MediaPipe Image Generator-Aufgabe 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 Android-Apps stehen für diese Aufgabe die folgenden Konfigurationsoptionen zur Verfügung:
| Option | Beschreibung | Wertebereich |
|---|---|---|
imageGeneratorModelDirectory |
Das Verzeichnis des Bildgenerierungsmodells, in dem die Modellgewichte gespeichert werden. | PATH |
loraWeightsFilePath |
Legt den Pfad zur LoRA-Gewichtungsdatei 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, sodass Nutzer Bedingungsbilder in die Aufgabeneingabe einfügen können, die das Fundamentmodell erweitern und als Referenz für die Generierung verwenden kann. Diese Bedingungsbilder können Gesichtsmerkmale, Kantenkonturen und Tiefenschätzungen sein, die das Modell als zusätzlichen Kontext und zusätzliche Informationen zum Generieren von Bildern verwendet.
Wenn Sie dem Foundation Model ein Plug-in-Modell hinzufügen, konfigurieren Sie auch die Plug-in-Optionen. Das Plug-in „Gesichtsmerkmale“ verwendet faceConditionOptions, das Plug-in „Canny Edge“ edgeConditionOptions und das Plug-in „Tiefe“ depthConditionOptions.
Optionen für Canny Edge
Konfigurieren Sie die folgenden Optionen in edgeConditionOptions.
| Option | Beschreibung | Wertebereich | Standardwert |
|---|---|---|---|
threshold1 |
Erster Schwellenwert für das Hystereseverfahren. | Float |
100 |
threshold2 |
Zweiter Schwellenwert für das Hystereseverfahren. | Float |
200 |
apertureSize |
Blendenöffnung 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 verwendet wird, um die Bildgradientenmagnitude zu berechnen. | BOOLEAN |
False |
EdgePluginModelBaseOptions |
Das BaseOptions-Objekt, das den Pfad für das Plugin-Modell festlegt. |
BaseOptions Objekt |
N/A |
Weitere Informationen zur Funktionsweise dieser Konfigurationsoptionen finden Sie unter Canny-Kantendetektor.
Optionen für Gesichts-Landmarks
Konfigurieren Sie die folgenden Optionen in faceConditionOptions.
| Option | Beschreibung | Wertebereich | Standardwert |
|---|---|---|---|
minFaceDetectionConfidence |
Der Mindestkonfidenzwert, damit die Gesichtserkennung als erfolgreich gilt. | Float [0.0,1.0] |
0.5 |
minFacePresenceConfidence |
Der minimale Konfidenzwert für die Gesichtserkennung bei der Erkennung von Gesichts-Landmarks. | Float [0.0,1.0] |
0.5 |
faceModelBaseOptions |
Das BaseOptions-Objekt, mit dem der Pfad für das Modell festgelegt wird, das das Bedingungsbild erstellt. |
BaseOptions Objekt |
N/A |
FacePluginModelBaseOptions |
Das BaseOptions-Objekt, das den Pfad für das Plugin-Modell festlegt. |
BaseOptions Objekt |
N/A |
Weitere Informationen zur Funktionsweise dieser Konfigurationsoptionen finden Sie unter Face Landmarker-Aufgabe.
Tiefenoptionen
Konfigurieren Sie die folgenden Optionen in depthConditionOptions.
| Option | Beschreibung | Wertebereich | Standardwert |
|---|---|---|---|
depthModelBaseOptions |
Das BaseOptions-Objekt, mit dem der Pfad für das Modell festgelegt wird, das das Bedingungsbild erstellt. |
BaseOptions Objekt |
N/A |
depthPluginModelBaseOptions |
Das BaseOptions-Objekt, das den Pfad für das Plugin-Modell festlegt. |
BaseOptions Objekt |
N/A |
Nur mit dem Basismodell erstellen
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Plug‑ins verwenden
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ätzlich heruntergeladenes Modell zum Erstellen des Bedingungsbilds 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 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)
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)
Inhalte mit LoRA-Gewichten erstellen
Wenn Sie LoRA-Gewichtungen einbeziehen, verwenden Sie den Parameter loraWeightsFilePath, um auf den Pfad 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 Bildes. Ein guter Ausgangspunkt ist 20.
- seed (erforderlich): Der zufällige Startwert, 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 mit der Aufgabe verwendeten Plug-in-Modells. Gilt nur, wenn ein Plug-in-Modell verwendet wird.
Eingaben nur mit dem Foundation Model
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 Bedingungsbild zu generieren.
| Option | Beschreibung | Wert |
|---|---|---|
conditionType |
Das auf das Fundamentmodell angewendete Plug-in-Modell. | {"FACE", "EDGE", "DEPTH"} |
sourceConditionImage |
Das Quellbild, das zum Erstellen des Bedingungsbildes 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, fügen Sie es zusammen mit dem Prompt, dem Seed und der Anzahl der Iterationen als Eingabe hinzu.
imageGenerator.setInputs(
prompt,
conditionalImage,
conditionType,
iteration,
seed
)
Eingaben mit LoRA-Gewichten
Wenn Sie LoRA-Gewichtungen verwenden, muss das Token im Text-Prompt enthalten sein, wenn Sie ein Bild mit dem spezifischen Konzept generieren möchten, das durch die Gewichtungen dargestellt wird.
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 angegebenen Eingaben zu generieren. Dadurch wird ein einzelnes generiertes Bild erstellt.
Nur mit dem Foundation Model 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 Image Generator kann auch die generierten Zwischenbilder während jeder Iteration ausgeben, wie im Eingabeparameter iterations definiert. Wenn Sie diese Zwischenergebnisse aufrufen möchten, rufen Sie die Methode setInputs und dann execute() auf, um jeden Schritt auszuführen. Setzen Sie den Parameter showResult auf true, um die 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 Image Generator gibt ein ImageGeneratorResult zurück, das das generierte Bild, einen Zeitstempel für den Zeitpunkt des Abschlusses und das bedingte Bild enthält, sofern es als Eingabe bereitgestellt wurde.
val bitmap = BitmapExtractor.extract(result.generatedImage())
Das folgende Bild wurde mit den folgenden Eingaben und nur einem Fundierungsmodell generiert.
Eingaben:
- Prompt: „Ein bunter Cartoon-Waschbär mit einem Schlapphut mit breiter Krempe, der einen Stock hält und durch den Wald geht, animiert, Dreiviertelansicht, Gemälde“
- Seed: 312687592
- Iterationen: 20
Generiertes Bild: