Bạn có thể dùng Bộ công cụ học máy để phát hiện và theo dõi các đối tượng trong các khung hình video liên tiếp.
Khi bạn truyền hình ảnh đến Bộ công cụ học máy, công cụ này sẽ phát hiện tối đa 5 đối tượng trong hình ảnh đó cùng với vị trí của mỗi đối tượng trong hình ảnh. Khi phát hiện đối tượng trong luồng video, mỗi đối tượng có một mã nhận dạng duy nhất mà bạn có thể dùng để theo dõi đối tượng giữa các khung hình. Bạn cũng có thể tùy ý bật đối tượng tương đối Phân loại để gắn nhãn các đối tượng bằng mô tả danh mục rộng.
Dùng thử
- Dùng thử ứng dụng mẫu để xem ví dụ về cách sử dụng API này.
- Xem trang giới thiệu Material Design để triển khai toàn diện API này.
Trước khi bắt đầu
- Đưa các nhóm Bộ công cụ học máy sau đây vào Podfile của bạn:
pod 'GoogleMLKit/ObjectDetection', '3.2.0'
- Sau khi bạn cài đặt hoặc cập nhật Nhóm của dự án, hãy mở dự án Xcode của bạn bằng cách sử dụng
.xcworkspace
. Bộ công cụ học máy được hỗ trợ trong Xcode phiên bản 12.4 trở lên.
1. Định cấu hình trình phát hiện đối tượng
Để phát hiện và theo dõi các đối tượng, trước tiên hãy tạo một thực thể của
ObjectDetector
và tuỳ ý chỉ định mọi chế độ cài đặt trình phát hiện bạn muốn
thay đổi so với giá trị mặc định.
Định cấu hình trình phát hiện đối tượng cho trường hợp sử dụng của bạn bằng Đối tượng
ObjectDetectorOptions
. Bạn có thể thay đổi các tuỳ chọn sau cài đặt:Cài đặt trình phát hiện đối tượng Chế độ phát hiện .stream
(mặc định) |.singleImage
Ở chế độ phát trực tuyến (mặc định), trình phát hiện đối tượng chạy với mức pin rất thấp nhưng có thể dẫn đến kết quả không đầy đủ (chẳng hạn như kết quả không được chỉ định) hộp giới hạn hoặc danh mục) trên một số lệnh gọi đầu tiên của trình phát hiện. Ngoài ra, ở chế độ phát trực tuyến, trình phát hiện gán tính năng theo dõi Mã nhận dạng của các đối tượng mà bạn có thể dùng để theo dõi đối tượng trên nhiều khung hình. Sử dụng chế độ này khi bạn muốn theo dõi các đối tượng hoặc khi có độ trễ thấp rất quan trọng, chẳng hạn như khi xử lý luồng video trong thực tế bất cứ lúc nào.
Ở chế độ hình ảnh đơn, trình phát hiện đối tượng sẽ trả về kết quả sau khi xác định vùng giới hạn của đối tượng. Nếu bạn cũng bật phương thức này sẽ trả về kết quả sau hộp giới hạn và nhãn danh mục đều có sẵn. Do vậy, việc phát hiện thì độ trễ có thể cao hơn. Ngoài ra, ở chế độ hình ảnh đơn, tính năng theo dõi Chưa chỉ định mã nhận dạng. Sử dụng chế độ này nếu độ trễ không quan trọng và bạn không muốn xử lý một phần kết quả.
Phát hiện và theo dõi nhiều đối tượng false
(mặc định) |true
Phát hiện và theo dõi tối đa 5 đối tượng hay chỉ phát hiện tối đa đối tượng đối tượng nổi bật (mặc định).
Phân loại đối tượng false
(mặc định) |true
Liệu có phân loại các đối tượng được phát hiện thành các danh mục tương đối hay không. Khi được bật, trình phát hiện đối tượng sẽ phân loại đối tượng thành các danh mục sau: hàng thời trang, thực phẩm, đồ gia dụng, địa điểm và cây cối.
API theo dõi và phát hiện đối tượng được tối ưu hoá cho hai mục đích sử dụng cốt lõi này trường hợp:
- Phát hiện trực tiếp và theo dõi đối tượng nổi bật nhất trong máy ảnh kính ngắm.
- Phát hiện nhiều đối tượng trong ảnh tĩnh.
Cách định cấu hình API cho các trường hợp sử dụng này:
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;
- Nhận một thực thể của
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. Chuẩn bị hình ảnh đầu vào
Để phát hiện và theo dõi các đối tượng, hãy làm như sau cho từng hình ảnh hoặc khung video.
Nếu đã bật chế độ phát trực tuyến, bạn phải tạo các đối tượng VisionImage
từ
CMSampleBuffer
giây.
Tạo đối tượng VisionImage
bằng UIImage
hoặc
CMSampleBuffer
.
Nếu bạn sử dụng UIImage
, hãy làm theo các bước sau:
- Tạo đối tượng
VisionImage
bằngUIImage
. Hãy nhớ chỉ định đúng.orientation
.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Nếu bạn sử dụng CMSampleBuffer
, hãy làm theo các bước sau:
-
Chỉ định hướng của dữ liệu hình ảnh có trong
CMSampleBuffer
.Cách lấy hướng ảnh:
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; } }
- Tạo đối tượng
VisionImage
bằng cách sử dụng Đối tượng và hướngCMSampleBuffer
: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. Xử lý hình ảnh
TruyềnVisionImage
đến một trong các trình xử lý hình ảnh của trình phát hiện đối tượng
. Bạn có thể sử dụng phương thức process(image:)
không đồng bộ hoặc
results()
đồng bộ.
Cách phát hiện đối tượng không đồng bộ:
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. }];
Cách phát hiện đối tượng một cách đồng bộ:
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. Lấy thông tin về đối tượng được phát hiện
Nếu lệnh gọi đến bộ xử lý hình ảnh thành công, lệnh gọi đó sẽ chuyển danh sáchObject
cho trình xử lý hoàn thành hoặc trả về danh sách, tuỳ thuộc vào
cho dù bạn đã gọi phương thức không đồng bộ hay đồng bộ.
Mỗi Object
chứa các thuộc tính sau:
frame |
CGRect cho biết vị trí của đối tượng trong
hình ảnh. |
trackingID |
Một số nguyên xác định đối tượng trên các hình ảnh hoặc `nil` trong chế độ hình ảnh đơn. |
labels |
Một mảng nhãn mô tả đối tượng mà trình phát hiện trả về.
Thuộc tính sẽ trống nếu tuỳ chọn trình phát hiện
shouldEnableClassification được đặt thành 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]; ... } }
Cải thiện khả năng hữu dụng và hiệu suất
Để có trải nghiệm người dùng tốt nhất, hãy làm theo các nguyên tắc sau trong ứng dụng của bạn:
- Việc phát hiện được đối tượng có thành công hay không còn phụ thuộc vào độ phức tạp trực quan của đối tượng. Ngang bằng những đối tượng có một số ít đặc điểm trực quan có thể cần được phát hiện chiếm phần lớn hình ảnh. Bạn nên cung cấp cho người dùng hướng dẫn về thu thập dữ liệu đầu vào phù hợp với loại đối tượng bạn muốn phát hiện.
- Khi sử dụng tính năng phân loại, nếu bạn muốn phát hiện các đối tượng không nằm trong rõ ràng vào các danh mục được hỗ trợ, triển khai cách xử lý đặc biệt đối với các trường hợp không xác định .
Ngoài ra, hãy tham khảo Material Design Bộ sưu tập Mẫu cho các tính năng dựa trên công nghệ học máy.
Khi bạn sử dụng chế độ truyền trực tuyến trong một ứng dụng theo thời gian thực, hãy làm theo các nguyên tắc sau để đạt được tốc độ khung hình tốt nhất:
- Đừng dùng tính năng phát hiện nhiều vật thể ở chế độ phát trực tuyến, vì hầu hết các thiết bị sẽ không dùng được có thể tạo đủ tốc độ khung hình.
- Hãy tắt tính năng phân loại nếu bạn không cần.
- Để xử lý khung hình video, hãy sử dụng API đồng bộ
results(in:)
của trình phát hiện. Gọi điện phương thức này từ Điều khoản dịch vụ và Chính sách quyền riêng tư củaAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
để nhận kết quả một cách đồng bộ từ video đã cho khung. Giữ củaAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
dưới dạngtrue
để điều tiết lệnh gọi đến trình phát hiện. Nếu một khách hàng mới khung hình video sẽ bị loại bỏ trong khi trình phát hiện đang chạy. - Nếu bạn sử dụng đầu ra của trình phát hiện để phủ đồ hoạ lên hình ảnh đầu vào, trước tiên hãy lấy kết quả từ Bộ công cụ học máy, sau đó kết xuất hình ảnh và phủ lên trên trong một bước duy nhất. Khi làm vậy, bạn sẽ kết xuất lên giao diện màn hình một lần cho mỗi khung đầu vào đã xử lý. Hãy xem lớp updatePreviewOverlayViewWithLastFrame trong mẫu bắt đầu nhanh của Bộ công cụ học máy.