Руководство по созданию изображений для Android

Задача MediaPipe Image Generator позволяет создавать изображения на основе текстового запроса. В этой задаче используется модель преобразования текста в изображение для создания изображений с использованием методов диффузии.

Задача принимает в качестве входных данных текстовую подсказку, а также необязательное изображение условия, которое модель может дополнить и использовать в качестве ссылки для генерации. Генератор изображений также может генерировать изображения на основе конкретных концепций, предоставленных модели во время обучения или переобучения. Дополнительные сведения см. в разделе Настройка с помощью LoRA .

Пример кода, описанный в этой инструкции, доступен на GitHub . Дополнительные сведения о возможностях, моделях и параметрах конфигурации этой задачи см. в разделе Обзор .

Пример кода

Пример кода задач MediaPipe — это базовая реализация приложения Image Generator для Android. Вы можете использовать это приложение в качестве отправной точки для своего собственного приложения для Android или обращаться к нему при изменении существующего приложения. Пример кода Image Generator размещен на GitHub .

Загрузите код

Следующие инструкции показывают, как создать локальную копию кода примера с помощью инструмента командной строки git .

Чтобы загрузить пример кода:

  1. Клонируйте репозиторий git, используя следующую команду:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. При желании настройте свой экземпляр git на использование разреженной проверки, чтобы у вас были только файлы для примера приложения Image Generator:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_generation/android
    

После создания локальной версии кода примера вы можете импортировать проект в Android Studio и запустить приложение. Инструкции см. в Руководстве по установке для Android .

Ключевые компоненты

Следующие файлы содержат ключевой код для этого примера приложения для создания изображений:

  • ImageGenerationHelper.kt : инициализирует задачу и управляет генерацией изображения.
  • DiffusionActivity.kt : генерирует изображения, когда плагины или веса LoRA не включены.
  • PluginActivity.kt : реализует модели плагинов, которые позволяют пользователям предоставлять изображение состояния в качестве входных данных.
  • LoRAWeightActivity.kt : осуществляет доступ к весам LoRA и обрабатывает их, которые используются для настройки базовых моделей и позволяют им генерировать изображения конкретных концепций.

Настраивать

В этом разделе описаны ключевые шаги по настройке среды разработки и проектов кода специально для использования Image Generator. Общие сведения о настройке среды разработки для использования задач MediaPipe, включая требования к версии платформы, см. в руководстве по настройке для Android .

Зависимости

Задача «Генератор изображений» использует библиотеку com.google.mediapipe:tasks-vision-image-generator . Добавьте эту зависимость в файл build.gradle вашего приложения Android:

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

Для устройств с Android 12 (API 31) или более поздней версии добавьте зависимость от собственной библиотеки OpenCL. Дополнительную информацию см. в документации по тегу uses-native-library .

Добавьте следующие теги uses-native-library в файл 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" />

Модель

Для задачи MediaPipe Image Generator требуется обученная базовая модель, совместимая с этой задачей. После загрузки модели установите необходимые зависимости и преобразуйте модель в подходящий формат. Затем отправьте преобразованную модель на устройство Android.

Дополнительную информацию о доступных обученных моделях для Image Generator см. в разделе «Модели» обзора задач.

Скачать модель фундамента

Генератор изображений требует, чтобы базовая модель соответствовала формату модели runwayml/stable-diffusion-v1-5 EMA-only , основанному на следующей модели: runwayml/stable-diffusion-v1-5 .

Установите зависимости и преобразуйте модель

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

Запустите скрипт convert.py :

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

Отправьте преобразованную модель на устройство.

Отправьте содержимое папки <output_path> на устройство 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

Загрузите модели плагинов и добавьте веса LoRA (необязательно)

Если вы собираетесь использовать модель плагина , проверьте, нужно ли загружать модель. Для плагинов, которым требуется дополнительная модель, модели плагинов должны быть либо включены в APK, либо загружены по требованию. Модели плагинов имеют небольшой вес (около 23 МБ) и могут быть включены непосредственно в APK. Однако мы рекомендуем загружать модели плагинов по требованию.

Если вы настроили модель с помощью LoRA , загрузите ее по требованию. Дополнительные сведения см. в разделе Модель плагина весов LoRA.

Создать задачу

Задача MediaPipe Image Generator использует функцию createFromOptions() для настройки задачи. Функция createFromOptions() принимает значения параметров конфигурации. Дополнительные сведения о параметрах конфигурации см. в разделе Параметры конфигурации .

Варианты конфигурации

Эта задача имеет следующие параметры конфигурации для приложений Android:

Название опции Описание Диапазон значений
imageGeneratorModelDirectory Каталог модели генератора изображений, в котором хранятся веса модели. PATH
loraWeightsFilePath Устанавливает путь к файлу весов LoRA. Необязательно и применимо только в том случае, если модель была настроена с помощью LoRA. PATH
errorListener Устанавливает дополнительный прослушиватель ошибок. N/A

Задача также поддерживает модели плагинов, которые позволяют пользователям включать изображения условий во входные данные задачи, которые базовая модель может дополнять и использовать в качестве эталона для генерации. Этими изображениями состояния могут быть ориентиры лиц, контуры краев и оценки глубины, которые модель использует в качестве дополнительного контекста и информации для создания изображений.

При добавлении модели плагина к базовой модели также настройте параметры плагина. Плагин ориентира Face использует faceConditionOptions , плагин Canny Edge использует edgeConditionOptions , а плагин Depth использует depthConditionOptions .

Варианты канни-края

Настройте следующие параметры в edgeConditionOptions .

Название опции Описание Диапазон значений Значение по умолчанию
threshold1 Первый порог для процедуры гистерезиса. Float 100
threshold2 Второй порог для процедуры гистерезиса. Float 200
apertureSize Размер апертуры для оператора Собеля. Типичный диапазон составляет от 3 до 7. Integer 3
l2Gradient Используется ли норма L2 для расчета величины градиента изображения вместо нормы L1 по умолчанию. BOOLEAN False
EdgePluginModelBaseOptions Объект BaseOptions , задающий путь к модели подключаемого модуля. Объект BaseOptions N/A

Дополнительную информацию о том, как работают эти параметры конфигурации, см. в разделе Детектор границ Canny .

Параметры ориентира лица

Настройте следующие параметры в faceConditionOptions .

Название опции Описание Диапазон значений Значение по умолчанию
minFaceDetectionConfidence Минимальный показатель достоверности, позволяющий считать обнаружение лица успешным. Float [0.0,1.0] 0.5
minFacePresenceConfidence Минимальный показатель достоверности оценки присутствия лица при обнаружении ориентиров лица. Float [0.0,1.0] 0.5
faceModelBaseOptions Объект BaseOptions , задающий путь к модели, создающей изображение условия. Объект BaseOptions N/A
FacePluginModelBaseOptions Объект BaseOptions , задающий путь к модели подключаемого модуля. Объект BaseOptions N/A

Дополнительную информацию о том, как работают эти параметры конфигурации, см. в задаче Face Landmarker .

Опции глубины

Настройте следующие параметры в depthConditionOptions .

Название опции Описание Диапазон значений Значение по умолчанию
depthModelBaseOptions Объект BaseOptions , задающий путь к модели, создающей изображение условия. Объект BaseOptions N/A
depthPluginModelBaseOptions Объект BaseOptions , задающий путь к модели подключаемого модуля. Объект BaseOptions N/A

Создайте, используя только базовую модель

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

imageGenerator = ImageGenerator.createFromOptions(context, options)

Создавайте с помощью плагинов

Если вы применяете дополнительную модель плагина, установите базовые параметры модели плагина с помощью setPluginModelBaseOptions . Если для модели плагина требуется дополнительная загруженная модель для создания изображения условия, укажите путь в BaseOptions .

Ориентир на лицо

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)
    

Кэнни Эдж

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)
    

Глубина

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)
    

Создавайте с весами LoRA

Если вы включаете веса LoRA, используйте параметр loraWeightsFilePath чтобы указать местоположение пути.

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

imageGenerator = ImageGenerator.createFromOptions(context, options)

Подготовьте данные

Генератор изображений принимает следующие входные данные:

  • подсказка (обязательно): текстовая подсказка, описывающая создаваемое изображение.
  • итерации (обязательно): общее количество итераций для создания изображения. Хорошая отправная точка — 20.
  • начальное число (обязательно): случайное начальное значение, используемое при создании изображения.
  • Изображение состояния (необязательно): изображение, которое модель использует в качестве эталона для создания. Применимо только при использовании модели плагина.
  • тип условия (необязательно): тип модели плагина, используемой в задаче. Применимо только при использовании модели плагина.

Входные данные только с моделью фундамента

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

Входы с плагинами

Если вы применяете дополнительную модель подключаемого модуля, также используйте conditionType , чтобы выбрать модель подключаемого модуля, и параметр sourceConditionImage , чтобы создать изображение условия.

Название опции Описание Ценить
conditionType Модель плагина применена к базовой модели. {"FACE", "EDGE", "DEPTH"}
sourceConditionImage Исходное изображение, используемое для создания условного изображения. Объект MPImage

Если вы используете модель плагина, используйте createConditionImage для создания изображения условия:

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

После создания изображения условия включите его в качестве входных данных вместе с подсказкой, начальным числом и количеством итераций.

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

Входы с весами LoRA

Если вы используете веса LoRA, убедитесь, что токен находится в текстовой подсказке, если вы собираетесь создать изображение с конкретной концепцией, представленной весами.

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

Запустить задачу

Используйте методgenerate generate() , чтобы сгенерировать изображение, используя входные данные, указанные в предыдущем разделе. Это создает одно сгенерированное изображение.

Генерация только с использованием модели фундамента

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

Генерировать с помощью плагинов

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
}

Генерация с весами LoRA

Процесс создания изображений с использованием модели, настроенной с использованием весов LoRA, аналогичен процессу со стандартной моделью фундамента. Убедитесь, что токен включен в приглашение, и запустите тот же код.

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

Итеративная генерация

Генератор изображений также может выводить сгенерированные промежуточные изображения во время каждой итерации, как определено во входном параметре iterations . Чтобы просмотреть эти промежуточные результаты, вызовите метод setInputs , затем вызовите execute() для выполнения каждого шага. Установите для параметра showResult значение true , чтобы отобразить промежуточные результаты.

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

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

    return bitmap
}

Обработка и отображение результатов

Генератор изображений возвращает ImageGeneratorResult , который включает в себя сгенерированное изображение, временную метку времени завершения и условное изображение, если оно было предоставлено в качестве входных данных.

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

Следующее изображение было создано на основе следующих входных данных с использованием только модели фундамента.

Входы:

  • Подсказка : «красочный мультяшный енот в широкополой шляпе с гибкими полями и палкой, идущий по лесу, анимированный, вид в три четверти, рисующий»
  • Семя : 312687592
  • Итерации : 20

Сгенерированное изображение: