Guia de geração de imagens para Android

.

A tarefa "MediaPipe Image Generator" permite gerar imagens com base em um prompt de texto. Isso usa um modelo de texto para imagem para gerar imagens usando técnicas de difusão.

A tarefa aceita um comando de texto como entrada, junto com uma imagem de condição opcional que o modelo pode ampliar e usar como referência para geração. Gerador de imagens também pode gerar imagens com base em conceitos específicos fornecidos ao modelo durante ou retreinamento. Para mais informações, consulte Personalizar com LoRA.

O exemplo de código descrito nestas instruções está disponível em GitHub. Para mais informações sobre recursos, modelos e opções de configuração, desta tarefa, consulte a Visão geral.

Exemplo de código

O código de exemplo do MediaPipe Tasks é uma implementação básica de um gerador de imagens para Android. Você pode usar o app como ponto de partida para seu próprio app Android app ou se referir a ele ao modificar um app existente. O exemplo do gerador de imagem código está hospedado em GitHub.

Fazer o download do código

As instruções a seguir mostram como criar uma cópia local do exemplo. usando a ferramenta de linha de comando git.

Para fazer o download do código de exemplo:

  1. Clone o repositório git usando o seguinte comando:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Opcionalmente, configure sua instância git para usar a finalização esparsa. Assim, você terá apenas os arquivos do app de exemplo Image Generator:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_generator/android
    

Depois de criar uma versão local do código de exemplo, você pode importar o projeto no Android Studio e executar o app. Para obter instruções, consulte o Guia de configuração do Android.

Principais componentes

Os arquivos a seguir contêm o código essencial para este exemplo de geração de imagem aplicativo:

  • ImageGenerationHelper.kt: Inicializa a tarefa e processa a geração de imagens.
  • DiffusionActivity.kt: Gera imagens quando os plug-ins ou pesos LoRA não estão ativados.
  • PluginActivity.kt: Implementa os modelos do plug-in, permitindo que os usuários forneçam uma condição como entrada.
  • LoRAWeightActivity.kt (link em inglês): Acessa e gerencia os pesos LoRA, que são usados para personalizar a base e permitir que eles gerem imagens de conceitos específicos.

Configuração

Esta seção descreve as principais etapas para configurar seu ambiente de desenvolvimento e projetos de código especificamente para usar o Image Generator. Para informações gerais a configuração do seu ambiente de desenvolvimento para usar tarefas do MediaPipe, incluindo requisitos de versão da plataforma, consulte o Guia de configuração do Android.

Dependências

A tarefa Gerador de imagens usa o com.google.mediapipe:tasks-vision-image-generator. Adicionar esta dependência ao arquivo build.gradle do seu app Android:

dependencies {
    implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
}

Para dispositivos com o Android 12 (nível 31 da API) ou mais recente, adicione a biblioteca OpenCL nativa dependência de AndroidManifest.xml. Para saber mais, consulte a documentação da uses-native-library tag.

Alguns dispositivos Android também podem exigir bibliotecas adicionais:

<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" />

Modelo

A tarefa Gerador de imagens do MediaPipe requer um modelo de fundação treinado que seja compatível a essa tarefa. Depois de fazer o download de um modelo, instale as dependências e converter o modelo em um formato adequado. Depois, envie por push o ao dispositivo Android.

Para mais informações sobre modelos treinados disponíveis para o gerador de imagens, consulte a tarefa Visão geral da seção Modelos.

Baixar o modelo de fundação

O Image Generator exige que o modelo de fundação corresponda ao Formato do modelo runwayml/stable-diffusion-v1-5 EMA-only, com base no seguinte modelo: runwayml/stable-diffusion-v1-5.

Instalar dependências e converter o modelo

$ pip install torch typing_extensions numpy Pillow requests pytorch_lightning absl-py

Execute o convert.py script:

$ python3 convert.py --ckpt_path <ckpt_path> --output_path <output_path>

Enviar o modelo convertido para o dispositivo

Envie o conteúdo da pasta <output_path> para o 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

Fazer o download de modelos de plug-in e adicionar pesos LoRA (opcional)

Se você pretende usar um modelo de plug-in, verifique se ele para fazer o download. Para plug-ins que exigem um modelo adicional, o plug-in Os modelos precisam ser empacotados no APK ou transferidos por download sob demanda. Modelos de plug-in são leves (~23 MB) e podem ser agrupadas diretamente no APK. No entanto, recomendado fazer o download de modelos de plug-in sob demanda.

