คุณสามารถใช้ ML Kit เพื่อตรวจจับและติดตามวัตถุข้ามเฟรมของวิดีโอได้
เมื่อคุณส่งภาพ ML Kit ML Kit จะส่งกลับรายการวัตถุที่ตรวจพบสูงสุดห้ารายการและตำแหน่งในรูปภาพสำหรับแต่ละภาพ เมื่อตรวจจับวัตถุในสตรีมวิดีโอ วัตถุทุกชิ้นจะมี ID ที่คุณสามารถใช้เพื่อติดตามวัตถุในรูปภาพต่างๆ คุณยังสามารถเลือกเปิดใช้งานการจัดประเภทอ็อบเจ็กต์หยาบ ซึ่งจะติดป้ายอ็อบเจ็กต์ด้วยคำอธิบายหมวดหมู่แบบกว้างๆ
ก่อนที่คุณจะเริ่ม
- หากคุณยังไม่ได้เพิ่ม Firebase ลงในแอปของคุณ ให้ทำตามขั้นตอนใน คู่มือการเริ่มต้นใช้งาน
- รวมไลบรารี ML Kit ไว้ใน Podfile ของคุณ:
pod 'Firebase/MLVision', '6.25.0' pod 'Firebase/MLVisionObjectDetection', '6.25.0'
หลังจากที่คุณติดตั้งหรืออัปเดต Pod ของโปรเจ็กต์แล้ว อย่าลืมเปิดโปรเจ็กต์ Xcode โดยใช้.xcworkspace
- ในแอปของคุณ ให้นำเข้า Firebase:
สวิฟท์
import Firebase
วัตถุประสงค์-C
@import Firebase;
1. กำหนดค่าเครื่องตรวจจับวัตถุ
หากต้องการเริ่มตรวจจับและติดตามวัตถุ ขั้นแรกให้สร้างอินสแตนซ์ของ VisionObjectDetector
โดยระบุการตั้งค่าตัวตรวจจับใดๆ ที่คุณต้องการเปลี่ยนจากค่าเริ่มต้นหรือไม่ก็ได้
กำหนดค่าตัวตรวจจับวัตถุสำหรับกรณีการใช้งานของคุณด้วยวัตถุ
VisionObjectDetectorOptions
คุณสามารถเปลี่ยนการตั้งค่าต่อไปนี้:การตั้งค่าตัวตรวจจับวัตถุ โหมดการตรวจจับ .stream
(ค่าเริ่มต้น) |.singleImage
ในโหมดสตรีม (ค่าเริ่มต้น) ตัวตรวจจับวัตถุจะทำงานโดยมีเวลาแฝงต่ำมาก แต่อาจให้ผลลัพธ์ที่ไม่สมบูรณ์ (เช่น กรอบหรือหมวดหมู่ขอบเขตที่ไม่ระบุ) ในการเรียกใช้ตัวตรวจจับสองสามครั้งแรก นอกจากนี้ ในโหมดสตรีม ตัวตรวจจับจะกำหนดรหัสติดตามให้กับออบเจ็กต์ ซึ่งคุณสามารถใช้ติดตามออบเจ็กต์ข้ามเฟรมได้ ใช้โหมดนี้เมื่อคุณต้องการติดตามวัตถุ หรือเมื่อเวลาแฝงต่ำเป็นสิ่งสำคัญ เช่น เมื่อประมวลผลสตรีมวิดีโอแบบเรียลไทม์
ในโหมดรูปภาพเดียว ตัวตรวจจับวัตถุจะรอจนกว่ากล่องขอบเขตของวัตถุที่ตรวจพบและหมวดหมู่ (หากคุณเปิดใช้งานการจัดหมวดหมู่) จะพร้อมใช้งานก่อนที่จะส่งคืนผลลัพธ์ ด้วยเหตุนี้ เวลาแฝงในการตรวจจับจึงอาจสูงขึ้น นอกจากนี้ ในโหมดรูปภาพเดี่ยว จะไม่มีการกำหนดรหัสติดตาม ใช้โหมดนี้หากเวลาแฝงไม่สำคัญและคุณไม่ต้องการจัดการกับผลลัพธ์บางส่วน
ตรวจจับและติดตามวัตถุหลายชิ้น false
(ค่าเริ่มต้น) |true
ไม่ว่าจะตรวจจับและติดตามวัตถุสูงสุดห้าชิ้นหรือเฉพาะวัตถุที่โดดเด่นที่สุด (ค่าเริ่มต้น)
จำแนกวัตถุ false
(ค่าเริ่มต้น) |true
ไม่ว่าจะจำแนกวัตถุที่ตรวจพบเป็นประเภทหยาบหรือไม่ เมื่อเปิดใช้งาน ตัวตรวจจับวัตถุจะจัดประเภทวัตถุเป็นหมวดหมู่ต่อไปนี้: สินค้าแฟชั่น อาหาร ของใช้ในบ้าน สถานที่ ต้นไม้ และที่ไม่รู้จัก
API การตรวจจับและติดตามออบเจ็กต์ได้รับการปรับให้เหมาะสมสำหรับกรณีการใช้งานหลักสองกรณีนี้:
- การตรวจจับและการติดตามวัตถุที่โดดเด่นที่สุดในช่องมองภาพของกล้องแบบเรียลไทม์
- การตรวจจับวัตถุหลายชิ้นในภาพนิ่ง
หากต้องการกำหนดค่า API สำหรับกรณีการใช้งานเหล่านี้:
สวิฟท์
// Live detection and tracking let options = VisionObjectDetectorOptions() options.detectorMode = .stream options.shouldEnableMultipleObjects = false options.shouldEnableClassification = true // Optional // Multiple object detection in static images let options = VisionObjectDetectorOptions() options.detectorMode = .singleImage options.shouldEnableMultipleObjects = true options.shouldEnableClassification = true // Optional
วัตถุประสงค์-C
// Live detection and tracking FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init]; options.detectorMode = FIRVisionObjectDetectorModeStream; options.shouldEnableMultipleObjects = NO; options.shouldEnableClassification = YES; // Optional // Multiple object detection in static images FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init]; options.detectorMode = FIRVisionObjectDetectorModeSingleImage; options.shouldEnableMultipleObjects = YES; options.shouldEnableClassification = YES; // Optional
รับอินสแตนซ์ของ
FirebaseVisionObjectDetector
:สวิฟท์
let objectDetector = Vision.vision().objectDetector() // Or, to change the default settings: let objectDetector = Vision.vision().objectDetector(options: options)
วัตถุประสงค์-C
FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetector]; // Or, to change the default settings: FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetectorWithOptions:options];
2. เรียกใช้เครื่องตรวจจับวัตถุ
ในการตรวจจับและติดตามวัตถุ ให้ทำดังต่อไปนี้สำหรับแต่ละภาพหรือเฟรมของวิดีโอ หากคุณเปิดใช้งานโหมดสตรีม คุณต้องสร้างออบเจ็กต์ VisionImage
จาก CMSampleBufferRef
สร้างวัตถุ
VisionImage
โดยใช้UIImage
หรือCMSampleBufferRef
วิธีใช้
UIImage
:- หากจำเป็น ให้หมุนรูปภาพเพื่อให้คุณสมบัติ
imageOrientation
เป็น.up
- สร้างวัตถุ
VisionImage
โดยใช้UIImage
ที่หมุนอย่างถูกต้อง อย่าระบุข้อมูลเมตาการหมุนเวียนใดๆ ต้องใช้ค่าเริ่มต้น ..topLeft
สวิฟท์
let image = VisionImage(image: uiImage)
วัตถุประสงค์-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
วิธีใช้
CMSampleBufferRef
:สร้างออบเจ็กต์
VisionImageMetadata
ที่ระบุการวางแนวของข้อมูลรูปภาพที่มีอยู่ในบัฟเฟอร์CMSampleBufferRef
เพื่อให้ได้การวางแนวของภาพ:
สวิฟท์
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> VisionDetectorImageOrientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftTop : .rightTop case .landscapeLeft: return cameraPosition == .front ? .bottomLeft : .topLeft case .portraitUpsideDown: return cameraPosition == .front ? .rightBottom : .leftBottom case .landscapeRight: return cameraPosition == .front ? .topRight : .bottomRight case .faceDown, .faceUp, .unknown: return .leftTop } }
วัตถุประสงค์-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
จากนั้นสร้างวัตถุข้อมูลเมตา:
สวิฟท์
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
วัตถุประสงค์-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
- สร้างวัตถุ
VisionImage
โดยใช้วัตถุCMSampleBufferRef
และข้อมูลเมตาการหมุน:สวิฟท์
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
วัตถุประสงค์-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- หากจำเป็น ให้หมุนรูปภาพเพื่อให้คุณสมบัติ
ส่ง
VisionImage
ไปยังวิธีการประมวลผลภาพของเครื่องตรวจจับวัตถุวิธีใดวิธีหนึ่ง คุณสามารถใช้เมธอดprocess(image:)
หรือเมธอดresults()
ในการตรวจจับวัตถุแบบอะซิงโครนัส:
สวิฟท์
objectDetector.process(image) { detectedObjects, error in guard error == nil else { // Error. return } guard let detectedObjects = detectedObjects, !detectedObjects.isEmpty else { // No objects detected. return } // Success. Get object info here. // ... }
วัตถุประสงค์-C
[objectDetector processImage:image completion:^(NSArray<FIRVisionObject *> * _Nullable objects, NSError * _Nullable error) { if (error == nil) { return; } if (objects == nil | objects.count == 0) { // No objects detected. return; } // Success. Get object info here. // ... }];
ในการตรวจจับวัตถุแบบซิงโครนัส:
สวิฟท์
var results: [VisionObject]? = nil do { results = try objectDetector.results(in: image) } catch let error { print("Failed to detect object with error: \(error.localizedDescription).") return } guard let detectedObjects = results, !detectedObjects.isEmpty else { print("Object detector returned no results.") return } // ...
วัตถุประสงค์-C
NSError *error; NSArray<FIRVisionObject *> *objects = [objectDetector resultsInImage:image error:&error]; if (error == nil) { return; } if (objects == nil | objects.count == 0) { // No objects detected. return; } // Success. Get object info here. // ...
หากการเรียกไปยังตัวประมวลผลภาพสำเร็จ การเรียกใช้รายการ
VisionObject
ไปยังตัวจัดการความสมบูรณ์หรือส่งคืนรายการ ขึ้นอยู่กับว่าคุณเรียกใช้เมธอดอะซิงโครนัสหรือซิงโครนัสVisionObject
แต่ละอันมีคุณสมบัติดังต่อไปนี้:frame
CGRect
ระบุตำแหน่งของวัตถุในภาพtrackingID
จำนวนเต็มที่ระบุวัตถุระหว่างรูปภาพ ไม่มีในโหมดภาพเดี่ยว classificationCategory
หมวดหมู่หยาบของวัตถุ หากตัวตรวจจับวัตถุไม่ได้เปิดใช้งานการจัดหมวดหมู่ สิ่งนี้จะเป็น .unknown
เสมอconfidence
ค่าความเชื่อมั่นของการจำแนกวัตถุ หากตัวตรวจจับวัตถุไม่ได้เปิดใช้งานการจัดหมวดหมู่ หรือวัตถุถูกจัดประเภทเป็นไม่ทราบ ค่านี้จะเท่ากับ nil
สวิฟท์
// detectedObjects contains one item if multiple object detection wasn't enabled. for obj in detectedObjects { let bounds = obj.frame let id = obj.trackingID // If classification was enabled: let category = obj.classificationCategory let confidence = obj.confidence }
วัตถุประสงค์-C
// The list of detected objects contains one item if multiple // object detection wasn't enabled. for (FIRVisionObject *obj in objects) { CGRect bounds = obj.frame; if (obj.trackingID) { NSInteger id = obj.trackingID.integerValue; } // If classification was enabled: FIRVisionObjectCategory category = obj.classificationCategory; float confidence = obj.confidence.floatValue; }
ปรับปรุงการใช้งานและประสิทธิภาพ
เพื่อประสบการณ์ผู้ใช้ที่ดีที่สุด โปรดปฏิบัติตามหลักเกณฑ์เหล่านี้ในแอปของคุณ:
- การตรวจหาวัตถุที่ประสบความสำเร็จขึ้นอยู่กับความซับซ้อนในการมองเห็นของวัตถุ วัตถุที่มีคุณสมบัติด้านการมองเห็นเพียงเล็กน้อยอาจต้องใช้พื้นที่ขนาดใหญ่กว่าของภาพจึงจะตรวจพบได้ คุณควรให้คำแนะนำแก่ผู้ใช้ในการจับอินพุตที่ทำงานได้ดีกับประเภทของวัตถุที่คุณต้องการตรวจจับ
- เมื่อใช้การจัดหมวดหมู่ หากคุณต้องการตรวจจับอ็อบเจ็กต์ที่ไม่อยู่ในหมวดหมู่ที่รองรับ ให้ใช้การจัดการพิเศษสำหรับอ็อบเจ็กต์ที่ไม่รู้จัก
นอกจากนี้ โปรดตรวจสอบ [แอปแสดงการออกแบบวัสดุของ ML Kit][showcase-link]{: .external } และ รูปแบบการออกแบบวัสดุสำหรับคอลเล็กชันฟีเจอร์ที่ขับเคลื่อนด้วยแมชชีนเลิร์นนิง
เมื่อใช้โหมดสตรีมมิ่งในแอปพลิเคชันแบบเรียลไทม์ ให้ปฏิบัติตามคำแนะนำเหล่านี้เพื่อให้ได้เฟรมเรตที่ดีที่สุด:
อย่าใช้การตรวจจับวัตถุหลายรายการในโหมดสตรีมมิ่ง เนื่องจากอุปกรณ์ส่วนใหญ่ไม่สามารถสร้างเฟรมเรตที่เพียงพอได้
ปิดการใช้งานการจัดหมวดหมู่หากคุณไม่ต้องการมัน
- คันเร่งเรียกไปที่เครื่องตรวจจับ หากมีเฟรมวิดีโอใหม่ในขณะที่ตัวตรวจจับกำลังทำงานอยู่ ให้ปล่อยเฟรมนั้น
- หากคุณใช้เอาต์พุตของตัวตรวจจับเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต อันดับแรกรับผลลัพธ์จาก ML Kit จากนั้นเรนเดอร์รูปภาพและโอเวอร์เลย์ในขั้นตอนเดียว การทำเช่นนี้ คุณจะเรนเดอร์ไปยังพื้นผิวจอแสดงผลเพียงครั้งเดียวสำหรับแต่ละเฟรมอินพุต ดูตัวอย่างคลาส PreviewOverlayView และ FIRDetectionOverlayView ในแอปตัวอย่าง Showcase