คุณใช้ ML Kit เพื่อตรวจหาและติดตามวัตถุในเฟรมวิดีโอต่อเนื่องได้
เมื่อคุณส่งภาพไปยัง ML Kit จะตรวจหาวัตถุในภาพได้สูงสุด 5 รายการ พร้อมกับตำแหน่งของแต่ละวัตถุในรูปภาพ เมื่อตรวจพบวัตถุใน สตรีมวิดีโอ โดยออบเจ็กต์แต่ละรายการจะมีรหัสที่ไม่ซ้ำกันซึ่งใช้ติดตามออบเจ็กต์ได้ จากเฟรมหนึ่งไปอีกเฟรม คุณยังเลือกเปิดใช้ออบเจ็กต์คร่าวๆ ได้ด้วย ซึ่งติดป้ายกำกับออบเจ็กต์ที่มีคำอธิบายหมวดหมู่แบบกว้างๆ
ลองเลย
- ลองใช้แอปตัวอย่างเพื่อ ดูตัวอย่างการใช้ API นี้
- ดูการจัดแสดงดีไซน์ Material สำหรับการติดตั้งใช้งาน API นี้แบบครบวงจร
ก่อนเริ่มต้น
- ใส่พ็อด ML Kit ต่อไปนี้ใน Podfile
pod 'GoogleMLKit/ObjectDetection', '3.2.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:)
ในตัวตรวจจับ โทร เมธอดนี้จาก ของAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
เพื่อให้ได้ผลลัพธ์จากวิดีโอที่ระบุแบบพร้อมกัน เฟรม เก็บ ของAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
เป็นtrue
เพื่อควบคุมการโทรหาตัวตรวจจับ หาก เฟรมวิดีโอจะพร้อมใช้งานขณะที่ตัวตรวจจับทำงานอยู่ เฟรมนั้นจะหายไป - หากคุณใช้เอาต์พุตของเครื่องมือตรวจจับเพื่อวางซ้อนกราฟิก รูปภาพอินพุต รับผลลัพธ์จาก ML Kit ก่อน จากนั้นจึงแสดงผลรูปภาพ ซ้อนทับในขั้นตอนเดียว การทำเช่นนี้จะช่วยให้แสดงผลบนพื้นผิวจอแสดงผล เพียงครั้งเดียวสำหรับแต่ละเฟรมอินพุตที่ประมวลผลแล้ว ดู updatePreviewOverlayViewWithLastFrame ในตัวอย่างการเริ่มต้นอย่างรวดเร็วใน ML Kit