Se você personalizou um modelo com LoRA, fazer o download sob demanda. Para mais informações, consulte o modelo de plug-in de pesos LoRA.

Criar a tarefa

A tarefa Gerador de imagem do MediaPipe usa a função createFromOptions() para configurar o tarefa. A função createFromOptions() aceita valores para a configuração. . Para mais informações sobre as opções de configuração, consulte Configuração .

Opções de configuração

Esta tarefa tem as seguintes opções de configuração para apps Android:

Nome da opção Descrição Intervalo de valor
imageGeneratorModelDirectory O diretório do modelo do gerador de imagens que armazena os pesos do modelo. PATH
loraWeightsFilePath Define o caminho para o arquivo de pesos LoRA. Opcional e aplicável somente se o modelo foi personalizado com o LoRA. PATH
errorListener Define um listener de erro opcional. N/A

A tarefa também oferece suporte a modelos de plug-in, o que permite que os usuários incluam imagens de condição na entrada da tarefa, que o modelo de fundação pode ampliar e usar como referência para geração. Essas imagens de condição podem ser pontos de referência, contornos de bordas e estimativas de profundidade, que o modelo usa como contexto e informações adicionais para gerar imagens.

Ao adicionar um modelo de plug-in ao modelo de fundação, configure também o plug-in . O plug-in de ponto de referência do Face usa faceConditionOptions, a borda do Canny. o plug-in usa edgeConditionOptions, e o plug-in Depth usa depthConditionOptions

Opções do Canny Edge

Configure as opções abaixo no edgeConditionOptions.

Nome da opção Descrição Intervalo de valor Valor padrão
threshold1 Primeiro limite para o procedimento de histerese. Float 100
threshold2 Segundo limite para o procedimento de histerese. Float 200
apertureSize Tamanho da abertura para o operador Sobel. O intervalo típico é de 3 a 7. Integer 3
l2Gradient Se a norma L2 for usada para calcular a magnitude do gradiente da imagem, em vez da norma L1 padrão. BOOLEAN False
EdgePluginModelBaseOptions O objeto BaseOptions que define o caminho para o modelo do plug-in. Objeto BaseOptions N/A

Para mais informações sobre como essas opções de configuração funcionam, consulte Detector de borda do Canny.

Opções de pontos de referência do rosto

Configure as opções abaixo no faceConditionOptions.

Nome da opção Descrição Intervalo de valor Valor padrão
minFaceDetectionConfidence A pontuação de confiança mínima para que a detecção facial seja considerada bem-sucedida. Float [0.0,1.0] 0.5
minFacePresenceConfidence A pontuação de confiança mínima da presença facial na detecção de pontos de referência do rosto. Float [0.0,1.0] 0.5
faceModelBaseOptions O objeto BaseOptions que define o caminho para o modelo que cria a imagem de condição. Objeto BaseOptions N/A
FacePluginModelBaseOptions O objeto BaseOptions que define o caminho para o modelo do plug-in. Objeto BaseOptions N/A

Para mais informações sobre como essas opções de configuração funcionam, consulte a Tarefa "Face Marqueer":

Opções de profundidade

Configure as opções abaixo no depthConditionOptions.

Nome da opção Descrição Intervalo de valor Valor padrão
depthModelBaseOptions O objeto BaseOptions que define o caminho para o modelo que cria a imagem de condição. Objeto BaseOptions N/A
depthPluginModelBaseOptions O objeto BaseOptions que define o caminho para o modelo do plug-in. Objeto BaseOptions N/A

Criar apenas usando o modelo de fundação

val options = ImageGeneratorOptions.builder()
    .setImageGeneratorModelDirectory(modelPath)
    .build()

imageGenerator = ImageGenerator.createFromOptions(context, options)

Criar com plug-ins

Se você estiver aplicando um modelo de plug-in opcional, defina as opções básicas para o modelo de plug-in com setPluginModelBaseOptions. Se o modelo do plug-in exigir modelo extra transferido por download para criar a imagem de condição, especifique o caminho em BaseOptions:

Ponto de referência do rosto

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)
    

Profundidade

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)
    

Criar com pesos LoRA

Se você estiver incluindo pesos LoRA, use o parâmetro loraWeightsFilePath para para o local do caminho.

