L'attività MediaPipe Image Generator consente di generare immagini in base a un prompt di testo. Questo task utilizza un modello da testo a immagine per generare immagini utilizzando tecniche di diffusione.
L'attività accetta un prompt di testo come input, insieme a un'immagine di condizione facoltativa che il modello può aumentare e utilizzare come riferimento per la generazione. Image Generator può anche generare immagini basate su concetti specifici forniti al modello durante l'addestramento o il riaddestramento. Per saperne di più, consulta Personalizzazione con LoRA.
Il codice campione descritto in queste istruzioni è disponibile su GitHub. Per saperne di più sulle funzionalità, sui modelli e sulle opzioni di configurazione di questa attività, consulta la panoramica.
Esempio di codice
Il codice di esempio di MediaPipe Tasks è un'implementazione di base di un'app Image Generator per Android. Puoi utilizzare l'app come punto di partenza per la tua app Android o farvi riferimento quando modifichi un'app esistente. Il codice di esempio di Image Generator è ospitato su GitHub.
Scarica il codice
Le istruzioni riportate di seguito mostrano come creare una copia locale del codice di esempio utilizzando lo strumento a riga di comando git.
Per scaricare il codice di esempio:
- Clona il repository Git utilizzando il seguente comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
- (Facoltativo) Configura l'istanza Git per utilizzare il checkout selettivo, in modo da avere
solo i file per l'app di esempio Image Generator:
cd mediapipe-samples git sparse-checkout init --cone git sparse-checkout set examples/image_generation/android
Dopo aver creato una versione locale del codice di esempio, puoi importare il progetto in Android Studio ed eseguire l'app. Per istruzioni, consulta la Guida alla configurazione per Android.
Componenti chiave
I seguenti file contengono il codice cruciale per questa applicazione di esempio di generazione di immagini:
- ImageGenerationHelper.kt: inizializza l'attività e gestisce la generazione di immagini.
- DiffusionActivity.kt: Genera immagini quando i plug-in o i pesi LoRA non sono attivi.
- PluginActivity.kt: Implementa i modelli di plug-in, che consentono agli utenti di fornire un'immagine di condizione come input.
- LoRAWeightActivity.kt: Accede alle ponderazioni LoRA e le gestisce. Queste vengono utilizzate per personalizzare i modelli di base e consentire loro di generare immagini di concetti specifici.
Configurazione
Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e i progetti di codice specifici per l'utilizzo di Generatore di immagini. Per informazioni generali sulla configurazione dell'ambiente di sviluppo per l'utilizzo delle attività MediaPipe, inclusi i requisiti della versione della piattaforma, consulta la Guida alla configurazione per Android.
Dipendenze
L'attività Generatore di immagini utilizza la libreria
com.google.mediapipe:tasks-vision-image-generator. Aggiungi questa dipendenza
al file build.gradle della tua app per Android:
dependencies {
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
}
Per i dispositivi con Android 12 (API 31) o versioni successive, aggiungi la dipendenza della libreria OpenCL nativa. Per saperne di più, consulta la documentazione relativa al tag
uses-native-library.
Aggiungi i seguenti tag uses-native-library al file 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" />
Modello
L'attività Generatore di immagini MediaPipe richiede un foundation model addestrato compatibile con questa attività. Dopo aver scaricato un modello, installa le dipendenze richieste e convertilo in un formato adatto. Poi, invia il modello convertito al dispositivo Android.
Per saperne di più sui modelli addestrati disponibili per Generatore di immagini, consulta la sezione Modelli della panoramica dell'attività.
Scarica il modello di base
Image Generator richiede che il modello di base corrisponda al formato del modello stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only, in base al seguente modello: stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only.
Installa le dipendenze e converti il modello
$ pip install torch typing_extensions numpy Pillow requests pytorch_lightning absl-py
Esegui lo script
convert.py:
$ python3 convert.py --ckpt_path <ckpt_path> --output_path <output_path>
Invia il modello convertito al dispositivo
Invia i contenuti della cartella <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
(Facoltativo) Scarica i modelli di plug-in e aggiungi i pesi LoRA
Se intendi utilizzare un modello di plug-in, controlla se il modello deve essere scaricato. Per i plug-in che richiedono un modello aggiuntivo, i modelli del plug-in devono essere raggruppati nell'APK o scaricati on demand. I modelli di plug-in sono leggeri (~23 MB) e possono essere raggruppati direttamente nell'APK. Tuttavia, ti consigliamo di scaricare i modelli dei plug-in on demand.
Se hai personalizzato un modello con LoRA, scaricali on demand. Per ulteriori informazioni, consulta il modello di plug-in dei pesi LoRA.
Creare l'attività
L'attività Generatore di immagini MediaPipe utilizza la funzione createFromOptions() per configurare l'attività. La funzione createFromOptions() accetta valori per le opzioni di configurazione. Per ulteriori informazioni sulle opzioni di configurazione, consulta Opzioni di
configurazione.
Opzioni di configurazione
Questa attività ha le seguenti opzioni di configurazione per le app per Android:
| Nome opzione | Descrizione | Intervallo di valori |
|---|---|---|
imageGeneratorModelDirectory |
La directory del modello di generatore di immagini in cui sono memorizzati i pesi del modello. | PATH |
loraWeightsFilePath |
Imposta il percorso del file dei pesi LoRA. Facoltativo e applicabile solo se il modello è stato personalizzato con LoRA. | PATH |
errorListener |
Imposta un listener di errori facoltativo. | N/A |
L'attività supporta anche i modelli di plug-in, che consentono agli utenti di includere immagini di condizioni nell'input dell'attività, che il modello di base può aumentare e utilizzare come riferimento per la generazione. Queste immagini delle condizioni possono essere punti di riferimento del volto, contorni dei bordi e stime di profondità, che il modello utilizza come contesto e informazioni aggiuntivi per generare immagini.
Quando aggiungi un modello di plug-in al modello di base, configura anche le opzioni del plug-in. Il plug-in Punti caratteristici del volto utilizza faceConditionOptions, il plug-in Bordo di Canny utilizza edgeConditionOptions e il plug-in Profondità utilizza depthConditionOptions.
Opzioni di rilevamento dei contorni
Configura le seguenti opzioni in edgeConditionOptions.
| Nome opzione | Descrizione | Intervallo di valori | Valore predefinito |
|---|---|---|---|
threshold1 |
Prima soglia per la procedura di isteresi. | Float |
100 |
threshold2 |
Seconda soglia per la procedura di isteresi. | Float |
200 |
apertureSize |
Dimensione dell'apertura per l'operatore Sobel. L'intervallo tipico è compreso tra 3 e 7. | Integer |
3 |
l2Gradient |
Indica se la norma L2 viene utilizzata per calcolare la grandezza del gradiente dell'immagine, anziché la norma L1 predefinita. | BOOLEAN |
False |
EdgePluginModelBaseOptions |
L'oggetto BaseOptions che imposta il percorso
per il modello del plug-in. |
BaseOptions oggetto |
N/A |
Per ulteriori informazioni sul funzionamento di queste opzioni di configurazione, consulta Rilevatore di bordi Canny.
Opzioni per i punti di riferimento del volto
Configura le seguenti opzioni in faceConditionOptions.
| Nome opzione | Descrizione | Intervallo di valori | Valore predefinito |
|---|---|---|---|
minFaceDetectionConfidence |
Il punteggio di confidenza minimo affinché il rilevamento del volto venga considerato riuscito. | Float [0.0,1.0] |
0.5 |
minFacePresenceConfidence |
Il punteggio di attendibilità minimo della presenza del volto nel rilevamento dei punti di riferimento del volto. | Float [0.0,1.0] |
0.5 |
faceModelBaseOptions |
L'oggetto BaseOptions che imposta il percorso
per il modello che crea l'immagine della condizione. |
BaseOptions oggetto |
N/A |
FacePluginModelBaseOptions |
L'oggetto BaseOptions che imposta il percorso
per il modello del plug-in. |
BaseOptions oggetto |
N/A |
Per ulteriori informazioni su come funzionano queste opzioni di configurazione, consulta l'attività Face Landmarker.
Opzioni di profondità
Configura le seguenti opzioni in depthConditionOptions.
| Nome opzione | Descrizione | Intervallo di valori | Valore predefinito |
|---|---|---|---|
depthModelBaseOptions |
L'oggetto BaseOptions che imposta il percorso
per il modello che crea l'immagine della condizione. |
BaseOptions oggetto |
N/A |
depthPluginModelBaseOptions |
L'oggetto BaseOptions che imposta il percorso
per il modello del plug-in. |
BaseOptions oggetto |
N/A |
Crea con solo il modello di base
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Creare con i plug-in
Se applichi un modello di plug-in facoltativo, imposta le opzioni di base per il
modello di plug-in con setPluginModelBaseOptions. Se il modello di plug-in richiede un modello scaricato aggiuntivo per creare l'immagine della condizione, specifica il percorso in BaseOptions.
Punto di riferimento del viso
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)
Profondità
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 i pesi LoRA
Se includi i pesi LoRA, utilizza il parametro loraWeightsFilePath per
indicare il percorso.
val options = ImageGeneratorOptions.builder()
.setLoraWeightsFilePath(weightsPath)
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Preparazione dei dati
Image Generator accetta i seguenti input:
- Prompt (obbligatorio): il prompt di testo che descrive l'immagine da generare.
- iterazioni (obbligatorio): il numero totale di iterazioni per generare l'immagine. Un buon punto di partenza è 20.
- seed (obbligatorio): il seme casuale utilizzato durante la generazione dell'immagine.
- condition image (immagine della condizione) (facoltativo): l'immagine che il modello utilizza come riferimento per la generazione. Applicabile solo quando utilizzi un modello di plug-in.
- (Facoltativo) Tipo di condizione: il tipo di modello di plug-in utilizzato con l'attività. Applicabile solo quando utilizzi un modello di plug-in.
Input con solo il modello di base
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
Input con plug-in
Se applichi un modello di plug-in facoltativo, utilizza anche il parametro conditionType
per scegliere il modello di plug-in e il parametro sourceConditionImage per
generare l'immagine della condizione.
| Nome opzione | Descrizione | Valore |
|---|---|---|
conditionType |
Il modello di plug-in applicato al modello di base. | {"FACE", "EDGE", "DEPTH"} |
sourceConditionImage |
L'immagine di origine utilizzata per creare l'immagine della condizione. | MPImage oggetto |
Se utilizzi un modello di plug-in, utilizza createConditionImage per creare l'immagine
della condizione:
fun createConditionImage(
inputImage: MPImage,
conditionType: ConditionType
): Bitmap {
val result =
imageGenerator.createConditionImage(inputImage, conditionType)
return BitmapExtractor.extract(result)
}
Dopo aver creato l'immagine della condizione, includila come input insieme a prompt, seed e numero di iterazioni.
imageGenerator.setInputs(
prompt,
conditionalImage,
conditionType,
iteration,
seed
)
Input con pesi LoRA
Se utilizzi i pesi LoRA, assicurati che il token sia nel prompt di testo se intendi generare un'immagine con il concetto specifico rappresentato dai pesi.
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
Esegui l'attività
Utilizza il metodo generate() per generare un'immagine utilizzando gli input forniti nella sezione precedente. In questo modo viene generata una singola immagine.
Genera solo con il modello di 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
}
Generare con i plug-in
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 i pesi LoRA
Il processo di generazione di immagini con un modello personalizzato con pesi LoRA è simile a quello con un foundation model standard. Assicurati che il token sia incluso nel prompt ed esegui lo stesso codice.
fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
}
Generazione iterativa
Il generatore di immagini può anche restituire le immagini intermedie generate durante ogni
iterazione, come definito nel parametro di input iterations. Per visualizzare questi
risultati intermedi, chiama il metodo setInputs, poi chiama execute() per eseguire
ogni passaggio. Imposta il parametro showResult su true per visualizzare i risultati intermedi.
fun execute(showResult: Boolean): Bitmap {
val result = imageGenerator.execute(showResult)
val bitmap =
BitmapExtractor.extract(result.generatedImage())
return bitmap
}
Gestire e visualizzare i risultati
Image Generator restituisce un ImageGeneratorResult, che include l'immagine generata, un timestamp dell'ora di completamento e l'immagine condizionale, se ne è stata fornita una come input.
val bitmap = BitmapExtractor.extract(result.generatedImage())
L'immagine seguente è stata generata dai seguenti input utilizzando solo un modello di base.
Input:
- Prompt: "un procione colorato in stile cartone animato che indossa un cappello floscio a tesa larga che tiene un bastone mentre cammina nella foresta, animato, inquadratura di tre quarti, dipinto"
- Seed: 312687592
- Iterazioni: 20
Immagine generata: