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

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

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

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

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

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

ดาวน์โหลดโค้ด

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

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

  1. โคลนที่เก็บ Git โดยใช้คำสั่งต่อไปนี้
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. (ไม่บังคับ) กำหนดค่าอินสแตนซ์ Git เพื่อใช้การชำระเงินแบบกระจัดกระจาย เพื่อให้คุณมีเฉพาะไฟล์สำหรับแอปตัวอย่างของโปรแกรมสร้างรูปภาพ ดังนี้
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_generator/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 เพิ่มทรัพยากร Dependency นี้ ลงในไฟล์ build.gradle ของแอป Android

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

สำหรับอุปกรณ์ที่ใช้ Android 12 (API 31) ขึ้นไป ให้เพิ่มค่า Dependency ของไลบรารี OpenCL แบบเนทีฟไปยัง AndroidManifest.xml ดูข้อมูลเพิ่มเติมได้ในเอกสารในแท็ก uses-native-library

อุปกรณ์ Android บางรุ่นอาจต้องใช้ไลบรารีเพิ่มเติม:

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

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

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

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

ติดตั้งทรัพยากร Dependency และแปลงโมเดล

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

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

สร้างงาน

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

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

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

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

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

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

ตัวเลือกขอบแบบไม่มีข้อมูล

กำหนดค่าตัวเลือกต่อไปนี้ใน 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

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของตัวเลือกการกำหนดค่าเหล่านี้ได้ที่งานจุดสังเกตสำหรับใบหน้า

ตัวเลือกความลึก

กำหนดค่าตัวเลือกต่อไปนี้ใน 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)

เตรียมข้อมูล

เครื่องมือสร้างรูปภาพยอมรับอินพุตต่อไปนี้

  • prompt (ต้องระบุ): พรอมต์ข้อความที่อธิบายรูปภาพที่จะสร้าง
  • iterations (จำเป็น): จำนวนครั้งทั้งหมดในการสร้างรูปภาพ จุดเริ่มต้นที่ดีคือ 20
  • seed (ต้องระบุ): Seed แบบสุ่มที่ใช้ระหว่างการสร้างรูปภาพ
  • รูปภาพสภาพสินค้า (ไม่บังคับ): รูปภาพที่โมเดลใช้เป็นข้อมูลอ้างอิงสำหรับการสร้าง ใช้ได้เฉพาะเมื่อใช้โมเดลปลั๊กอิน
  • condition type (ไม่บังคับ): ประเภทโมเดลปลั๊กอินที่ใช้กับงาน ใช้ได้เฉพาะเมื่อใช้โมเดลปลั๊กอิน

ข้อมูลที่มีเฉพาะรูปแบบพื้นฐาน

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

สร้างโดยใช้โมเดลพื้นฐานเท่านั้น

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())

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

อินพุต:

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

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