คุณใช้ ML Kit เพื่อตรวจหาและติดตามวัตถุในเฟรมวิดีโอต่อเนื่องได้
เมื่อคุณส่งภาพไปยัง ML Kit จะตรวจหาวัตถุในภาพได้สูงสุด 5 รายการ พร้อมกับตำแหน่งของแต่ละวัตถุในรูปภาพ เมื่อตรวจพบวัตถุใน สตรีมวิดีโอ โดยออบเจ็กต์แต่ละรายการจะมีรหัสที่ไม่ซ้ำกันซึ่งใช้ติดตามออบเจ็กต์ได้ จากเฟรมหนึ่งไปอีกเฟรม คุณยังเลือกเปิดใช้ออบเจ็กต์คร่าวๆ ได้ด้วย ซึ่งติดป้ายกำกับออบเจ็กต์ที่มีคำอธิบายหมวดหมู่แบบกว้างๆ
ลองเลย
- ลองใช้แอปตัวอย่างเพื่อ ดูตัวอย่างการใช้ API นี้
- ดูการจัดแสดงดีไซน์ Material สำหรับการติดตั้งใช้งาน API นี้แบบครบวงจร
ก่อนเริ่มต้น
- ใส่พ็อด ML Kit ต่อไปนี้ใน Podfile
pod 'GoogleMLKit/ObjectDetection', '8.0.0'
- หลังจากที่คุณติดตั้งหรืออัปเดตพ็อดของโปรเจ็กต์แล้ว ให้เปิดโปรเจ็กต์ Xcode โดยใช้
.xcworkspaceทั้งนี้ ML Kit รองรับ Xcode เวอร์ชัน 12.4 ขึ้นไป
1. กำหนดค่าตัวตรวจจับออบเจ็กต์
ในการตรวจหาและติดตามออบเจ็กต์ ให้สร้างอินสแตนซ์ของ
ObjectDetector และเลือกระบุการตั้งค่าตัวตรวจจับที่คุณต้องการ
เปลี่ยนจากค่าเริ่มต้น
กำหนดค่าตัวตรวจจับออบเจ็กต์สำหรับ Use Case ของคุณด้วย ออบเจ็กต์
ObjectDetectorOptionsรายการ คุณสามารถเปลี่ยนสิ่งต่อไปนี้ได้ การตั้งค่าต่อไปนี้การตั้งค่าตัวตรวจจับวัตถุ โหมดการตรวจจับ .stream(ค่าเริ่มต้น) | วันที่.singleImageในโหมดสตรีม (ค่าเริ่มต้น) ตัวตรวจจับวัตถุจะทำงานโดยมีปริมาณต่ำมาก เวลาในการตอบสนอง แต่อาจทำให้ผลลัพธ์ไม่สมบูรณ์ (เช่น ไม่ได้ระบุ กรอบหรือหมวดหมู่) ในการเรียกใช้ 2-3 ครั้งแรก ตัวตรวจจับ นอกจากนี้ ตัวตรวจจับจะกำหนดการติดตามในโหมดสตรีม รหัสไปยังออบเจ็กต์ซึ่งใช้เพื่อติดตามวัตถุในเฟรมได้ ใช้โหมดนี้เมื่อคุณต้องการติดตามออบเจ็กต์ หรือเมื่อมีเวลาในการตอบสนองต่ำ มีความสำคัญ เช่น เมื่อประมวลผลสตรีมวิดีโอแบบเรียลไทม์
ในโหมดภาพเดียว ตัวตรวจจับวัตถุจะแสดงผลลัพธ์ หลังจากกำหนดกรอบล้อมรอบของวัตถุแล้ว หากคุณเปิดใช้ ระบบจะส่งคืนผลลัพธ์หลังกรอบล้อมรอบและ ทั้งป้ายกำกับหมวดหมู่ ดังนั้น การตรวจพบ เวลาในการตอบสนองอาจสูงขึ้น นอกจากนี้ ในโหมดภาพเดียว การติดตาม ไม่มีการกำหนดรหัส ใช้โหมดนี้หากเวลาในการตอบสนองไม่ร้ายแรงและ คุณคงไม่ต้องการจัดการกับผลลัพธ์บางส่วน
ตรวจหาและติดตามวัตถุหลายรายการ false(ค่าเริ่มต้น) | วันที่trueสามารถตรวจจับและติดตามวัตถุได้สูงสุด 5 รายการ หรือเฉพาะวัตถุที่พบมากที่สุด ออบเจ็กต์ที่โดดเด่น (ค่าเริ่มต้น)
จำแนกประเภทวัตถุ false(ค่าเริ่มต้น) | วันที่trueระบุว่าจะจัดประเภทออบเจ็กต์ที่ตรวจพบเป็นหมวดหมู่คร่าวๆ หรือไม่ เมื่อเปิดใช้ ตัวตรวจจับวัตถุจะจัดประเภทออบเจ็กต์ลงใน หมวดหมู่ต่อไปนี้: สินค้าแฟชั่น อาหาร ของใช้ในบ้าน สถานที่ และต้นไม้ได้
API การติดตามและตรวจจับออบเจ็กต์ได้รับการเพิ่มประสิทธิภาพสำหรับการใช้งานหลัก 2 รายการนี้ กรณี:
- การตรวจจับแบบเรียลไทม์และการติดตามวัตถุที่โดดเด่นที่สุดในกล้อง ช่องมองภาพ
- การตรวจจับวัตถุหลายรายการในภาพนิ่ง
วิธีกำหนดค่า API สำหรับกรณีการใช้งานเหล่านี้
Swift
// Live detection and tracking let options = ObjectDetectorOptions() options.shouldEnableClassification = true // Multiple object detection in static images let options = ObjectDetectorOptions() options.detectorMode = .singleImage options.shouldEnableMultipleObjects = true options.shouldEnableClassification = true
Objective-C
// Live detection and tracking MLKObjectDetectorOptions *options = [[MLKObjectDetectorOptions alloc] init]; options.shouldEnableClassification = YES; // Multiple object detection in static images MLKObjectDetectorOptions *options = [[MLKOptions alloc] init]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableMultipleObjects = YES; options.shouldEnableClassification = YES;
- รับอินสแตนซ์ของ
ObjectDetector:
Swift
let objectDetector = ObjectDetector.objectDetector() // Or, to change the default settings: let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetector]; // Or, to change the default settings: MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
2. เตรียมรูปภาพอินพุต
ในการตรวจหาและติดตามวัตถุ ให้ทำตามขั้นตอนต่อไปนี้กับรูปภาพหรือเฟรมของวิดีโอแต่ละภาพ
หากเปิดใช้โหมดสตรีม คุณต้องสร้างออบเจ็กต์ VisionImage รายการจาก
CMSampleBuffer วินาที
สร้างออบเจ็กต์ VisionImage โดยใช้ UIImage หรือ
CMSampleBuffer
หากคุณใช้ UIImage ให้ทำตามขั้นตอนต่อไปนี้
- สร้างออบเจ็กต์
VisionImageด้วยUIImageตรวจสอบว่าได้ระบุ.orientationที่ถูกต้องSwift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
หากคุณใช้ CMSampleBuffer ให้ทำตามขั้นตอนต่อไปนี้
-
ระบุการวางแนวของข้อมูลภาพที่มีอยู่ใน
CMSampleBufferวิธีดูการวางแนวรูปภาพ
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- สร้างออบเจ็กต์
VisionImageโดยใช้CMSampleBufferวัตถุและการวางแนว:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. ประมวลผลรูปภาพ
ส่งVisionImage ไปยังการประมวลผลรูปภาพของตัวตรวจจับวัตถุ
คุณสามารถใช้เมธอด process(image:) แบบไม่พร้อมกันหรือ
เมธอด results() แบบซิงโครนัส
วิธีตรวจหาวัตถุแบบไม่พร้อมกัน
Swift
objectDetector.process(image) { objects, error in guard error == nil else { // Error. return } guard !objects.isEmpty else { // No objects detected. return } // Success. Get object info here. // ... }
Objective-C
[objectDetector processImage:image completion:^(NSArray* _Nullable objects, NSError * _Nullable error) { if (error == nil) { return; } if (objects.count == 0) { // No objects detected. return; } // Success. Get object info here. }];
วิธีตรวจหาวัตถุพร้อมกัน
Swift
var objects: [Object] do { objects = try objectDetector.results(in: image) } catch let error { print("Failed to detect object with error: \(error.localizedDescription).") return } guard !objects.isEmpty else { print("Object detector returned no results.") return } // Success. Get object info here.
Objective-C
NSError *error; NSArray*objects = [objectDetector resultsInImage:image error:&error]; if (error == nil) { return; } if (objects.count == 0) { // No objects detected. return; } // Success. Get object info here.
4. รับข้อมูลเกี่ยวกับวัตถุที่ตรวจพบ
หากการเรียกใช้โปรแกรมประมวลผลรูปภาพสำเร็จ โปรแกรมดังกล่าวจะมีการส่งรายการObject วินาทีไปยังตัวแฮนเดิลการเสร็จสมบูรณ์หรือส่งกลับรายการ ทั้งนี้ขึ้นอยู่
ไม่ว่าคุณจะเรียกใช้เมธอด
แบบอะซิงโครนัสหรือซิงโครนัส
Object แต่ละรายการจะมีพร็อพเพอร์ตี้ต่อไปนี้
frame |
CGRect ที่ระบุตำแหน่งของออบเจ็กต์ในส่วน
รูปภาพ |
trackingID |
จำนวนเต็มที่ระบุออบเจ็กต์ในรูปภาพ หรือ "nil" ใน โหมดภาพเดียว |
labels |
อาร์เรย์ของป้ายกำกับที่อธิบายออบเจ็กต์ที่ตัวตรวจจับแสดงผล
พร็อพเพอร์ตี้ว่างเปล่าหากตัวเลือกตัวตรวจจับ
ตั้งค่า shouldEnableClassification เป็น false
|
Swift
// objects contains one item if multiple object detection wasn't enabled. for object in objects { let frame = object.frame let trackingID = object.trackingID // If classification was enabled: let description = object.labels.enumerated().map { (index, label) in "Label \(index): \(label.text), \(label.confidence)" }.joined(separator:"\n") }
Objective-C
// The list of detected objects contains one item if multiple // object detection wasn't enabled. for (MLKObject *object in objects) { CGRect frame = object.frame; NSNumber *trackingID = object.trackingID; for (MLKObjectLabel *label in object.labels) { NSString *labelString = [NSString stringWithFormat: @"%@, %f, %lu", label.text, label.confidence, (unsigned long)label.index]; ... } }
การปรับปรุงความสามารถในการใช้งานและประสิทธิภาพ
โปรดปฏิบัติตามหลักเกณฑ์ต่อไปนี้ในแอปเพื่อให้ผู้ใช้ได้รับประสบการณ์ที่ดีที่สุด
- การตรวจจับออบเจ็กต์ที่ประสบความสำเร็จขึ้นอยู่กับความซับซ้อนของภาพของออบเจ็กต์ ใน วัตถุที่มีคุณลักษณะทางภาพจำนวนน้อยอาจต้องให้ตรวจจับได้ เพื่อใช้ส่วนที่ใหญ่กว่าของรูปภาพ คุณควรให้คำแนะนำแก่ผู้ใช้เกี่ยวกับ ซึ่งเหมาะสำหรับวัตถุที่ต้องการตรวจจับ
- เมื่อใช้การจำแนกประเภท หากต้องการตรวจหาวัตถุที่ไม่ตกหล่น อยู่ในหมวดหมู่ที่สนับสนุนอย่างชัดเจน ใช้การจัดการพิเศษสำหรับสิ่งที่ไม่ทราบ ออบเจ็กต์
อย่าลืมดูดีไซน์ Material คอลเล็กชันรูปแบบของฟีเจอร์ที่ขับเคลื่อนด้วยแมชชีนเลิร์นนิง
เมื่อใช้โหมดสตรีมมิงในแอปพลิเคชันแบบเรียลไทม์ ให้ทำตามหลักเกณฑ์ต่อไปนี้เพื่อ ได้อัตราเฟรมที่ดีที่สุด
- อย่าใช้การตรวจหาวัตถุหลายรายการในโหมดสตรีมมิง เนื่องจากอุปกรณ์ส่วนใหญ่จะไม่ สามารถสร้างอัตราเฟรมที่เพียงพอ
- ปิดใช้การแยกประเภทหากไม่ต้องการใช้
- สำหรับการประมวลผลเฟรมวิดีโอ ให้ใช้ API แบบซิงโครนัสของ
results(in:)ในตัวตรวจจับ โทร เมธอดนี้จาก ของAVCaptureVideoDataOutputSampleBufferDelegatecaptureOutput(_, didOutput:from:)เพื่อให้ได้ผลลัพธ์จากวิดีโอที่ระบุแบบพร้อมกัน เฟรม เก็บ ของAVCaptureVideoDataOutputalwaysDiscardsLateVideoFramesเป็นtrueเพื่อควบคุมการโทรหาตัวตรวจจับ หาก เฟรมวิดีโอจะพร้อมใช้งานขณะที่ตัวตรวจจับทำงานอยู่ เฟรมนั้นจะหายไป - หากคุณใช้เอาต์พุตของเครื่องมือตรวจจับเพื่อวางซ้อนกราฟิก รูปภาพอินพุต รับผลลัพธ์จาก ML Kit ก่อน จากนั้นจึงแสดงผลรูปภาพ ซ้อนทับในขั้นตอนเดียว การทำเช่นนี้จะช่วยให้แสดงผลบนพื้นผิวจอแสดงผล เพียงครั้งเดียวสำหรับแต่ละเฟรมอินพุตที่ประมวลผลแล้ว ดู updatePreviewOverlayViewWithLastFrame ในตัวอย่างการเริ่มต้นอย่างรวดเร็วใน ML Kit