val options = ImageGeneratorOptions.builder()
    .setLoraWeightsFilePath(weightsPath)
    .setImageGeneratorModelDirectory(modelPath)
    .build()

imageGenerator = ImageGenerator.createFromOptions(context, options)

Preparar dados

O Image Generator aceita as seguintes entradas:

  • prompt (obrigatório): o comando de texto que descreve a imagem a ser gerada.
  • iterations (obrigatório): o total de iterações para gerar a imagem. Um um bom ponto de partida é 20.
  • seed (obrigatório): a sugestão aleatória usada durante a geração da imagem.
  • condition image (opcional): a imagem que o modelo usa como referência para geração de imagens. Aplicável apenas ao usar um modelo de plug-in.
  • condition type (opcional): o tipo de modelo de plug-in usado com a tarefa. Aplicável apenas ao usar um modelo de plug-in.

Entradas apenas com o modelo de fundação

fun setInput(prompt: String, iteration: Int, seed: Int) {
    imageGenerator.setInputs(prompt, iteration, seed)
}

Entradas com plug-ins

Se você estiver aplicando um modelo de plug-in opcional, use também o conditionType parâmetro para escolher o modelo de plug-in e o parâmetro sourceConditionImage para gerar a imagem de condição.

Nome da opção Descrição Valor
conditionType O modelo de plug-in aplicado ao modelo de fundação. {"FACE", "EDGE", "DEPTH"}
sourceConditionImage A imagem de origem usada para criar a imagem de condição. Objeto MPImage

Se você estiver usando um modelo de plug-in, use o createConditionImage para criar o imagem da condição:

fun createConditionImage(
    inputImage: MPImage,
    conditionType: ConditionType
): Bitmap {
    val result =
        imageGenerator.createConditionImage(inputImage, conditionType)
    return BitmapExtractor.extract(result)
}

Depois de criar a imagem da condição, inclua em como entrada junto com o comando, sugestão e número de iterações.

imageGenerator.setInputs(
    prompt,
    conditionalImage,
    conditionType,
    iteration,
    seed
)

Entradas com pesos LoRA

Se você estiver usando pesos LoRA, certifique-se de que o token esteja no comando de texto se você pretende gerar uma imagem com o conceito específico representado pelo pesos específicos.

fun setInput(prompt: String, iteration: Int, seed: Int) {
    imageGenerator.setInputs(prompt, iteration, seed)
}

Executar a tarefa

Use o método generate() para gerar uma imagem usando as entradas fornecidas em na seção anterior. Isso produz uma única imagem gerada.

Gerar apenas com o modelo de fundação

fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
    val result = imageGenerator.generate(prompt, iteration, seed)
    val bitmap = BitmapExtractor.extract(result?.generatedImage())
    return bitmap
}

Gerar com 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
}

Gerar com pesos LoRA

O processo de geração de imagens com um modelo personalizado com pesos LoRA é semelhante ao processo de um modelo de fundação padrão. Verifique se o token incluído no comando e executar o mesmo código.

fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
    val result = imageGenerator.generate(prompt, iteration, seed)
    val bitmap = BitmapExtractor.extract(result?.generatedImage())
    return bitmap
}

Geração iterativa

O Image Generator também pode gerar as imagens intermediárias geradas durante cada iteração, conforme definido no parâmetro de entrada iterations. Para acessar essas resultados intermediários, chame o método setInputs e, em seguida, chame execute() para executar cada etapa. Defina o parâmetro showResult como true para exibir o intermediário. resultados.

fun execute(showResult: Boolean): Bitmap {
    val result = imageGenerator.execute(showResult)

    val bitmap =
        BitmapExtractor.extract(result.generatedImage())

    return bitmap
}

Gerenciar e exibir resultados

O gerador de imagem retorna um ImageGeneratorResult, que inclui o resultado imagem, um carimbo de data/hora do horário de conclusão e a imagem condicional, se houver foi fornecido como entrada.

val bitmap = BitmapExtractor.extract(result.generatedImage())

A imagem a seguir foi gerada a partir das seguintes entradas, usando apenas um modelo de fundação.

Entradas:

  • Comando: "Um guaxinim colorido usando um chapéu de aba larga larga segurando um graveto caminhando pela floresta, animação animada em três quartos, pintura"
  • Semente: 312687592
  • Iterações: 20

Imagem gerada: