คู่มือการสร้างรูปภาพสำหรับ Android

งาน Image Generator ของ MediaPipe ช่วยให้คุณสร้างรูปภาพตามพรอมต์ข้อความได้ งานนี้ใช้โมเดลการเปลี่ยนข้อความเป็นรูปภาพเพื่อสร้างรูปภาพโดยใช้เทคนิคการแพร่กระจาย

งานนี้รับพรอมต์ข้อความเป็นอินพุต พร้อมด้วยรูปภาพเงื่อนไขที่ไม่บังคับ ซึ่งโมเดลสามารถเพิ่มและใช้เป็นข้อมูลอ้างอิงสำหรับการสร้างได้ Image Generator ยังสร้างรูปภาพตามแนวคิดเฉพาะที่ระบุไว้ในโมเดลระหว่าง การฝึกหรือการฝึกซ้ำได้ด้วย ดูข้อมูลเพิ่มเติมได้ที่ปรับแต่งด้วย LoRA

ตัวอย่างโค้ดที่อธิบายไว้ในวิธีการเหล่านี้พร้อมให้บริการบน GitHub ดูข้อมูลเพิ่มเติมเกี่ยวกับความสามารถ โมเดล และตัวเลือกการกำหนดค่า ของงานนี้ได้ที่ภาพรวม

ตัวอย่างโค้ด

โค้ดตัวอย่างของ MediaPipe Tasks เป็นการติดตั้งใช้งานพื้นฐานของแอป Image Generator สำหรับ Android คุณสามารถใช้แอปเป็นจุดเริ่มต้นสำหรับแอป Android ของคุณเอง หรือใช้เป็นข้อมูลอ้างอิงเมื่อแก้ไขแอปที่มีอยู่ได้ โค้ดตัวอย่าง Image Generator โฮสต์อยู่ใน GitHub

ดาวน์โหลดรหัส

วิธีการต่อไปนี้จะแสดงวิธีสร้างสำเนาโค้ดตัวอย่างในเครื่องโดยใช้เครื่องมือบรรทัดคำสั่ง git

วิธีดาวน์โหลดโค้ดตัวอย่าง

  1. โคลนที่เก็บ Git โดยใช้คำสั่งต่อไปนี้
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. คุณอาจกำหนดค่าอินสแตนซ์ Git ให้ใช้การชำระเงินแบบ Sparse เพื่อให้มีเฉพาะไฟล์สำหรับแอปตัวอย่าง Image Generator ก็ได้
    cd mediapipe-samples
    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 ซึ่งใช้เพื่อปรับแต่งโมเดลพื้นฐาน และช่วยให้โมเดลสร้างรูปภาพของแนวคิดที่เฉพาะเจาะจงได้

ตั้งค่า

ส่วนนี้จะอธิบายขั้นตอนสำคัญในการตั้งค่าสภาพแวดล้อมในการพัฒนาและ โปรเจ็กต์โค้ดเพื่อใช้เครื่องมือสร้างรูปภาพโดยเฉพาะ ดูข้อมูลทั่วไปเกี่ยวกับการตั้งค่าสภาพแวดล้อมการพัฒนาเพื่อใช้ MediaPipe Tasks รวมถึงข้อกำหนดด้านเวอร์ชันแพลตฟอร์มได้ที่คู่มือการตั้งค่าสำหรับ Android

แท็กเริ่มการทำงาน

งาน Image Generator ใช้ไลบรารี com.google.mediapipe:tasks-vision-image-generator เพิ่มทรัพยากร Dependency นี้ ลงในไฟล์ 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 กำหนดให้ต้องมีโมเดลพื้นฐานที่ผ่านการฝึกมาแล้วซึ่งเข้ากันได้ กับงานนี้ หลังจากดาวน์โหลดโมเดลแล้ว ให้ติดตั้งการขึ้นต่อกันที่จำเป็นและ แปลงโมเดลเป็นรูปแบบที่เหมาะสม จากนั้นพุชโมเดลที่แปลงแล้วไปยังอุปกรณ์ Android

ดูข้อมูลเพิ่มเติมเกี่ยวกับโมเดลที่ผ่านการฝึกที่พร้อมใช้งานสำหรับเครื่องมือสร้างรูปภาพได้ที่ส่วนโมเดลในภาพรวมของงาน

ดาวน์โหลดโมเดลพื้นฐาน

เครื่องมือสร้างรูปภาพกำหนดให้โมเดลพื้นฐานต้องตรงกับ stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only รูปแบบโมเดลตาม โมเดล stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only

ติดตั้งการอ้างอิงและแปลงโมเดล

$ 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 หรือดาวน์โหลดตามต้องการ โมเดลปลั๊กอิน มีขนาดเล็ก (~23MB) และสามารถรวมไว้ใน APK ได้โดยตรง อย่างไรก็ตาม เราขอแนะนำให้ดาวน์โหลดโมเดลปลั๊กอินตามต้องการ

หากคุณปรับแต่งโมเดลด้วย LoRA ให้ดาวน์โหลดตามต้องการ ดูข้อมูลเพิ่มเติมได้ที่โมเดลปลั๊กอินน้ำหนัก LoRA

สร้างงาน

งาน MediaPipe Image Generator ใช้ฟังก์ชัน createFromOptions() เพื่อตั้งค่างาน ฟังก์ชัน createFromOptions() ยอมรับค่าสำหรับตัวเลือกการกำหนดค่า ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกการกำหนดค่าได้ที่ตัวเลือกการกำหนดค่า

ตัวเลือกการกำหนดค่า

งานนี้มีตัวเลือกการกำหนดค่าต่อไปนี้สำหรับแอป Android

ชื่อตัวเลือก คำอธิบาย ช่วงค่า
imageGeneratorModelDirectory ไดเรกทอรีโมเดลเครื่องมือสร้างรูปภาพที่จัดเก็บน้ำหนักของโมเดล PATH
loraWeightsFilePath กำหนดเส้นทางไปยังไฟล์น้ำหนัก LoRA ไม่บังคับและใช้ได้เฉพาะในกรณีต่อไปนี้ โมเดลได้รับการปรับแต่งด้วย LoRA PATH
errorListener ตั้งค่าเครื่องมือฟังข้อผิดพลาดที่ไม่บังคับ N/A

นอกจากนี้ งานยังรองรับโมเดลปลั๊กอิน ซึ่งช่วยให้ผู้ใช้ใส่รูปภาพเงื่อนไข ในอินพุตของงานได้ ซึ่งโมเดลพื้นฐานสามารถเพิ่มและใช้เป็นข้อมูลอ้างอิง สำหรับการสร้างได้ รูปภาพเงื่อนไขเหล่านี้อาจเป็นจุดสังเกตบนใบหน้า เส้นขอบ และ การประมาณความลึก ซึ่งโมเดลจะใช้เป็นบริบทและข้อมูลเพิ่มเติมเพื่อ สร้างรูปภาพ

เมื่อเพิ่มโมเดลปลั๊กอินลงในโมเดลพื้นฐาน ให้กำหนดค่าตัวเลือกปลั๊กอินด้วย ปลั๊กอินจุดสังเกตบนใบหน้าใช้ faceConditionOptions ปลั๊กอิน Canny Edge ใช้ edgeConditionOptions และปลั๊กอินความลึกใช้ depthConditionOptions

ตัวเลือกขอบ Canny

กำหนดค่าตัวเลือกต่อไปนี้ใน edgeConditionOptions

ชื่อตัวเลือก คำอธิบาย ช่วงค่า ค่าเริ่มต้น
threshold1 เกณฑ์แรกสำหรับกระบวนการฮิสเทอรีซิส Float 100
threshold2 เกณฑ์ที่ 2 สำหรับกระบวนการฮิสเทอรีซิส Float 200
apertureSize ขนาดรูรับแสงสำหรับตัวดำเนินการ Sobel ช่วงปกติอยู่ระหว่าง 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
  • Seed (ต้องระบุ): Seed แบบสุ่มที่ใช้ระหว่างการสร้างรูปภาพ
  • รูปภาพสภาพ (ไม่บังคับ): รูปภาพที่โมเดลใช้เป็นข้อมูลอ้างอิงสำหรับการสร้าง ใช้ได้เมื่อใช้โมเดลปลั๊กอินเท่านั้น
  • ประเภทเงื่อนไข (ไม่บังคับ): ประเภทโมเดลปลั๊กอินที่ใช้กับงาน ใช้ได้เมื่อใช้โมเดลปลั๊กอินเท่านั้น

อินพุตที่มีเฉพาะโมเดลพื้นฐาน

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() เพื่อสร้างรูปภาพโดยใช้ข้อมูลที่ระบุไว้ใน ส่วนก่อนหน้า ซึ่งจะสร้างรูปภาพที่สร้างขึ้น 1 รูป

สร้างโดยใช้เฉพาะโมเดลพื้นฐาน

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
}

การสร้างแบบวนซ้ำ

นอกจากนี้ Image Generator ยังสามารถแสดงรูปภาพระดับกลางที่สร้างขึ้นระหว่างการทำซ้ำแต่ละครั้งได้ตามที่กำหนดไว้ใน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())

รูปภาพต่อไปนี้สร้างขึ้นจากอินพุตต่อไปนี้โดยใช้โมเดลพื้นฐานเท่านั้น

อินพุต:

  • พรอมต์: "แรคคูนการ์ตูนสีสันสดใสสวมหมวกปีกกว้าง ถือไม้เท้าเดินผ่านป่า ภาพเคลื่อนไหว มุม 3/4 ภาพวาด"
  • Seed: 312687592
  • การวนซ้ำ: 20

รูปภาพที่สร้างขึ้น:

รูปภาพที่สร้างขึ้นของแรคคูนซึ่งสอดคล้องกับพรอมต์