Zadanie MediaPipe Image Generator umożliwia generowanie obrazów na podstawie prompta tekstowego. To zadanie wykorzystuje model zamiany tekstu na obraz do generowania obrazów za pomocą technik dyfuzji.
Zadanie przyjmuje jako dane wejściowe prompt tekstowy oraz opcjonalny obraz warunkowy, który model może rozszerzyć i użyć jako odniesienia do generowania. Generator obrazów może też generować obrazy na podstawie konkretnych koncepcji dostarczonych do modelu podczas trenowania lub ponownego trenowania. Więcej informacji znajdziesz w artykule Dostosowywanie za pomocą LoRA.
Przykładowy kod opisany w tych instrukcjach jest dostępny na GitHub. Więcej informacji o możliwościach, modelach i opcjach konfiguracji tego zadania znajdziesz w tym artykule.
Przykładowy kod
Przykładowy kod MediaPipe Tasks to podstawowe wdrożenie aplikacji Image Generator na Androida. Możesz użyć tej aplikacji jako punktu wyjścia do utworzenia własnej aplikacji na Androida lub skorzystać z niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod generatora obrazów jest hostowany na GitHub.
Pobieranie kodu
Z poniższych instrukcji dowiesz się, jak utworzyć lokalną kopię przykładowego kodu za pomocą narzędzia wiersza poleceń git.
Aby pobrać przykładowy kod:
- Sklonuj repozytorium Git za pomocą tego polecenia:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Opcjonalnie możesz skonfigurować instancję Git, aby używać rzadkiego wyewidencjonowania, dzięki czemu będziesz mieć tylko pliki przykładowej aplikacji Image Generator:
cd mediapipe-samples git sparse-checkout init --cone git sparse-checkout set examples/image_generation/android
Po utworzeniu lokalnej wersji przykładowego kodu możesz zaimportować projekt do Androida Studio i uruchomić aplikację. Instrukcje znajdziesz w przewodniku po konfiguracji na Androida.
Kluczowe komponenty
Te pliki zawierają kluczowy kod dla tej przykładowej aplikacji do generowania obrazów:
- ImageGenerationHelper.kt: Inicjuje zadanie i obsługuje generowanie obrazu.
- DiffusionActivity.kt: Generuje obrazy, gdy wtyczki lub wagi LoRA nie są włączone.
- PluginActivity.kt Implementuje modele wtyczek, które umożliwiają użytkownikom podanie obrazu warunkowego jako danych wejściowych.
- LoRAWeightActivity.kt: Dostęp do wag LoRA i ich obsługa. Wagi te służą do dostosowywania modeli podstawowych i umożliwiają generowanie obrazów przedstawiających określone koncepcje.
Konfiguracja
W tej sekcji opisujemy najważniejsze kroki, które należy wykonać, aby skonfigurować środowisko programistyczne i projekty kodu do korzystania z Generatora obrazów. Ogólne informacje o konfigurowaniu środowiska programistycznego do korzystania z zadań MediaPipe, w tym wymagania dotyczące wersji platformy, znajdziesz w przewodniku konfiguracji na Androida.
Zależności
Zadanie Generator obrazów korzysta z biblioteki com.google.mediapipe:tasks-vision-image-generator. Dodaj tę zależność do pliku build.gradle w aplikacji na Androida:
dependencies {
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
}
W przypadku urządzeń z Androidem 12 (API 31) lub nowszym dodaj zależność od natywnej biblioteki OpenCL. Więcej informacji znajdziesz w dokumentacji dotyczącej tagu
uses-native-library.
Dodaj do pliku AndroidManifest.xml te tagi uses-native-library:
<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" />
Model
Zadanie MediaPipe Image Generator wymaga wytrenowanego modelu podstawowego, który jest z nim zgodny. Po pobraniu modelu zainstaluj wymagane zależności i przekonwertuj model do odpowiedniego formatu. Następnie przenieś przekonwertowany model na urządzenie z Androidem.
Więcej informacji o dostępnych wytrenowanych modelach Generatora obrazów znajdziesz w sekcji Modele w omówieniu zadania.
Pobieranie modelu podstawowego
Generator obrazów wymaga, aby model podstawowy był zgodny z formatem modelu stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only, na podstawie tego modelu: stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only.
Instalowanie zależności i konwertowanie modelu
$ pip install torch typing_extensions numpy Pillow requests pytorch_lightning absl-py
Uruchom skrypt
convert.py:
$ python3 convert.py --ckpt_path <ckpt_path> --output_path <output_path>
Przekazywanie przekonwertowanego modelu na urządzenie
Przekaż zawartość folderu <output_path> na urządzenie z Androidem.
$ 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
Pobieranie modeli wtyczek i dodawanie wag LoRA (opcjonalnie)
Jeśli zamierzasz używać modelu wtyczki, sprawdź, czy model musi zostać pobrany. W przypadku wtyczek, które wymagają dodatkowego modelu, modele wtyczek muszą być dołączone do pliku APK lub pobierane na żądanie. Modele wtyczek są lekkie (ok. 23 MB) i można je dołączyć bezpośrednio do pliku APK. Zalecamy jednak pobieranie modeli wtyczek na żądanie.
Jeśli masz model dostosowany za pomocą LoRA, możesz pobrać go na żądanie. Więcej informacji znajdziesz w artykule Wagi LoRA modelu wtyczki.
Tworzenie zadania
Zadanie MediaPipe Image Generator używa funkcji createFromOptions() do skonfigurowania zadania. Funkcja createFromOptions() akceptuje wartości opcji konfiguracji. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Opcje konfiguracji.
Opcje konfiguracji
To zadanie ma te opcje konfiguracji w przypadku aplikacji na Androida:
| Nazwa opcji | Opis | Zakres wartości |
|---|---|---|
imageGeneratorModelDirectory |
Katalog modelu generatora obrazów, w którym są przechowywane wagi modelu. | PATH |
loraWeightsFilePath |
Ustawia ścieżkę do pliku wag LoRA. Opcjonalne i ma zastosowanie tylko wtedy, gdy model został dostosowany za pomocą LoRA. | PATH |
errorListener |
Ustawia opcjonalny odbiornik błędów. | N/A |
Zadanie obsługuje też modele wtyczek, które umożliwiają użytkownikom dodawanie do danych wejściowych obrazów warunkowych, które model podstawowy może rozszerzać i wykorzystywać jako odniesienie do generowania. Obrazy warunków mogą zawierać punkty orientacyjne twarzy, kontury krawędzi i szacunki głębi, które model wykorzystuje jako dodatkowy kontekst i informacje do generowania obrazów.
Gdy dodajesz model wtyczki do modelu podstawowego, skonfiguruj też opcje wtyczki. Wtyczka Face landmark używa faceConditionOptions, wtyczka Canny edge używa edgeConditionOptions, a wtyczka Depth używa depthConditionOptions.
Opcje wykrywania krawędzi metodą Canny
Skonfiguruj te opcje w edgeConditionOptions.
| Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
|---|---|---|---|
threshold1 |
Pierwszy próg procedury histerezy. | Float |
100 |
threshold2 |
Drugi próg procedury histerezy. | Float |
200 |
apertureSize |
Rozmiar przysłony operatora Sobela. Typowy zakres to 3–7. | Integer |
3 |
l2Gradient |
Określa, czy do obliczania wielkości gradientu obrazu ma być używana norma L2 zamiast domyślnej normy L1. | BOOLEAN |
False |
EdgePluginModelBaseOptions |
Obiekt BaseOptions, który ustawia ścieżkę
dla modelu wtyczki. |
BaseOptions obiekt |
N/A |
Więcej informacji o działaniu tych opcji konfiguracji znajdziesz w artykule Wykrywacz krawędzi Canny’ego.
Opcje punktów charakterystycznych twarzy
Skonfiguruj te opcje w faceConditionOptions.
| Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
|---|---|---|---|
minFaceDetectionConfidence |
Minimalny poziom ufności, przy którym wykrywanie twarzy jest uznawane za udane. | Float [0.0,1.0] |
0.5 |
minFacePresenceConfidence |
Minimalny poziom ufności wykrycia twarzy. | Float [0.0,1.0] |
0.5 |
faceModelBaseOptions |
Obiekt BaseOptions, który ustawia ścieżkę
dla modelu tworzącego obraz warunkowy. |
BaseOptions obiekt |
N/A |
FacePluginModelBaseOptions |
Obiekt BaseOptions, który ustawia ścieżkę
dla modelu wtyczki. |
BaseOptions obiekt |
N/A |
Więcej informacji o działaniu tych opcji konfiguracji znajdziesz w sekcji Zadanie Face Landmarker.
Opcje głębi
Skonfiguruj te opcje w depthConditionOptions.
| Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
|---|---|---|---|
depthModelBaseOptions |
Obiekt BaseOptions, który ustawia ścieżkę
dla modelu tworzącego obraz warunkowy. |
BaseOptions obiekt |
N/A |
depthPluginModelBaseOptions |
Obiekt BaseOptions, który ustawia ścieżkę
dla modelu wtyczki. |
BaseOptions obiekt |
N/A |
Tworzenie tylko za pomocą modelu podstawowego
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Tworzenie za pomocą wtyczek
Jeśli stosujesz opcjonalny model wtyczki, ustaw podstawowe opcje modelu wtyczki za pomocą setPluginModelBaseOptions. Jeśli model wtyczki wymaga dodatkowego pobranego modelu do utworzenia obrazu warunku, określ ścieżkę w BaseOptions.
Punkt orientacyjny twarzy
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)
Głębokość
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)
Tworzenie z wagami LoRA
Jeśli uwzględniasz wagi LoRA, użyj parametru loraWeightsFilePath, aby wskazać ścieżkę.
val options = ImageGeneratorOptions.builder()
.setLoraWeightsFilePath(weightsPath)
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Przygotuj dane
Generator obrazów akceptuje te dane wejściowe:
- prompt (wymagany): prompt tekstowy opisujący obraz, który ma zostać wygenerowany.
- iterations (wymagane): łączna liczba iteracji potrzebnych do wygenerowania obrazu. Dobrym punktem wyjścia jest 20.
- seed (wymagane): losowy klucz używany podczas generowania obrazu.
- condition image (opcjonalnie): obraz, którego model używa jako odniesienia do generowania. Ma zastosowanie tylko w przypadku korzystania z modelu wtyczki.
- condition type (opcjonalnie): typ modelu wtyczki używanego w przypadku zadania. Ma zastosowanie tylko w przypadku korzystania z modelu wtyczki.
Dane wejściowe zawierające tylko model podstawowy
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
Wejścia z wtyczkami
Jeśli stosujesz opcjonalny model wtyczki, użyj też parametru conditionType, aby wybrać model wtyczki, oraz parametru sourceConditionImage, aby wygenerować obraz warunkowy.
| Nazwa opcji | Opis | Wartość |
|---|---|---|
conditionType |
Model wtyczki zastosowany do modelu podstawowego. | {"FACE", "EDGE", "DEPTH"} |
sourceConditionImage |
Obraz źródłowy użyty do utworzenia obrazu warunkowego. | MPImage obiekt |
Jeśli używasz modelu wtyczki, użyj createConditionImage, aby utworzyć obraz warunku:
fun createConditionImage(
inputImage: MPImage,
conditionType: ConditionType
): Bitmap {
val result =
imageGenerator.createConditionImage(inputImage, conditionType)
return BitmapExtractor.extract(result)
}
Po utworzeniu obrazu warunkowego uwzględnij go jako dane wejściowe wraz z promptem, wartością ziarna i liczbą iteracji.
imageGenerator.setInputs(
prompt,
conditionalImage,
conditionType,
iteration,
seed
)
Dane wejściowe z wagami LoRA
Jeśli używasz wag LoRA, upewnij się, że token znajduje się w prompcie tekstowym, jeśli chcesz wygenerować obraz z określonym pojęciem reprezentowanym przez wagi.
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
Uruchamianie zadania
Użyj generate(), aby wygenerować obraz na podstawie danych wejściowych podanych w poprzedniej sekcji. W ten sposób powstaje jeden wygenerowany obraz.
Generowanie tylko za pomocą modelu podstawowego
fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
}
Generowanie za pomocą wtyczek
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
}
Generowanie za pomocą wag LoRA
Proces generowania obrazów za pomocą modelu dostosowanego za pomocą wag LoRA jest podobny do procesu z użyciem standardowego modelu podstawowego. Upewnij się, że token jest uwzględniony w prompcie, i uruchom ten sam kod.
fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
}
Generowanie iteracyjne
Generator obrazów może też wyświetlać wygenerowane obrazy pośrednie podczas każdej iteracji, zgodnie z parametrem wejściowym iterations. Aby wyświetlić te wyniki pośrednie, wywołaj metodę setInputs, a potem wywołaj execute(), aby uruchomić każdy krok. Ustaw parametr showResult na true, aby wyświetlić wyniki pośrednie.
fun execute(showResult: Boolean): Bitmap {
val result = imageGenerator.execute(showResult)
val bitmap =
BitmapExtractor.extract(result.generatedImage())
return bitmap
}
Obsługa i wyświetlanie wyników
Generator obrazów zwraca obiekt ImageGeneratorResult, który zawiera wygenerowany obraz, sygnaturę czasową zakończenia i obraz warunkowy, jeśli został podany jako dane wejściowe.
val bitmap = BitmapExtractor.extract(result.generatedImage())
Ten obraz został wygenerowany na podstawie tych danych wejściowych przy użyciu tylko modelu podstawowego.
Dane wejściowe:
- Prompt: „kolorowy kreskówkowy szop w kapeluszu z szerokim rondem trzymający kij i idący przez las, animacja, widok z trzech czwartych, obraz”
- Seed: 312687592
- Iteracje: 20
Wygenerowany obraz: