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. Tác vụ này sử dụng mô hình chuyển văn bản sang hình ảnh để tạo hình ảnh bằng các kỹ thuật khuếch tán.

Tác vụ này chấp nhận một câu lệnh văn bản làm dữ liệu đầu vào, cùng với một hình ảnh điều kiện không bắt buộc mà mô hình có thể mở rộng và sử dụng làm 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.

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

Ví dụ về mã

Mã ví dụ về Tác vụ MediaPipe là cách triển khai cơ bản của ứng dụng Trình tạo hình ảnh cho Android. Bạn có thể sử 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 khảo ứ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 cho bạn biết 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ã mẫu 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 tính năng kiểm tra thư mục thưa, nhờ đó, bạn chỉ có các tệp cho ứng dụng mẫu Trình tạo hình ảnh:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_generation/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. Để biết hướng dẫn, hãy xem Hướng dẫn thiết lập cho Android.

Các thành phần chính

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

  • ImageGenerationHelper.kt: khởi chạy tác vụ và xử lý việc tạo hình ảnh.
  • DiffusionActivity.kt: Tạo hình ảnh khi không bật trình bổ trợ hoặc trọng số LoRA.
  • 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 dữ liệu đầ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 các mô hình này tạo hình ảnh của 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à dự án mã dành riêng cho việc 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 cho việc sử dụng các tác vụ MediaPipe, bao gồm cả cá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 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. Để biết thêm thông tin, hãy xem tài liệu về thẻ uses-native-library.

Thêm các thẻ uses-native-library sau vào tệp 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" />

Mẫu

Tác vụ Trình tạo hình ảnh MediaPipe yêu cầu một mô hình nền tảng đã được huấn luyện 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 bắt buộc và chuyển đổi mô hình đó thành một định dạng phù hợp. Sau đó, đẩy mô hình đã chuyển đổi vào thiết bị Android.

Để biết thêm thông tin về các mô hình đã huấn luyện có sẵn cho Trình tạo hình ảnh, hãy xem phần Mô hình trong phần tổng quan về tác 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 cơ sở 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 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ô hình đã chuyển đổi vào thiết bị

Đẩy nội dung của thư mục <output_path> vào 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 đị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 thêm mô hình, mô hình trình bổ trợ phải được đóng gói trong tệp APK hoặc tải xuống theo yêu cầu. Mô hình trình bổ trợ có kích thước nhỏ (~23 MB) và có thể được đó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ợ 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 tuỳ chọn cấu hình, hãy xem phần Tuỳ 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 tuỳ chọn cấu hình sau đây cho ứng dụng Android:

Tên tuỳ chọn Mô tả Phạm vi giá trị
imageGeneratorModelDirectory Thư mục mô hình trình tạo hình ảnh lưu trữ các trọng số của mô hình. PATH
loraWeightsFilePath Đặt đườ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 Đặt trình nghe lỗi không bắt buộc. N/A

Tác vụ này 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 tác vụ. Mô hình nền tảng có thể mở rộng và sử dụng hình ảnh này làm tham chiếu để tạo. Những hình ảnh điều kiện này có thể là các điểm đánh dấu trên khuôn mặt, đường viền cạnh và độ sâu ước tính mà mô hình sử dụng làm ngữ cảnh và thông tin 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, hãy định cấu hình các tuỳ chọn trình bổ trợ. Trình bổ trợ Điểm đánh dấu trên khuôn mặt sử dụng faceConditionOptions, trình bổ trợ Cạnh Canny sử dụng edgeConditionOptions và trình bổ trợ Độ sâu sử dụng depthConditionOptions.

Tuỳ chọn cạnh Canny

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

Tên tuỳ chọn Mô tả Phạm vi giá trị Giá trị mặc định
threshold1 Ngưỡng đầu tiên cho quy trình hồi quy. Float 100
threshold2 Ngưỡng thứ hai cho quy trình hồi quy. 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 chuẩn L2 có được dùng để tính toán độ lớn của độ dốc hình ảnh thay vì chuẩn L1 mặc định hay không. BOOLEAN False
EdgePluginModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình trình bổ trợ. Đối tượng BaseOptions 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 phần Trình phát hiện cạnh Canny.

Tuỳ chọn về điểm đặc trưng trên khuôn mặt

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

Tên tuỳ chọn Mô tả Phạm vi giá trị Giá trị mặc định
minFaceDetectionConfidence Điểm tin cậy tối thiểu để tính năng 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 tin cậy tối thiểu của điểm hiện diện khuôn mặt trong tính năng phát hiện điểm đặc trưng trên khuôn mặt. Float [0.0,1.0] 0.5
faceModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình tạo hình ảnh điều kiện. Đối tượng BaseOptions N/A
FacePluginModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình trình bổ trợ. Đối tượng BaseOptions 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ụ Điểm đánh dấu khuôn mặt.

Tuỳ chọn chiều sâu

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

Tên tuỳ chọn Mô tả Phạm vi giá trị Giá trị mặc định
depthModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình tạo hình ảnh điều kiện. Đối tượng BaseOptions N/A
depthPluginModelBaseOptions Đối tượng BaseOptions đặt đường dẫn cho mô hình trình bổ trợ. Đối tượng BaseOptions N/A

Tạo chỉ bằng mô hình cơ sở

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ô 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.

Địa danh trên 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)
    

Độ 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)
    

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

Nếu bạn đang thêm 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): Câu lệnh dạng văn bản mô tả hình ảnh cần tạo.
  • iterations (bắt buộc): Tổng số lần lặp để tạo hình ảnh. Bạn nên bắt đầu từ 20.
  • seed (bắt buộc): Giá trị hạt ngẫu nhiên được dùng trong quá trình tạo hình ảnh.
  • hình ảnh điều kiện (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ợ.
  • loại điều kiện (không bắt buộc): Loại mô hình trình bổ trợ được sử dụng với 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 cơ sở

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

Phương thức nhập 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 tuỳ chọn 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 dùng để tạo hình ảnh điều kiện. Đối tượng MPImage

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 hình ảnh đó vào dưới dạng dữ liệu đầu vào cùng với lời nhắc, hạt giống và số lần lặp lại.

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

Dữ liệu đầ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 câu lệnh văn bản nếu bạn dự định tạo 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 được cung cấp trong phần trước. Thao tác này sẽ tạo ra một hình ảnh được tạo.

Chỉ tạo bằng mô hình cơ sở

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 bằng trọng số LoRA tương tự như quy trình với mô hình nền tảng chuẩn. Đảm bảo mã thông báo được đưa vào 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 lần lặp lại, như được 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 trả về một ImageGeneratorResult, bao gồm hình ảnh được tạo, dấu thời gian của thời điểm hoàn tất và hình ảnh có điều kiện nếu bạn đã cung cấp hình ảnh đó 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, chỉ sử dụng mô hình cơ sở.

Đầu vào:

  • Câu lệnh: "một con gấu trúc hoạt hình đầy màu sắc, đội chiếc mũ rộng vành, cầm một cây gậy đi qua rừng, ảnh động, góc nhìn ba phần tư, bức vẽ"
  • Giá trị khởi tạo: 312687592
  • Số lần lặp lại: 20

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