คุณใช้ ML Kit เพื่อตรวจหาและติดตามออบเจ็กต์ในเฟรมวิดีโอที่ต่อเนื่องได้
เมื่อคุณส่งรูปภาพไปยัง ML Kit จะตรวจหาออบเจ็กต์ได้สูงสุด 5 รายการในรูปภาพ รวมถึงตําแหน่งของออบเจ็กต์แต่ละรายการในรูปภาพ เมื่อตรวจพบออบเจ็กต์ในสตรีมวิดีโอ ออบเจ็กต์แต่ละรายการจะมีรหัสที่ไม่ซ้ํากันซึ่งใช้เพื่อติดตามออบเจ็กต์จากเฟรมหนึ่งไปยังอีกเฟรมหนึ่งได้ คุณยังเปิดใช้การแยกประเภทออบเจ็กต์แบบคร่าวๆ ได้ด้วย ซึ่งจะช่วยติดป้ายกํากับออบเจ็กต์ที่มีคําอธิบายหมวดหมู่แบบกว้าง
ลองใช้งาน
- ลองใช้แอปตัวอย่างเพื่อดูตัวอย่างการใช้งาน API นี้
- ดูแอป Showcase Material Design สําหรับการใช้งาน API นี้แบบครบวงจร
ข้อควรทราบก่อนที่จะเริ่มต้น
- รวมพ็อด ML Kit ต่อไปนี้ใน Podfile
pod 'GoogleMLKit/ObjectDetection', '3.2.0'
- หลังจากติดตั้งหรืออัปเดตพ็อดของโปรเจ็กต์ ให้เปิดโปรเจ็กต์ Xcode โดยใช้
.xcworkspace
XKit เวอร์ชัน 12.4 ขึ้นไปรองรับ ML Kit
1. กําหนดค่าตัวตรวจจับออบเจ็กต์
หากต้องการตรวจจับและติดตามออบเจ็กต์ ก่อนอื่นให้สร้างอินสแตนซ์ของ ObjectDetector
และเลือกระบุการตั้งค่าตัวตรวจจับที่ต้องการเปลี่ยนแปลงจากค่าเริ่มต้น
กําหนดค่าตัวตรวจจับออบเจ็กต์สําหรับกรณีการใช้งานของคุณด้วยออบเจ็กต์
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 Design
เมื่อใช้โหมดสตรีมมิงในแอปพลิเคชันแบบเรียลไทม์ ให้ทําตามหลักเกณฑ์ต่อไปนี้เพื่อให้อัตราเฟรมดีที่สุด
- อย่าใช้การตรวจจับออบเจ็กต์หลายรายการในโหมดสตรีมมิง เนื่องจากอุปกรณ์ส่วนใหญ่จะไม่สามารถสร้างอัตราเฟรมให้เพียงพอได้
- ปิดใช้งานการแยกประเภทที่คุณไม่ต้องการ
- สําหรับการประมวลผลเฟรมวิดีโอ ให้ใช้
results(in:)
API แบบพร้อมกันของตัวตรวจจับ เรียกวิธีนี้จากฟังก์ชันcaptureOutput(_, didOutput:from:)
ของAVCaptureVideoDataOutputSampleBufferDelegate
เพื่อให้ได้ผลลัพธ์พร้อมกันจากเฟรมวิดีโอที่ระบุ เก็บalwaysDiscardsLateVideoFrames
ของAVCaptureVideoDataOutput
ไว้เป็นtrue
เพื่อควบคุมการโทรไปยังตัวตรวจจับ หาก เฟรมวิดีโอใหม่พร้อมใช้งานระหว่างตัวตรวจจับจะทํางาน เฟรมจะหายไป - หากใช้เอาต์พุตของตัวตรวจจับเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต ก่อนอื่นให้ดูผลลัพธ์จาก ML Kit จากนั้นแสดงผลรูปภาพและวางซ้อนในขั้นตอนเดียว เมื่อทําเช่นนั้น คุณจะแสดงผลบนพื้นที่แสดงผลเพียงครั้งเดียวสําหรับเฟรมอินพุตแต่ละรายการที่ประมวลผลแล้ว ดูตัวอย่าง update PreviewOverlayViewWithLastFrame ในตัวอย่างคู่มือเริ่มใช้งานฉบับย่อสําหรับ ML Kit