งาน MediaPipe Image Embedder ให้คุณแปลงข้อมูลรูปภาพเป็นรูปแบบตัวเลข เพื่อทำงานการประมวลผลรูปภาพที่เกี่ยวข้องกับ ML เช่น การเปรียบเทียบ ความคล้ายคลึงกันของรูปภาพสองรูป วิธีการเหล่านี้จะแสดงวิธีใช้ เครื่องมือฝังรูปภาพด้วยแอป Android
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความสามารถ โมเดล และตัวเลือกการกำหนดค่า ของงานนี้ โปรดดูภาพรวม
ตัวอย่างโค้ด
โค้ดตัวอย่าง MediaPipe Tasks เป็นการใช้งานที่เรียบง่ายของเครื่องมือฝังรูปภาพ แอปสำหรับ Android ตัวอย่างนี้ใช้กล้องบนอุปกรณ์ Android จริงเพื่อ ฝังรูปภาพอย่างต่อเนื่อง และยังเรียกใช้เครื่องมือฝังกับไฟล์ภาพที่จัดเก็บไว้ได้ด้วย ในอุปกรณ์
คุณสามารถใช้แอปนี้เป็นจุดเริ่มต้นสำหรับแอป Android ของคุณเอง หรืออ้างอิงถึงแอปนั้น เมื่อแก้ไขแอปที่มีอยู่ โค้ดตัวอย่างของเครื่องมือฝังรูปภาพโฮสต์อยู่บน GitHub
ดาวน์โหลดโค้ด
วิธีการต่อไปนี้แสดงวิธีสร้างสำเนาตัวอย่างในเครื่อง โดยใช้เครื่องมือบรรทัดคำสั่ง git
วิธีดาวน์โหลดโค้ดตัวอย่าง
- โคลนที่เก็บ Git โดยใช้คำสั่งต่อไปนี้
git clone https://github.com/google-ai-edge/mediapipe-samples
- นอกจากนี้ คุณสามารถกำหนดค่าอินสแตนซ์ Git ให้ใช้การชำระเงินแบบกระจัดกระจายเพื่อให้คุณมี
เฉพาะไฟล์สำหรับแอปตัวอย่างเครื่องมือฝังรูปภาพเท่านั้น
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_embedder/android
หลังจากสร้างโค้ดตัวอย่างในเวอร์ชันในเครื่องแล้ว คุณจะนำเข้าโปรเจ็กต์ได้ ลงใน Android Studio และเรียกใช้แอป โปรดดูวิธีการในคู่มือการตั้งค่าสำหรับ Android
องค์ประกอบหลัก
ไฟล์ต่อไปนี้มีโค้ดที่สำคัญสำหรับตัวอย่างเครื่องมือฝังภาพนี้ แอปพลิเคชัน:
- ImageEmbedderHelper.kt: เริ่มต้นเครื่องมือฝังรูปภาพและจัดการโมเดลและมอบสิทธิ์ มากมาย
- MainActivity.kt: ใช้งานแอปพลิเคชันและประกอบคอมโพเนนต์อินเทอร์เฟซผู้ใช้
ตั้งค่า
ส่วนนี้จะอธิบายขั้นตอนสำคัญในการตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ และ โค้ดเพื่อใช้เครื่องมือฝังรูปภาพ สำหรับข้อมูลทั่วไปเกี่ยวกับการตั้งค่า สภาพแวดล้อมในการพัฒนาซอฟต์แวร์สำหรับการใช้งาน MediaPipe ซึ่งรวมถึงเวอร์ชันแพลตฟอร์ม โปรดดูคู่มือการตั้งค่าสำหรับ Android
การอ้างอิง
เครื่องมือฝังรูปภาพใช้ไลบรารี com.google.mediapipe:tasks-vision
เพิ่มรายการนี้
จะขึ้นอยู่กับไฟล์ build.gradle
ของโปรเจ็กต์การพัฒนาแอป Android ของคุณ
นำเข้าทรัพยากร Dependency ที่จำเป็นด้วยโค้ดต่อไปนี้
dependencies {
...
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
รุ่น
งาน MediaPipe Image Embedder ต้องใช้โมเดลที่ผ่านการฝึกซึ่งสามารถทำงานร่วมกับไฟล์ดังกล่าวได้ งาน สำหรับข้อมูลเพิ่มเติมเกี่ยวกับโมเดลที่ผ่านการฝึกที่ใช้ได้สำหรับเครื่องมือฝังรูปภาพ โปรดดู ภาพรวมงานส่วนโมเดล
เลือกและดาวน์โหลดโมเดล จากนั้นเก็บโมเดลไว้ในไดเรกทอรีโปรเจ็กต์ของคุณ:
<dev-project-root>/src/main/assets
ระบุเส้นทางของโมเดลภายในพารามิเตอร์ ModelAssetPath
ใน
โค้ดตัวอย่าง โมเดลจะได้รับการกำหนดในฟังก์ชัน setupImageEmbedder()
ใน
ImageEmbedderHelper.kt
ไฟล์:
ใช้เมธอด BaseOptions.Builder.setModelAssetPath()
เพื่อระบุเส้นทาง
ที่โมเดลใช้อยู่ มีการอ้างอิงเมธอดนี้ในตัวอย่างโค้ดถัดไป
สร้างงาน
คุณใช้ฟังก์ชัน createFromOptions
เพื่อสร้างงานได้
ฟังก์ชัน createFromOptions
ยอมรับตัวเลือกการกำหนดค่าเพื่อตั้งค่าเครื่องมือฝัง
ตัวเลือก โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกการกําหนดค่าได้ที่การกําหนดค่า
ภาพรวม
งานเครื่องมือฝังรูปภาพรองรับอินพุต 3 ประเภท ได้แก่ ภาพนิ่ง ไฟล์วิดีโอ และสตรีมวิดีโอสด คุณต้องระบุโหมดการทำงานที่สอดคล้องกับ ประเภทข้อมูลอินพุตเมื่อสร้างงาน เลือกแท็บที่ตรงกับ ประเภทข้อมูลอินพุตเพื่อดูวิธีสร้างงานและเรียกใช้การอนุมาน
รูปภาพ
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.IMAGE) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
วิดีโอ
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.VIDEO) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
สตรีมแบบสด
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.LIVE_STREAM) .setResultListener((result, inputImage) -> { // Process the embedding result here. }) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
ตัวอย่างการติดตั้งโค้ดทำให้ผู้ใช้สลับไปมาได้ระหว่างการประมวลผล
โหมดต่างๆ วิธีนี้ทำให้โค้ดการสร้างงานซับซ้อนขึ้นและอาจไม่
เหมาะสำหรับกรณีการใช้งานของคุณ คุณดูรหัสนี้ได้ใน
setupImageEmbedder()
ในฟังก์ชัน
ImageEmbedderHelper.kt
ตัวเลือกการกำหนดค่า
งานนี้มีตัวเลือกการกำหนดค่าต่อไปนี้สำหรับแอป Android
ชื่อตัวเลือก | คำอธิบาย | ช่วงค่า | ค่าเริ่มต้น |
---|---|---|---|
runningMode |
ตั้งค่าโหมดการทำงานสำหรับงาน มี 3 แบบ
โหมด: รูปภาพ: โหมดสำหรับอินพุตรูปภาพเดียว วิดีโอ: โหมดสำหรับเฟรมที่ถอดรหัสของวิดีโอ LIVE_STREAM: โหมดสำหรับสตรีมแบบสดของอินพุต เช่น ข้อมูลจากกล้อง ในโหมดนี้ resultsListener ต้องเป็น ถูกเรียกให้ตั้งค่า Listener เพื่อรับผลลัพธ์ แบบไม่พร้อมกัน |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
l2_normalize |
เลือกว่าจะแปลงเวกเตอร์ฟีเจอร์ที่ส่งคืนด้วยบรรทัดฐาน L2 หรือไม่ ใช้ตัวเลือกนี้เฉพาะในกรณีที่โมเดลไม่มีโฆษณาเนทีฟ L2_NORMALIZATION TFLite Op. ในกรณีส่วนใหญ่ กรณีเช่นนี้มักจะเกิดขึ้น และ การปรับมาตรฐาน L2 จึงทำได้ผ่านการอนุมาน TFLite โดยไม่จำเป็นต้อง สำหรับตัวเลือกนี้ | Boolean |
False |
quantize |
ควรแปลงการฝังที่แสดงผลเป็นไบต์เป็นไบต์ผ่านหรือไม่ การวัดสเกลาร์ การฝังจะถูกสันนิษฐานโดยนัยว่าเป็นหน่วยบรรทัดฐานและ ดังนั้น ทุกมิติข้อมูลต้องมีค่าเป็น [-1.0, 1.0] ใช้ ตัวเลือก l2_normalize หากไม่เป็นเช่นนั้น | Boolean |
False |
resultListener |
ตั้งค่า Listener ผลลัพธ์เพื่อรับผลลัพธ์การฝัง
แบบไม่พร้อมกันเมื่อเครื่องมือฝังรูปภาพอยู่ในสตรีมแบบสด
ใช้ได้เมื่อตั้งค่าโหมดวิ่งเป็น LIVE_STREAM เท่านั้น |
ไม่มี | ไม่ได้ตั้งค่า |
errorListener |
ตั้งค่า Listener ข้อผิดพลาดที่ไม่บังคับ | ไม่มี | ไม่ได้ตั้งค่า |
เตรียมข้อมูล
เครื่องมือฝังรูปภาพใช้งานได้กับรูปภาพ ไฟล์วิดีโอ และวิดีโอสตรีมแบบสด งาน จัดการการประมวลผลอินพุตข้อมูลล่วงหน้า ซึ่งรวมถึงการปรับขนาด การหมุน และค่า การแปลงเป็นรูปแบบมาตรฐาน
คุณต้องแปลงรูปภาพหรือเฟรมอินพุตเป็น
com.google.mediapipe.framework.image.MPImage
ก่อนที่จะส่งไปยัง
งานเครื่องมือฝังรูปภาพ
รูปภาพ
import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Load an image on the user’s device as a Bitmap object using BitmapFactory. // Convert an Android’s Bitmap object to a MediaPipe’s Image object. Image mpImage = new BitmapImageBuilder(bitmap).build();
วิดีโอ
import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Load a video file on the user's device using MediaMetadataRetriever // From the video’s metadata, load the METADATA_KEY_DURATION and // METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them // to calculate the timestamp of each frame later. // Loop through the video and load each frame as a Bitmap object. // Convert the Android’s Bitmap object to a MediaPipe’s Image object. Image mpImage = new BitmapImageBuilder(frame).build();
สตรีมแบบสด
import com.google.mediapipe.framework.image.MediaImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Create a CameraX’s ImageAnalysis to continuously receive frames // from the device’s camera. Configure it to output frames in RGBA_8888 // format to match with what is required by the model. // For each Android’s ImageProxy object received from the ImageAnalysis, // extract the encapsulated Android’s Image object and convert it to // a MediaPipe’s Image object. android.media.Image mediaImage = imageProxy.getImage() Image mpImage = new MediaImageBuilder(mediaImage).build();
ในโค้ดตัวอย่าง การจัดเตรียมข้อมูลจะดำเนินการใน ImageEmbedderHelper.kt
เรียกใช้งาน
คุณสามารถเรียกใช้ฟังก์ชัน embed
ที่สอดคล้องกับโหมดการวิ่งเพื่อทริกเกอร์ได้
การอนุมาน API การฝังรูปภาพแสดงผลเวกเตอร์การฝังสำหรับอินพุต
รูปภาพหรือเฟรม
รูปภาพ
ImageEmbedderResult embedderResult = imageEmbedder.embed(image);
วิดีโอ
// Calculate the timestamp in milliseconds of the current frame. long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count; // Run inference on the frame. ImageEmbedderResult embedderResult = imageEmbedder.embedForVideo(image, frameTimestampMs);
สตรีมแบบสด
// Run inference on the frame. The embedding results will be available // via the `resultListener` provided in the `ImageEmbedderOptions` when // the image embedder was created. imageEmbedder.embedAsync(image, frameTimestampMs);
โปรดทราบดังต่อไปนี้
- เมื่อทำงานในโหมดวิดีโอหรือโหมดสตรีมแบบสด คุณต้อง ระบุการประทับเวลาของเฟรมอินพุตในงานเครื่องมือฝังรูปภาพ
- เมื่อทำงานในโหมดรูปภาพหรือวิดีโอ งานเครื่องมือฝังรูปภาพจะ บล็อกชุดข้อความปัจจุบันจนกว่าจะประมวลผลรูปภาพอินพุตเสร็จสิ้น หรือ เฟรม หากต้องการหลีกเลี่ยงการบล็อกเทรดปัจจุบัน ให้เรียกใช้การประมวลผลใน เทรดพื้นหลัง
- เมื่อทำงานในโหมดสตรีมแบบสด งานเครื่องมือฝังรูปภาพจะไม่บล็อก
ชุดข้อความปัจจุบันแต่จะแสดงอีกครั้งทันที ระบบจะเรียกใช้ผลลัพธ์
Listener พร้อมผลลัพธ์การตรวจจับทุกครั้งที่ประมวลผลเสร็จแล้ว
เฟรมอินพุต หากมีการเรียกฟังก์ชัน
embedAsync
เมื่อเครื่องมือฝังรูปภาพ งานไม่ว่างในการประมวลผลอีกเฟรมหนึ่ง งานจะไม่สนใจเฟรมอินพุตใหม่
ในโค้ดตัวอย่าง ฟังก์ชัน embed
กำหนดไว้ใน
ImageEmbedderHelper.kt
จัดการและแสดงผลลัพธ์
หลังจากเรียกใช้การอนุมาน งานเครื่องมือฝังรูปภาพจะแสดงผล ImageEmbedderResult
ที่มีรายการการฝัง (ทั้งจุดทศนิยมหรือ
สเกลาร์-ควอนซ์) สำหรับรูปภาพอินพุต
ตัวอย่างต่อไปนี้แสดงตัวอย่างข้อมูลเอาต์พุตจากงานนี้
ImageEmbedderResult:
Embedding #0 (sole embedding head):
float_embedding: {0.0, 0.0, ..., 0.0, 1.0, 0.0, 0.0, 2.0}
head_index: 0
ผลการค้นหานี้มาจากการฝังรูปภาพต่อไปนี้
คุณสามารถเปรียบเทียบความคล้ายคลึงกันของการฝัง 2 รายการโดยใช้
ImageEmbedder.cosineSimilarity
โปรดดูโค้ดต่อไปนี้สำหรับ
// Compute cosine similarity.
double similarity = ImageEmbedder.cosineSimilarity(
result.embeddingResult().embeddings().get(0),
otherResult.embeddingResult().embeddings().get(0));