Hướng dẫn tạo hình ảnh cho Android

Tác vụ Trình tạo hình ảnh MediaPipe cho phép bạn tạo hình ảnh dựa trên câu lệnh dạng văn bản. Nhiệm vụ này sử dụng mô hình từ văn bản đến hình ảnh để tạo hình ảnh bằng kỹ thuật khuếch tán.

Tác vụ chấp nhận lời nhắc dạng văn bản làm thông tin đầu vào, cùng với hình ảnh điều kiện không bắt buộc mà mô hình có thể bổ sung và dùng làm thông tin tham chiếu để tạo. Trình tạo hình ảnh cũng có thể tạo hình ảnh dựa trên các khái niệm cụ thể được cung cấp cho mô hình trong quá trình huấn luyện hoặc huấn luyện lại. Để biết thêm thông tin, hãy xem phần tuỳ chỉnh bằng LoRA.

Mã mẫu được mô tả trong những hướng dẫn này hiện có trên GitHub. Để biết thêm thông tin về các tính năng, mô hình và lựa chọn cấu hình của nhiệm vụ này, hãy xem phần Tổng quan.

Ví dụ về mã

Mã ví dụ về MediaPipe Tasks là một cách triển khai cơ bản của ứng dụng Trình tạo hình ảnh dành cho Android. Bạn có thể dùng ứng dụng này làm điểm xuất phát cho ứng dụng Android của riêng mình hoặc tham chiếu đến ứng dụng này khi sửa đổi một ứng dụng hiện có. Mã ví dụ về Trình tạo hình ảnh được lưu trữ trên GitHub.

Tải mã xuống

Hướng dẫn sau đây chỉ cho bạn cách tạo bản sao cục bộ của mã ví dụ bằng công cụ dòng lệnh git.

Cách tải mã ví dụ xuống:

  1. Sao chép kho lưu trữ git bằng lệnh sau:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Bạn có thể tuỳ ý định cấu hình thực thể git để sử dụng quy trình thanh toán thưa thớt, vì vậy, bạn chỉ có các tệp cho ứng dụng mẫu về Trình tạo hình ảnh:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_generator/android
    

Sau khi tạo phiên bản cục bộ của mã ví dụ, bạn có thể nhập dự án vào Android Studio và chạy ứng dụng. Để được hướng dẫn, hãy xem Hướng dẫn thiết lập dành cho Android.

Thành phần chính

Các tệp sau đây chứa mã quan trọng cho ứng dụng mẫu tạo hình ảnh này:

  • ImageGenerationHelper.kt: Khởi động tác vụ và xử lý quá trình tạo hình ảnh.
  • DiffusionActivity.kt: Tạo hình ảnh khi trình bổ trợ hoặc trọng số LoRA không được bật.
  • PluginActivity.kt: Triển khai các mô hình trình bổ trợ, cho phép người dùng cung cấp hình ảnh điều kiện làm đầu vào.
  • LoRAWeightActivity.kt: Truy cập và xử lý các trọng số LoRA, dùng để tuỳ chỉnh các mô hình nền tảng và cho phép tạo hình ảnh về các khái niệm cụ thể.

Thiết lập

Phần này mô tả các bước chính để thiết lập môi trường phát triển và mã dự án dành riêng để sử dụng Trình tạo hình ảnh. Để biết thông tin chung về cách thiết lập môi trường phát triển nhằm sử dụng các tác vụ MediaPipe, bao gồm cả yêu cầu về phiên bản nền tảng, hãy xem Hướng dẫn thiết lập dành cho Android.

Phần phụ thuộc

Tác vụ Trình tạo hình ảnh sử dụng thư viện com.google.mediapipe:tasks-vision-image-generator. Thêm phần phụ thuộc này vào tệp build.gradle của ứng dụng Android:

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

Đối với các thiết bị chạy Android 12 (API 31) trở lên, hãy thêm phần phụ thuộc thư viện OpenCL gốc vào AndroidManifest.xml. Để biết thêm thông tin, hãy xem tài liệu về thẻ uses-native-library.

Một số thiết bị Android cũng có thể yêu cầu thêm thư viện:

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

Mẫu

Tác vụ Trình tạo hình ảnh MediaPipe cần có một mô hình nền tảng đã qua huấn luyện và tương thích với tác vụ này. Sau khi tải một mô hình xuống, hãy cài đặt các phần phụ thuộc cần thiết rồi chuyển đổi mô hình đó sang một định dạng phù hợp. Sau đó, đẩy mô hình đã chuyển đổi sang thiết bị Android.

Để biết thêm thông tin về các mô hình đã huấn luyện hiện có cho Trình tạo hình ảnh, hãy xem phần Mô hình tổng quan về nhiệm vụ.

Tải mô hình nền tảng xuống

Trình tạo hình ảnh yêu cầu mô hình nền tảng phải khớp với định dạng mô hình runwayml/stable-diffusion-v1-5 EMA-only, dựa trên mô hình sau: runwayml/stable-diffusion-v1-5.

Cài đặt các phần phụ thuộc và chuyển đổi mô hình

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

Chạy tập lệnh convert.py:

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

Đẩy mẫu đã chuyển đổi sang thiết bị

Đẩy nội dung của thư mục <output_path> sang thiết bị 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

Tải mô hình trình bổ trợ xuống và thêm trọng số LoRA (Không bắt buộc)

Nếu bạn có ý định sử dụng mô hình trình bổ trợ, hãy kiểm tra xem có phải tải mô hình đó xuống hay không. Đối với các trình bổ trợ yêu cầu mô hình bổ sung, các mô hình trình bổ trợ phải được đóng gói trong tệp APK hoặc được tải xuống theo yêu cầu. Các mô hình trình bổ trợ có kích thước nhẹ (~23MB) và có thể đóng gói trực tiếp trong tệp APK. Tuy nhiên, bạn nên tải các mô hình trình bổ trợ xuống theo yêu cầu.

Nếu bạn đã tuỳ chỉnh một mô hình bằng LoRA, hãy tải các mô hình đó xuống theo yêu cầu. Để biết thêm thông tin, hãy xem mô hình trình bổ trợ có trọng số LoRA.

Tạo việc cần làm

Tác vụ Trình tạo hình ảnh MediaPipe sử dụng hàm createFromOptions() để thiết lập tác vụ đó. Hàm createFromOptions() chấp nhận các giá trị cho các tuỳ chọn cấu hình. Để biết thêm thông tin về các lựa chọn cấu hình, hãy xem phần Lựa chọn cấu hình.

Các lựa chọn về cấu hình

Tác vụ này có các lựa chọn cấu hình sau đây cho ứng dụng Android:

Tên lựa chọn Nội dung mô tả Khoảng giá trị
imageGeneratorModelDirectory Thư mục mô hình trình tạo hình ảnh lưu trữ trọng số của mô hình. PATH
loraWeightsFilePath Thiết lập đường dẫn đến tệp trọng số LoRA. Không bắt buộc và chỉ áp dụng nếu mô hình được tuỳ chỉnh bằng LoRA. PATH
errorListener Thiết lập một trình nghe lỗi (không bắt buộc). N/A

Tác vụ cũng hỗ trợ các mô hình trình bổ trợ, cho phép người dùng đưa hình ảnh điều kiện vào đầu vào của tác vụ. Mô hình nền tảng có thể bổ sung và dùng làm tham chiếu cho việc tạo này. Những hình ảnh điều kiện này có thể là điểm mốc của khuôn mặt, đường viền cạnh và số liệu ước tính chiều sâu mà mô hình sẽ sử dụng làm thông tin và ngữ cảnh bổ sung để tạo hình ảnh.

Khi thêm mô hình trình bổ trợ vào mô hình nền tảng, bạn cũng nên định cấu hình các tuỳ chọn trình bổ trợ. Trình bổ trợ mốc khuôn mặt sử dụng faceConditionOptions, trình bổ trợ Canny cạnh sử dụng edgeConditionOptions và trình bổ trợ Độ sâu sử dụng depthConditionOptions.

Tuỳ chọn Canny Edge

Định cấu hình các tuỳ chọn sau trong edgeConditionOptions.

Tên lựa chọn Nội dung mô tả Khoảng giá trị Giá trị mặc định
threshold1 Ngưỡng đầu tiên đối với quy trình trì hoãn. Float 100
threshold2 Ngưỡng thứ hai cho quy trình trì hoãn. Float 200
apertureSize Kích thước khẩu độ cho toán tử Sobel. Phạm vi thông thường là từ 3 đến 7. Integer 3
l2Gradient Liệu có dùng định mức L2 để tính độ lớn độ dốc của hình ảnh hay không, thay vì tiêu chuẩn L1 mặc định. BOOLEAN False
EdgePluginModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình trình bổ trợ. BaseOptions đối tượng N/A

Để biết thêm thông tin về cách hoạt động của các tuỳ chọn cấu hình này, hãy xem Trình phát hiện cạnh của Canny.

Tuỳ chọn mốc khuôn mặt

Định cấu hình các tuỳ chọn sau trong faceConditionOptions.

Tên lựa chọn Nội dung mô tả Khoảng giá trị Giá trị mặc định
minFaceDetectionConfidence Điểm số tin cậy tối thiểu để phát hiện khuôn mặt được coi là thành công. Float [0.0,1.0] 0.5
minFacePresenceConfidence Điểm số tin cậy tối thiểu về sự hiện diện khuôn mặt trong công cụ phát hiện mốc khuôn mặt. Float [0.0,1.0] 0.5
faceModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình sẽ tạo hình ảnh điều kiện. BaseOptions đối tượng N/A
FacePluginModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình trình bổ trợ. BaseOptions đối tượng N/A

Để biết thêm thông tin về cách hoạt động của các tuỳ chọn cấu hình này, hãy xem tác vụ Khuôn mặt được đánh dấu.

Lựa chọn độ sâu

Định cấu hình các tuỳ chọn sau trong depthConditionOptions.

Tên lựa chọn Nội dung mô tả Khoảng giá trị Giá trị mặc định
depthModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình sẽ tạo hình ảnh điều kiện. BaseOptions đối tượng N/A
depthPluginModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình trình bổ trợ. BaseOptions đối tượng N/A

