ภารกิจตัวตรวจจับวัตถุช่วยให้คุณตรวจหาการมีอยู่และตำแหน่งของวัตถุหลายคลาสได้ เช่น เครื่องมือตรวจจับวัตถุสามารถหาตำแหน่งสุนัขในรูปภาพ วิธีการเหล่านี้แสดงวิธีใช้งานตัวตรวจจับวัตถุใน Android ตัวอย่างโค้ดที่อธิบายในวิธีการเหล่านี้มีอยู่ใน GitHub คุณสามารถดูการทํางานของงานนี้ได้โดยดูการสาธิตบนเว็บนี้ ดูข้อมูลเพิ่มเติมเกี่ยวกับความสามารถ รูปแบบ และตัวเลือกการกําหนดค่าของงานนี้ได้ที่ภาพรวม
ตัวอย่างโค้ด
โค้ดตัวอย่างของ 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/object_detection/android
หลังจากสร้างโค้ดตัวอย่างเวอร์ชันในเครื่องแล้ว คุณสามารถนําเข้าโปรเจ็กต์ไปยัง Android Studio และเรียกใช้แอปได้ ดูวิธีการได้ที่คู่มือการตั้งค่าสําหรับ Android
คอมโพเนนต์หลัก
ไฟล์ต่อไปนี้มีโค้ดสําคัญสําหรับแอปพลิเคชันตัวอย่างของโปรแกรมตรวจจับวัตถุ
- ObjectDetectorHelper.kt - เริ่มต้นตัวตรวจจับวัตถุและจัดการโมเดลและการเลือกตัวแทน
- MainActivity.kt - ใช้แอปพลิเคชันและประกอบคอมโพเนนต์อินเทอร์เฟซผู้ใช้
- OverlayView.kt - จัดการและแสดงผลลัพธ์
ตั้งค่า
ส่วนนี้จะอธิบายขั้นตอนสำคัญในการตั้งค่าสภาพแวดล้อมการพัฒนาและโปรเจ็กต์โค้ดเพื่อใช้เครื่องมือตรวจจับวัตถุ ดูข้อมูลทั่วไปเกี่ยวกับการตั้งค่าสภาพแวดล้อมการพัฒนาเพื่อใช้งาน MediaPipe รวมถึงข้อกำหนดเวอร์ชันแพลตฟอร์มได้ที่คู่มือการตั้งค่าสำหรับ Android
การอ้างอิง
ตัวตรวจจับวัตถุใช้ไลบรารี com.google.mediapipe:tasks-vision
เพิ่มข้อกำหนดนี้ลงในไฟล์ build.gradle
ของโปรเจ็กต์การพัฒนาแอป Android นําเข้าข้อกําหนดเบื้องต้นที่จําเป็นด้วยโค้ดต่อไปนี้
dependencies {
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
รุ่น
ภารกิจของ MediaPipe Object Detector ต้องใช้โมเดลที่ผ่านการฝึกซึ่งเข้ากันได้กับภารกิจนี้ ดูข้อมูลเพิ่มเติมเกี่ยวกับโมเดลที่ผ่านการฝึกอบรมแล้วสำหรับตัวตรวจจับวัตถุได้ที่ส่วนโมเดลในภาพรวมของงาน
เลือกและดาวน์โหลดโมเดล จากนั้นจัดเก็บไว้ในไดเรกทอรีโปรเจ็กต์
<dev-project-root>/src/main/assets
ใช้เมธอด BaseOptions.Builder.setModelAssetPath()
เพื่อระบุเส้นทางที่โมเดลใช้ ดูตัวอย่างโค้ดได้ที่ส่วนถัดไป
สร้างงาน
คุณสามารถใช้ฟังก์ชัน createFromOptions
เพื่อสร้างงาน ฟังก์ชัน createFromOptions
ยอมรับตัวเลือกการกําหนดค่า ซึ่งรวมถึงโหมดการทํางาน ภาษาของชื่อที่แสดง จํานวนผลลัพธ์สูงสุด เกณฑ์ความเชื่อมั่น รายการที่อนุญาตและรายการที่ปฏิเสธของหมวดหมู่ หากไม่ได้ระบุตัวเลือกการกําหนดค่า ระบบจะใช้ค่าเริ่มต้น ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกการกำหนดค่าได้ที่ภาพรวมการกําหนดค่า
ภารกิจตัวตรวจจับวัตถุรองรับข้อมูลอินพุต 3 ประเภท ได้แก่ ภาพนิ่ง ไฟล์วิดีโอ และวิดีโอสตรีมแบบสด คุณต้องระบุโหมดการทํางานที่สอดคล้องกับประเภทข้อมูลอินพุตเมื่อสร้างงาน เลือกแท็บที่สอดคล้องกับประเภทข้อมูลอินพุตเพื่อดูวิธีสร้างงานและเรียกใช้การอนุมาน
รูปภาพ
ObjectDetectorOptions options = ObjectDetectorOptions.builder() .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build()) .setRunningMode(RunningMode.IMAGE) .setMaxResults(5) .build(); objectDetector = ObjectDetector.createFromOptions(context, options);
วิดีโอ
ObjectDetectorOptions options = ObjectDetectorOptions.builder() .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build()) .setRunningMode(RunningMode.VIDEO) .setMaxResults(5) .build(); objectDetector = ObjectDetector.createFromOptions(context, options);
ไลฟ์สด
ObjectDetectorOptions options = ObjectDetectorOptions.builder() .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build()) .setRunningMode(RunningMode.LIVE_STREAM) .setMaxResults(5) .setResultListener((result, inputImage) -> { // Process the detection result here. }) .setErrorListener((result, inputImage) -> { // Process the classification errors here. }) .build(); objectDetector = ObjectDetector.createFromOptions(context, options);
การใช้โค้ดตัวอย่างของโปรแกรมตรวจจับวัตถุช่วยให้ผู้ใช้สลับระหว่างโหมดการประมวลผลได้ แนวทางนี้ทําให้โค้ดการสร้างงานซับซ้อนขึ้นและอาจไม่เหมาะกับกรณีการใช้งานของคุณ คุณจะเห็นโค้ดนี้ในฟังก์ชัน setupObjectDetector()
ของคลาส ObjectDetectorHelper
ตัวเลือกการกำหนดค่า
งานนี้มีตัวเลือกการกำหนดค่าต่อไปนี้สำหรับแอป Android
ชื่อตัวเลือก | คำอธิบาย | ช่วงของค่า | ค่าเริ่มต้น |
---|---|---|---|
runningMode |
ตั้งค่าโหมดการทํางานสําหรับงาน โดยโหมดมี 3 แบบ ดังนี้ รูปภาพ: โหมดสำหรับอินพุตรูปภาพเดียว วิดีโอ: โหมดสำหรับเฟรมที่ถอดรหัสของวิดีโอ LIVE_STREAM: โหมดสตรีมแบบสดของข้อมูลอินพุต เช่น จากกล้อง ในโหมดนี้ คุณต้องเรียกใช้ resultListener เพื่อตั้งค่า Listener เพื่อรับผลลัพธ์แบบไม่พร้อมกัน |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
displayNamesLocales |
ตั้งค่าภาษาของป้ายกำกับที่จะใช้สำหรับชื่อที่แสดงซึ่งระบุไว้ในข้อมูลเมตาของโมเดลของงาน (หากมี) ค่าเริ่มต้นคือ en สำหรับภาษาอังกฤษ คุณเพิ่มป้ายกำกับที่แปลแล้วลงในข้อมูลเมตาของโมเดลที่กำหนดเองได้โดยใช้ TensorFlow Lite Metadata Writer API
|
รหัสภาษา | en |
maxResults |
กําหนดจํานวนสูงสุดของผลการค้นหาที่ตรวจพบซึ่งได้คะแนนสูงสุดที่จะแสดง (ไม่บังคับ) | ตัวเลขบวกใดก็ได้ | -1 (แสดงผลลัพธ์ทั้งหมด) |
scoreThreshold |
ตั้งค่าเกณฑ์คะแนนการคาดการณ์ที่จะลบล้างเกณฑ์ที่ระบุไว้ในข้อมูลเมตาของโมเดล (หากมี) ระบบจะปฏิเสธผลลัพธ์ที่ต่ำกว่าค่านี้ | ตัวเลขทศนิยม | ไม่ได้ตั้งค่า |
categoryAllowlist |
ตั้งค่ารายการชื่อหมวดหมู่ที่อนุญาต (ไม่บังคับ) หากไม่ว่างเปล่า ระบบจะกรองผลการตรวจหาที่มีชื่อหมวดหมู่ไม่อยู่ในชุดนี้ออก ระบบจะไม่สนใจชื่อหมวดหมู่ที่ซ้ำกันหรือไม่รู้จัก
ตัวเลือกนี้ใช้ร่วมกับ categoryDenylist ไม่ได้ และการใช้ทั้ง 2 ตัวเลือกจะทำให้เกิดข้อผิดพลาด |
สตริงใดก็ได้ | ไม่ได้ตั้งค่า |
categoryDenylist |
ตั้งค่ารายการชื่อหมวดหมู่ที่ไม่อนุญาต (ไม่บังคับ) หากไม่ว่างเปล่า ระบบจะกรองผลการตรวจหาที่มีชื่อหมวดหมู่อยู่ในชุดนี้ออก ระบบจะไม่สนใจชื่อหมวดหมู่ที่ซ้ำกันหรือไม่รู้จัก ตัวเลือกนี้ใช้ร่วมกันกับ categoryAllowlist ไม่ได้ และการใช้ทั้ง 2 ตัวเลือกจะทำให้เกิดข้อผิดพลาด |
สตริงใดก็ได้ | ไม่ได้ตั้งค่า |
resultListener |
ตั้งค่าโปรแกรมรับฟังผลลัพธ์ให้รับผลลัพธ์การตรวจจับแบบไม่พร้อมกันเมื่อตัวตรวจจับวัตถุอยู่ในโหมดสตรีมแบบสด คุณจะใช้ตัวเลือกนี้ได้ก็ต่อเมื่อตั้งค่า runningMode เป็น LIVE_STREAM เท่านั้น | ไม่เกี่ยวข้อง | ไม่ได้ตั้งค่า |
เตรียมข้อมูล
คุณต้องแปลงรูปภาพหรือเฟรมอินพุตเป็นออบเจ็กต์ 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 values. Use these values // 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() MPImage mpImage = new MediaImageBuilder(mediaImage).build();
ในโค้ดตัวอย่างของโปรแกรมตรวจจับวัตถุ การเตรียมข้อมูลจะดำเนินการในคลาส ObjectDetectorHelper
ภายในฟังก์ชัน detectImage()
, detectVideoFile()
, detectLivestreamFrame()
เรียกใช้งาน
ใช้ObjectDetector.detect...()
วิธีการเฉพาะสำหรับประเภทข้อมูลนั้นๆ โดยขึ้นอยู่กับประเภทข้อมูลที่คุณกำลังดำเนินการ ใช้
detect()
สำหรับรูปภาพแต่ละรูป
detectForVideo()
สำหรับเฟรมในไฟล์วิดีโอ และ
detectAsync()
สำหรับสตรีมวิดีโอ เมื่อทำการตรวจจับในสตรีมวิดีโอ ให้ตรวจสอบว่าคุณเรียกใช้การตรวจจับในเธรดแยกต่างหากเพื่อหลีกเลี่ยงการบล็อกเธรดอินเทอร์เฟซผู้ใช้
ตัวอย่างโค้ดต่อไปนี้แสดงตัวอย่างง่ายๆ ของวิธีเรียกใช้โปรแกรมตรวจจับวัตถุในโหมดข้อมูลต่างๆ เหล่านี้
รูปภาพ
ObjectDetectorResult detectionResult = objectDetector.detect(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. ObjectDetectorResult detectionResult = objectDetector.detectForVideo(image, frameTimestampMs);
ไลฟ์สด
// Run inference on the frame. The detection results will be available // via the `resultListener` provided in the `ObjectDetectorOptions` when // the object detector was created. objectDetector.detectAsync(image, frameTimestampMs);
ตัวอย่างโค้ดของโปรแกรมตรวจจับวัตถุแสดงการใช้งานโหมดเหล่านี้อย่างละเอียด detect()
, detectVideoFile()
และ detectAsync()
โค้ดตัวอย่างนี้ช่วยให้ผู้ใช้สลับระหว่างโหมดการประมวลผลได้ ซึ่งอาจไม่จำเป็นสำหรับกรณีการใช้งานของคุณ
โปรดทราบดังต่อไปนี้
- เมื่อทำงานในโหมดวิดีโอหรือโหมดสตรีมแบบสด คุณต้องระบุการประทับเวลาของเฟรมอินพุตให้กับงานตัวตรวจจับวัตถุด้วย
- เมื่อทำงานในโหมดรูปภาพหรือวิดีโอ งานตัวตรวจจับวัตถุจะบล็อกเธรดปัจจุบันจนกว่าจะประมวลผลรูปภาพหรือเฟรมอินพุตเสร็จ ดำเนินการประมวลผลในเธรดแบ็กกราวด์เพื่อหลีกเลี่ยงการบล็อกเธรดปัจจุบัน
- เมื่อทำงานในโหมดสตรีมแบบสด งานของโปรแกรมตรวจจับวัตถุจะไม่บล็อกเธรดปัจจุบัน แต่จะแสดงผลทันที โดยจะเรียกใช้โปรแกรมรับฟังผลลัพธ์พร้อมผลการตรวจจับทุกครั้งที่ประมวลผลเฟรมอินพุตเสร็จแล้ว หากมีการเรียกใช้ฟังก์ชัน detect เมื่องานของโปรแกรมตรวจจับวัตถุกำลังประมวลผลเฟรมอื่นอยู่ ระบบจะไม่สนใจเฟรมอินพุตใหม่
จัดการและแสดงผลลัพธ์
เมื่อทำการอนุมาน งานตรวจจับวัตถุจะแสดงผลออบเจ็กต์ ObjectDetectorResult
ซึ่งอธิบายวัตถุที่พบในรูปภาพอินพุต
ต่อไปนี้เป็นตัวอย่างข้อมูลเอาต์พุตจากงานนี้
ObjectDetectorResult:
Detection #0:
Box: (x: 355, y: 133, w: 190, h: 206)
Categories:
index : 17
score : 0.73828
class name : dog
Detection #1:
Box: (x: 103, y: 15, w: 138, h: 369)
Categories:
index : 17
score : 0.73047
class name : dog
รูปภาพต่อไปนี้แสดงภาพเอาต์พุตของงาน
โค้ดตัวอย่างของโปรแกรมตรวจจับวัตถุแสดงวิธีแสดงผลลัพธ์การตรวจจับที่แสดงผลจากงาน ดูรายละเอียดเพิ่มเติมได้ที่คลาส OverlayView