งานตัวตรวจจับออบเจ็กต์ช่วยให้คุณตรวจหาการมีอยู่และตำแหน่งของออบเจ็กต์หลายคลาสได้ เช่น ตัวตรวจจับวัตถุระบุตำแหน่งสุนัขภายในรูปภาพได้ วิธีการเหล่านี้จะแสดงวิธีใช้งานตัวตรวจจับวัตถุบน Android ตัวอย่างโค้ดที่อธิบายในวิธีการเหล่านี้จะดูได้ใน GitHub คุณดูงานนี้จริงได้จากการสาธิตบนเว็บนี้ ดูข้อมูลเพิ่มเติมเกี่ยวกับความสามารถ โมเดล และตัวเลือกการกำหนดค่าของงานนี้ได้ที่ภาพรวม
ตัวอย่างโค้ด
โค้ดตัวอย่างงาน MediaPipe Tasks เป็นการติดตั้งใช้งานแอป Object Detector สำหรับ Android แบบง่ายๆ โดยใช้กล้องบนอุปกรณ์ Android จริงเพื่อตรวจจับวัตถุอย่างต่อเนื่อง และยังสามารถใช้รูปภาพและวิดีโอจากแกลเลอรีอุปกรณ์เพื่อตรวจจับวัตถุแบบคงที่ได้
คุณสามารถใช้แอปเป็นจุดเริ่มต้นสำหรับแอป Android ของคุณเองหรือใช้อ้างอิงเมื่อแก้ไขแอปที่มีอยู่ โค้ดตัวอย่างของตัวตรวจจับออบเจ็กต์โฮสต์อยู่ใน GitHub
ดาวน์โหลดโค้ด
วิธีการต่อไปนี้แสดงวิธีสร้างสำเนาโค้ดตัวอย่างในเครื่องโดยใช้เครื่องมือบรรทัดคำสั่ง git
วิธีดาวน์โหลดโค้ดตัวอย่าง
- โคลนที่เก็บ Git โดยใช้คำสั่งต่อไปนี้
git clone https://github.com/google-ai-edge/mediapipe-samples
- (ไม่บังคับ) กำหนดค่าอินสแตนซ์ Git เพื่อใช้การชำระเงินแบบกระจัดกระจาย
เพื่อให้คุณมีเฉพาะไฟล์สำหรับแอปตัวอย่าง Object Detector ดังนี้
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/object_detection/android
หลังจากสร้างโค้ดตัวอย่างเวอร์ชันในเครื่องแล้ว คุณจะนำเข้าโปรเจ็กต์ไปยัง Android Studio และเรียกใช้แอปได้ โปรดดูวิธีการที่หัวข้อคู่มือการตั้งค่าสำหรับ Android
องค์ประกอบหลัก
ไฟล์ต่อไปนี้มีโค้ดที่สำคัญสำหรับแอปพลิเคชันตัวอย่าง Object Detector
- ObjectDetectorHelper.kt - เริ่มต้นตัวตรวจจับออบเจ็กต์ รวมถึงจัดการโมเดลและมอบสิทธิ์การเลือก
- MainActivity.kt - ใช้งานแอปพลิเคชันและประกอบคอมโพเนนต์อินเทอร์เฟซผู้ใช้
- OverlayView.kt - จัดการและแสดงผลลัพธ์
ตั้งค่า
ส่วนนี้จะอธิบายขั้นตอนสำคัญในการตั้งค่าสภาพแวดล้อมการพัฒนาและโปรเจ็กต์โค้ดเพื่อใช้ตัวตรวจจับออบเจ็กต์ ดูข้อมูลทั่วไปเกี่ยวกับการตั้งค่าสภาพแวดล้อมการพัฒนาเพื่อใช้งาน MediaPipe รวมถึงข้อกำหนดเวอร์ชันแพลตฟอร์มได้ที่คำแนะนำการตั้งค่าสำหรับ Android
การอ้างอิง
ตัวตรวจจับออบเจ็กต์ใช้ไลบรารี com.google.mediapipe:tasks-vision
เพิ่มการอ้างอิงนี้ลงในไฟล์ build.gradle
ของโปรเจ็กต์การพัฒนาแอป Android นำเข้าทรัพยากร Dependency ที่ต้องการด้วยโค้ดต่อไปนี้
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);
การใช้โค้ดตัวอย่างตัวตรวจจับออบเจ็กต์ช่วยให้ผู้ใช้สลับโหมดการประมวลผลได้ วิธีนี้ทำให้โค้ดการสร้างงานซับซ้อนขึ้นและอาจไม่เหมาะกับกรณีการใช้งานของคุณ ดูโค้ดนี้ได้ในฟังก์ชัน ObjectDetectorHelper
คลาส setupObjectDetector()
ตัวเลือกการกำหนดค่า
งานมีตัวเลือกการกำหนดค่าต่อไปนี้สำหรับแอป Android
ชื่อตัวเลือก | คำอธิบาย | ช่วงของค่า | ค่าเริ่มต้น |
---|---|---|---|
runningMode |
ตั้งค่าโหมดการทำงาน มี 3 โหมดดังนี้ IMAGE: โหมดสำหรับการป้อนข้อมูลรูปภาพเดียว วิดีโอ: โหมดสำหรับเฟรมที่ถอดรหัสของวิดีโอ LIVE_Stream: โหมดสำหรับสตรีมแบบสดของข้อมูลอินพุต เช่น จากกล้อง ในโหมดนี้ ต้องมีการเรียกใช้ resultsListener เพื่อตั้งค่า Listener เพื่อรับผลลัพธ์แบบไม่พร้อมกัน |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
displayNamesLocales |
ตั้งค่าภาษาของป้ายกำกับที่จะใช้กับชื่อที่แสดงซึ่งระบุไว้ในข้อมูลเมตาของโมเดลของงาน หากมี ค่าเริ่มต้นคือ en สำหรับภาษาอังกฤษ คุณเพิ่มป้ายกำกับที่แปลเป็นภาษาท้องถิ่นลงในข้อมูลเมตาของโมเดลที่กำหนดเองได้โดยใช้ TensorFlow Lite Metadata Writer API
|
รหัสภาษา | en |
maxResults |
ตั้งค่าจำนวนสูงสุดของผลลัพธ์การตรวจจับที่มีคะแนนสูงสุดที่จะแสดงได้ | ตัวเลขจำนวนบวกใดก็ได้ | -1 (แสดงผลลัพธ์ทั้งหมด) |
scoreThreshold |
ตั้งค่าเกณฑ์คะแนนการคาดการณ์ที่จะลบล้างเกณฑ์ที่ระบุไว้ในข้อมูลเมตาของโมเดล (หากมี) ผลลัพธ์ที่ต่ำกว่าค่านี้ถูกปฏิเสธ | จำนวนลอยตัวใดก็ได้ | ไม่ได้ตั้งค่า |
categoryAllowlist |
ตั้งค่ารายการตัวเลือกของชื่อหมวดหมู่ที่อนุญาต หากไม่ว่างเปล่า ผลการตรวจสอบที่ไม่มีชื่อหมวดหมู่ในชุดนี้จะถูกกรองออก ระบบจะไม่สนใจชื่อหมวดหมู่ที่ซ้ำกันหรือไม่รู้จัก
ตัวเลือกนี้ใช้ด้วยกันกับ categoryDenylist ไม่ได้ และการใช้ทั้ง 2 รายการจะทำให้เกิดข้อผิดพลาด |
สตริงใดก็ได้ | ไม่ได้ตั้งค่า |
categoryDenylist |
ตั้งค่ารายการตัวเลือกของชื่อหมวดหมู่ที่ไม่ได้รับอนุญาต หาก
ไม่ว่างเปล่า ผลการตรวจหาที่มีชื่อหมวดหมู่ในชุดนี้จะถูกกรองออก ระบบจะไม่สนใจชื่อหมวดหมู่ที่ซ้ำกันหรือไม่รู้จัก ตัวเลือกนี้ใช้ด้วยกันกับ categoryAllowlist ไม่ได้เลย และใช้ทั้ง 2 ผลลัพธ์เกิดข้อผิดพลาด |
สตริงใดก็ได้ | ไม่ได้ตั้งค่า |
resultListener |
ตั้งค่า Listener ผลลัพธ์ให้รับผลการตรวจจับแบบไม่พร้อมกันเมื่อตัวตรวจจับออบเจ็กต์อยู่ในโหมดสตรีมแบบสด คุณจะใช้ตัวเลือกนี้ได้ก็ต่อเมื่อตั้งค่า 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()
โค้ดตัวอย่างช่วยให้ผู้ใช้สลับโหมดการประมวลผลได้
ซึ่งอาจไม่จำเป็นต้องใช้สำหรับกรณีการใช้งานของคุณ
โปรดทราบดังต่อไปนี้
- เมื่อทำงานในโหมดวิดีโอหรือโหมดสตรีมแบบสด คุณต้องระบุการประทับเวลาของเฟรมอินพุตให้กับงานตัวตรวจจับวัตถุด้วย
- เมื่อใช้งานในโหมดรูปภาพหรือวิดีโอ งานตัวตรวจจับวัตถุจะบล็อกเทรดปัจจุบันจนกว่าจะประมวลผลรูปภาพหรือเฟรมอินพุตเสร็จ เพื่อหลีกเลี่ยงการบล็อกเทรดปัจจุบัน ให้ดำเนินการประมวลผลในเทรดเบื้องหลัง
- เมื่อทำงานในโหมดสตรีมแบบสด งานตัวตรวจจับออบเจ็กต์จะไม่บล็อกเทรดปัจจุบัน แต่จะแสดงผลทันที โดยจะเรียกใช้ Listener ผลลัพธ์พร้อมกับผลการตรวจจับทุกครั้งที่ประมวลผลเฟรมอินพุตเสร็จ หากมีการเรียกฟังก์ชันตรวจจับเมื่องานตัวตรวจจับวัตถุกำลังไม่ว่างในการประมวลผลเฟรมอื่น ระบบจะไม่สนใจเฟรมอินพุตใหม่
แฮนเดิลและแสดงผลลัพธ์
เมื่อเรียกใช้การอนุมาน งานตัวตรวจจับออบเจ็กต์จะแสดงผลออบเจ็กต์ 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