การสร้างรูปภาพในอุปกรณ์บน Android ด้วย MediaPipe

1. บทนำ

MediaPipe คืออะไร

MediaPipe Solutions ให้คุณนำโซลูชันแมชชีนเลิร์นนิง (ML) ไปใช้กับแอป โดยมีเฟรมเวิร์กสำหรับกำหนดค่าไปป์ไลน์การประมวลผลที่สร้างไว้ล่วงหน้าซึ่งจะให้ผลลัพธ์ที่เป็นประโยชน์ น่าสนใจ และมีประโยชน์แก่ผู้ใช้ได้ทันที คุณยังสามารถปรับแต่งโซลูชันจำนวนมากเหล่านี้ได้ด้วย MediaPipe Model Maker เพื่ออัปเดตโมเดลเริ่มต้น

การสร้างข้อความเป็นรูปภาพเป็นหนึ่งในงาน ML มากมายที่ MediaPipe Solutions มีให้

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

สิ่งที่คุณจะได้เรียนรู้

  • วิธีใช้การสร้างข้อความเป็นรูปภาพที่ทำงานในแอป Android ในเครื่องด้วย MediaPipe Tasks

สิ่งที่ต้องมี

  • Android Studio เวอร์ชันติดตั้ง (Codelab นี้เขียนและทดสอบด้วย Android Studio Giraffe)
  • อุปกรณ์ Android ที่มี RAM อย่างน้อย 8 GB
  • ความรู้พื้นฐานเกี่ยวกับการพัฒนา Android และความสามารถในการเรียกใช้สคริปต์ Python ที่เขียนไว้ล่วงหน้า

2. เพิ่มงาน MediaPipe ลงในแอป Android

ดาวน์โหลดแอปเริ่มต้นสำหรับ Android

Codelab นี้จะเริ่มต้นด้วยตัวอย่างที่ทำไว้ล่วงหน้าซึ่งประกอบไปด้วย UI ที่จะใช้ในการสร้างรูปภาพเวอร์ชันพื้นฐาน คุณสามารถค้นหาแอปเริ่มต้นในที่เก็บ MediaPipe Samples อย่างเป็นทางการได้ที่นี่ โคลนที่เก็บหรือดาวน์โหลดไฟล์ ZIP โดยคลิก โค้ด > ดาวน์โหลด ZIP

นำเข้าแอปไปยัง Android Studio

  1. เปิด Android Studio
  2. จากหน้าจอยินดีต้อนรับสู่ Android Studio ให้เลือกเปิดที่มุมบนขวา

a0b5b070b802e4ea.png

  1. ไปยังตำแหน่งที่คุณโคลนหรือดาวน์โหลดที่เก็บ แล้วเปิดไดเรกทอรี codelabs/image_generation_basic/android/start
  2. ในขั้นตอนนี้ แอปไม่ควรคอมไพล์เนื่องจากคุณยังไม่ได้รวมทรัพยากร Dependency ของ MediaPipe Tasks

คุณจะแก้ไขแอปและทำให้แอปทำงานได้ โดยไปที่ไฟล์ build.gradle และเลื่อนลงไปที่// ขั้นตอนที่ 1 - เพิ่มทรัพยากร Dependency จากนั้นให้ใส่บรรทัดต่อไปนี้แล้วกดปุ่มซิงค์เลยที่ปรากฏในแบนเนอร์ที่ด้านบนของ Android Studio

// Step 1 - Add dependency
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'

เมื่อการซิงค์เสร็จสิ้นแล้ว ให้ตรวจสอบว่าทุกอย่างเปิดและติดตั้งอย่างถูกต้องโดยคลิกที่ลูกศรเรียกใช้สีเขียว ( 7e15a9c9e1620fe7.png) ที่ด้านบนขวาของ Android Studio คุณควรเห็นแอปเปิดขึ้นในหน้าจอที่มีปุ่มตัวเลือก 2 ปุ่ม และปุ่มเริ่มต้น หากคุณคลิกปุ่มดังกล่าว ระบบจะนำคุณไปยัง UI แยกต่างหากทันที ซึ่งประกอบด้วยพรอมต์ข้อความและตัวเลือกอื่นๆ ควบคู่ไปกับปุ่มสร้าง

83c31de8e8a320ee.png 78b8765e832024e3.png

เราต้องขออภัยที่เกี่ยวกับขอบเขตของแอปเริ่มต้น ดังนั้นถึงเวลาที่คุณจะได้เรียนรู้วิธีสร้างแอปนี้ให้เสร็จและเริ่มสร้างรูปภาพใหม่บนอุปกรณ์

3. การตั้งค่าเครื่องมือสร้างรูปภาพ

ในตัวอย่างนี้ การสร้างรูปภาพส่วนใหญ่จะเกิดขึ้นในไฟล์ ImageGenerationHelper.kt เมื่อเปิดไฟล์นี้ คุณจะเห็นตัวแปรอยู่ด้านบนของคลาสที่เรียกว่า imageGenerator ซึ่งเป็นออบเจ็กต์งานที่จะช่วยให้แอปสร้างรูปภาพทำงานหนัก

คุณจะเห็นฟังก์ชันชื่อ beginizeImageGenerator() ด้านล่างออบเจ็กต์ดังกล่าว // ขั้นตอนที่ 2 - เริ่มโปรแกรมสร้างรูปภาพ คุณน่าจะเดาได้ว่านี่คือที่ที่คุณจะเริ่มต้นออบเจ็กต์ ImageGenerator แทนที่เนื้อหาของฟังก์ชันด้วยโค้ดต่อไปนี้เพื่อตั้งค่าเส้นทางโมเดลการสร้างรูปภาพและเริ่มต้นออบเจ็กต์ ImageGenerator

// Step 2 - initialize the image generator
val options = ImageGeneratorOptions.builder()
    .setImageGeneratorModelDirectory(modelPath)
    .build()

imageGenerator = ImageGenerator.createFromOptions(context, options)

คุณจะเห็นฟังก์ชันอื่นชื่อ setInput() อยู่ด้านล่าง ซึ่งยอมรับพารามิเตอร์ 3 ตัว ได้แก่ สตริง prompt ที่จะใช้เพื่อกำหนดรูปภาพที่สร้างขึ้น จำนวนการทำซ้ำที่งานควรดำเนินการขณะสร้างรูปภาพใหม่ และค่า seed ที่ใช้สร้างเวอร์ชันใหม่ของรูปภาพได้ โดยอิงตามพรอมต์เดียวกันขณะสร้างรูปภาพเดียวกันเมื่อมีการใช้ Seed เดียวกัน วัตถุประสงค์ของฟังก์ชันนี้คือตั้งค่าพารามิเตอร์เริ่มต้นเหล่านี้สำหรับโปรแกรมสร้างรูปภาพเมื่อคุณพยายามสร้างรูปภาพที่แสดงขั้นตอนระดับกลาง

ดำเนินการต่อแล้วแทนที่เนื้อหา setInput() (ซึ่งคุณจะเห็นความคิดเห็น // ขั้นตอนที่ 3 - ยอมรับอินพุต) ด้วยบรรทัดนี้

// Step 3 - accept inputs
imageGenerator.setInputs(prompt, iteration, seed)

2 ขั้นตอนถัดไปคือจุดเริ่มต้นของการสร้าง ฟังก์ชัน generate() จะยอมรับอินพุตเดียวกันกับ setInput แต่จะสร้างรูปภาพเป็นการเรียกใช้ครั้งเดียวโดยไม่แสดงรูปขั้นตอนระดับกลาง คุณสามารถแทนที่เนื้อหาของฟังก์ชันนี้ (ซึ่งรวมถึงความคิดเห็น // ขั้นตอนที่ 4 สร้างโดยไม่แสดงซ้ำ) ด้วยคำสั่งต่อไปนี้

// Step 4 - generate without showing iterations
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap

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

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

// Step 5 - generate with iterations
val result = imageGenerator.execute(showResult)

if (result == null || result.generatedImage() == null) {
    return Bitmap.createBitmap(512, 512, Bitmap.Config.ARGB_8888)
        .apply {
            val canvas = Canvas(this)
            val paint = Paint()
            paint.color = Color.WHITE
            canvas.drawPaint(paint)
        }
}

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

return bitmap

และทั้งหมดนี้คือไฟล์ Helper ในส่วนถัดไป คุณจะต้องกรอกข้อมูลในไฟล์ ViewModel ที่จัดการตรรกะสำหรับตัวอย่างนี้

4. รวมแอปไว้ด้วยกัน

ไฟล์ MainViewModel จะจัดการสถานะ UI และตรรกะอื่นๆ ที่เกี่ยวข้องกับแอปตัวอย่างนี้ เปิดดูได้เลย

บริเวณด้านบนของไฟล์ คุณควรเห็นความคิดเห็น // ขั้นตอนที่ 6 - ตั้งค่าเส้นทางโมเดล ซึ่งเป็นที่ที่คุณจะบอกให้แอปหาไฟล์โมเดลที่จำเป็นสำหรับการสร้างรูปภาพได้ สำหรับตัวอย่างนี้ คุณจะกำหนดค่าเป็น /data/local/tmp/image_generator/bins/

// Step 6 - set model path
private val MODEL_PATH = "/data/local/tmp/image_generator/bins/"

จากตรงนั้น ให้เลื่อนลงไปที่ฟังก์ชัน generateImage() ที่ด้านล่างของฟังก์ชันนี้คุณจะเห็นทั้งขั้นตอนที่ 7 และ 8 ซึ่งระบบจะใช้ในการสร้างรูปภาพที่มีการแสดงผลซ้ำหรือไม่แสดงตามลำดับ เนื่องจากการดำเนินการทั้ง 2 อย่างนี้เกิดขึ้นพร้อมกัน คุณจะสังเกตได้ว่าการดำเนินการทั้ง 2 อย่างนี้อยู่ในคอร์บูทีน คุณสามารถเริ่มต้นได้โดยแทนที่ // ขั้นตอนที่ 7 - สร้างโดยไม่แสดงการทำซ้ำด้วยบล็อกโค้ดนี้เพื่อเรียก generate() จากไฟล์ ImageGenerationHelper จากนั้นอัปเดตสถานะ UI

// Step 7 - Generate without showing iterations
val result = helper?.generate(prompt, iteration, seed)
_uiState.update {
    it.copy(outputBitmap = result)
}

ขั้นตอนที่ 8 จะยากขึ้นเล็กน้อย เนื่องจากฟังก์ชันExecut() จะดำเนินการเพียง 1 ขั้นตอนแทนที่จะเป็นทั้งหมดขั้นตอนในการสร้างรูปภาพ คุณจึงต้องเรียกใช้แต่ละขั้นตอนทีละรายการผ่านการวนซ้ำ คุณยังต้องกําหนดด้วยว่าควรแสดงขั้นตอนปัจจุบันให้ผู้ใช้หรือไม่ ขั้นตอนสุดท้าย คุณจะต้องอัปเดตสถานะ UI หากการทำซ้ำปัจจุบันควรแสดง คุณสามารถทำทั้งหมดนี้ได้เลย

// Step 8 - Generate with showing iterations
helper?.setInput(prompt, iteration, seed)
for (step in 0 until iteration) {
    isDisplayStep =
        (displayIteration > 0 && ((step + 1) % displayIteration == 0))
    val result = helper?.execute(isDisplayStep)

    if (isDisplayStep) {
        _uiState.update {
            it.copy(
                outputBitmap = result,
                generatingMessage = "Generating... (${step + 1}/$iteration)",
            )
        }
    }
}

เมื่อถึงจุดนี้ คุณควรติดตั้งแอป เริ่มต้นโปรแกรมสร้างรูปภาพ แล้วสร้างรูปภาพใหม่ตามพรอมต์ข้อความได้

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

นอกจากการคัดลอกไฟล์ไปยังอุปกรณ์การพัฒนาโดยตรงแล้ว คุณยังตั้งค่าพื้นที่เก็บข้อมูลของ Firebase ให้ดาวน์โหลดไฟล์ที่จำเป็นไปยังอุปกรณ์ของผู้ใช้โดยตรงขณะรันไทม์ได้ด้วย

5. ติดตั้งใช้งานและทดสอบแอป

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

  1. คลิกเรียกใช้ ( 7e15a9c9e1620fe7.png) ในแถบเครื่องมือ Android Studio เพื่อเรียกใช้แอป
  2. เลือกประเภทของขั้นตอนการสร้าง (ขั้นสุดท้ายหรือด้วยการทำซ้ำ) แล้วกดปุ่มเริ่มต้น
  3. ในหน้าจอถัดไป ให้ตั้งค่าพร็อพเพอร์ตี้ที่ต้องการแล้วคลิกปุ่มสร้าง เพื่อดูลักษณะของเครื่องมือ

e46cfaeb9d3fc235.gif

6. ยินดีด้วย

สำเร็จแล้ว! ใน Codelab นี้ คุณได้เรียนรู้วิธีเพิ่มการสร้างข้อความเป็นรูปภาพในอุปกรณ์ลงในแอป Android แล้ว

ขั้นตอนถัดไป

การดำเนินการอื่นๆ ที่คุณทำได้กับงานสร้างรูปภาพ ได้แก่

  • การใช้อิมเมจฐานเพื่อจัดโครงสร้างรูปภาพที่สร้างขึ้นผ่านปลั๊กอิน หรือฝึกน้ำหนัก LoRA เพิ่มเติมของคุณเองผ่าน Vertex AI
  • ใช้พื้นที่เก็บข้อมูลของ Firebase เพื่อเรียกไฟล์โมเดลในอุปกรณ์โดยไม่ต้องใช้เครื่องมือ ADB

เราตื่นเต้นที่จะได้ดูสิ่งดีๆ ทั้งหมดที่คุณทำร่วมกับงานทดลองนี้ และรอดู Codelab และเนื้อหาเพิ่มเติมจากทีม MediaPipe ด้วยนะ