Sáng tạo chỉ bằng mô hình nền tảng

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

imageGenerator = ImageGenerator.createFromOptions(context, options)

Tạo bằng trình bổ trợ

Nếu bạn đang áp dụng một mô hình trình bổ trợ không bắt buộc, hãy đặt các tuỳ chọn cơ sở cho mô hình trình bổ trợ bằng setPluginModelBaseOptions. Nếu mô hình trình bổ trợ yêu cầu một mô hình đã tải xuống bổ sung để tạo hình ảnh điều kiện, hãy chỉ định đường dẫn trong BaseOptions.

Điểm mốc cho khuôn mặt

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)
    

Chiều sâu

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)
    

Sáng tạo bằng các trọng số LoRA

Nếu bạn đang thêm các trọng số LoRA, hãy sử dụng tham số loraWeightsFilePath để trỏ đến vị trí đường dẫn.

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

imageGenerator = ImageGenerator.createFromOptions(context, options)

Chuẩn bị dữ liệu

Trình tạo hình ảnh chấp nhận các dữ liệu đầu vào sau:

  • prompt (bắt buộc): Lời nhắc dạng văn bản mô tả hình ảnh cần tạo.
  • vòng lặp (bắt buộc): Tổng số lần lặp để tạo hình ảnh. Điểm xuất phát hợp lý là 20.
  • seed (bắt buộc): Nội dung gốc ngẫu nhiên được dùng trong quá trình tạo hình ảnh.
  • condition image (hình ảnh tình trạng) (không bắt buộc): Hình ảnh mà mô hình sử dụng làm tham chiếu để tạo. Chỉ áp dụng khi sử dụng mô hình trình bổ trợ.
  • condition type (không bắt buộc): Loại mô hình trình bổ trợ dùng trong tác vụ. Chỉ áp dụng khi sử dụng mô hình trình bổ trợ.

Đầu vào chỉ có mô hình nền tảng

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

Dữ liệu đầu vào có trình bổ trợ

Nếu bạn đang áp dụng một mô hình trình bổ trợ không bắt buộc, hãy sử dụng tham số conditionType để chọn mô hình trình bổ trợ và tham số sourceConditionImage để tạo hình ảnh điều kiện.

Tên lựa chọn Nội dung mô tả Giá trị
conditionType Mô hình trình bổ trợ được áp dụng cho mô hình nền tảng. {"FACE", "EDGE", "DEPTH"}
sourceConditionImage Hình ảnh nguồn được dùng để tạo hình ảnh điều kiện. MPImage đối tượng

Nếu bạn đang sử dụng mô hình trình bổ trợ, hãy sử dụng createConditionImage để tạo hình ảnh điều kiện:

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

Sau khi tạo hình ảnh điều kiện, hãy đưa vào dưới dạng dữ liệu đầu vào cùng với lời nhắc, nội dung khởi đầu và số lần lặp lại.

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

Đầu vào có trọng số LoRA

Nếu bạn đang sử dụng trọng số LoRA, hãy đảm bảo rằng mã thông báo nằm trong lời nhắc dạng văn bản nếu bạn định tạo một hình ảnh có khái niệm cụ thể được biểu thị bằng trọng số.

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

Chạy tác vụ

Sử dụng phương thức generate() để tạo hình ảnh bằng cách sử dụng dữ liệu đầu vào đã cung cấp trong phần trước. Thao tác này sẽ tạo ra một hình ảnh duy nhất.

Tạo chỉ bằng mô hình nền tảng

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

Tạo bằng trình bổ trợ

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
}

Tạo bằng trọng số LoRA

Quy trình tạo hình ảnh bằng mô hình được tuỳ chỉnh với các trọng số LoRA tương tự như quy trình với mô hình nền tảng tiêu chuẩn. Đảm bảo mã thông báo có trong lời nhắc và chạy cùng một mã.

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

Tạo lặp lại

Trình tạo hình ảnh cũng có thể xuất hình ảnh trung gian được tạo trong mỗi vòng lặp, như xác định trong tham số đầu vào iterations. Để xem các kết quả trung gian này, hãy gọi phương thức setInputs, sau đó gọi execute() để chạy từng bước. Đặt tham số showResult thành true để hiển thị kết quả trung gian.

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

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

    return bitmap
}

Xử lý và hiển thị kết quả

Trình tạo hình ảnh sẽ trả về một ImageGeneratorResult, bao gồm hình ảnh được tạo, dấu thời gian cho biết thời gian hoàn tất và hình ảnh có điều kiện nếu được cung cấp làm dữ liệu đầu vào.

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

Hình ảnh sau đây được tạo từ các dữ liệu đầu vào sau đây, chỉ sử dụng mô hình nền tảng.

Đầu vào:

  • Câu lệnh: "một chú gấu mèo hoạt hình sặc sỡ đội một chiếc mũ rộng vành mềm, đang cầm một cây gậy đi xuyên qua rừng, ảnh động, hình ảnh 3/4, tranh vẽ"
  • Hạt giống: 312687592
  • Số lần lặp lại: 20

Hình ảnh được tạo: