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

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

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

ตั้งค่า

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

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

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

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

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

สร้างงาน

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

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

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

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

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

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

ตัวเลือกขอบด้านข้าง

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

ชื่อตัวเลือก คำอธิบาย ช่วงค่า ค่าเริ่มต้น
threshold1 เกณฑ์แรกสำหรับขั้นตอนการตัดหญ้า Float 100
threshold2 เกณฑ์ที่ 2 สำหรับขั้นตอนการตัดหญ้า (Hysteresis ขั้นตอน) 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)
    

ทรง 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)
    

ความลึก

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 ส่วน ภาพวาด"
  • ซีด: 312687592
  • การทำซ้ำ: 20

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