Sau khi bạn tự đào tạo bằng AutoML Vision Edge, bạn có thể sử dụng mô hình này trong ứng dụng để gắn nhãn hình ảnh.
Trước khi bắt đầu
- Nếu bạn chưa thêm Firebase vào ứng dụng của mình, hãy thực hiện bằng cách làm theo hướng dẫn các bước trong hướng dẫn bắt đầu sử dụng.
- Thêm các thư viện Bộ công cụ học máy vào Podfile của bạn:
Sau khi cài đặt hoặc cập nhật Nhóm của dự án, hãy nhớ mở Xcode dự án bằngpod 'Firebase/MLVision', '6.25.0' pod 'Firebase/MLVisionAutoML', '6.25.0'
.xcworkspace
của nó. - Trong ứng dụng của bạn, hãy nhập Firebase:
Swift
import Firebase
Objective-C
@import Firebase;
1. Tải mô hình
Bộ công cụ học máy sẽ chạy các mô hình do AutoML tạo trên thiết bị. Tuy nhiên, bạn có thể định cấu hình Bộ công cụ học máy để tải mô hình của bạn từ xa từ Firebase, bộ nhớ cục bộ hoặc cả hai.
Bằng cách lưu trữ mô hình trên Firebase, bạn có thể cập nhật mô hình mà không cần phát hành một phiên bản ứng dụng mới và bạn có thể sử dụng Remote Config và A/B Testing để phân phát linh động các mô hình khác nhau cho các nhóm người dùng khác nhau.
Nếu bạn chỉ chọn cung cấp mô hình bằng cách lưu trữ mô hình đó bằng Firebase, chứ không phải hãy kết hợp ứng dụng đó với ứng dụng, bạn có thể giảm kích thước tải xuống ban đầu của ứng dụng. Mặc dù vậy, hãy lưu ý rằng nếu mô hình không được đóng gói với ứng dụng của bạn, bất kỳ sẽ không có sẵn chức năng liên quan đến mô hình cho đến khi ứng dụng của bạn tải xuống mô hình lần đầu tiên.
Bằng cách kết hợp mô hình với ứng dụng, bạn có thể đảm bảo các tính năng học máy của ứng dụng vẫn hoạt động khi không có mô hình lưu trữ trên Firebase.
Định cấu hình nguồn mô hình được lưu trữ trên Firebase
Để sử dụng mô hình được lưu trữ từ xa, hãy tạo một đối tượng AutoMLRemoteModel
,
chỉ định tên mà bạn đã chỉ định cho mô hình khi xuất bản:
Swift
let remoteModel = AutoMLRemoteModel(
name: "your_remote_model" // The name you assigned in the Firebase console.
)
Objective-C
FIRAutoMLRemoteModel *remoteModel = [[FIRAutoMLRemoteModel alloc]
initWithName:@"your_remote_model"]; // The name you assigned in the Firebase console.
Sau đó, bắt đầu tác vụ tải mô hình xuống, chỉ định các điều kiện mà theo đó mà bạn muốn cho phép tải xuống. Nếu kiểu máy này không có trên thiết bị hoặc nếu là kiểu máy mới hơn phiên bản của mô hình sẵn có, tác vụ sẽ tải xuống không đồng bộ mô hình từ Firebase:
Swift
let downloadConditions = ModelDownloadConditions(
allowsCellularAccess: true,
allowsBackgroundDownloading: true
)
let downloadProgress = ModelManager.modelManager().download(
remoteModel,
conditions: downloadConditions
)
Objective-C
FIRModelDownloadConditions *downloadConditions =
[[FIRModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
[[FIRModelManager modelManager] downloadRemoteModel:remoteModel
conditions:downloadConditions];
Nhiều ứng dụng bắt đầu tác vụ tải xuống trong mã khởi chạy, nhưng bạn có thể làm như vậy bất cứ lúc nào trước khi cần sử dụng mô hình.
Định cấu hình nguồn mô hình cục bộ
Cách đóng gói mô hình với ứng dụng:
- Trích xuất mô hình và siêu dữ liệu của mô hình từ tệp lưu trữ zip mà bạn đã tải xuống
từ bảng điều khiển Firebase vào một thư mục:
Cả 3 tệp phải nằm trong cùng một thư mục. Bạn nên dùng các tệp này làm bạn đã tải chúng xuống mà không sửa đổi (bao gồm tên tệp).your_model_directory |____dict.txt |____manifest.json |____model.tflite
- Sao chép thư mục vào dự án Xcode của bạn, nhớ chọn Tạo tệp tham chiếu thư mục khi bạn làm như vậy. Tệp mô hình và siêu dữ liệu sẽ có trong gói ứng dụng và được cung cấp trong Bộ công cụ học máy.
- Tạo một đối tượng
AutoMLLocalModel
, chỉ định đường dẫn đến tệp kê khai mô hình tệp:Swift
guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return true } let localModel = AutoMLLocalModel(manifestPath: manifestPath)
Objective-C
NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; FIRAutoMLLocalModel *localModel = [[FIRAutoMLLocalModel alloc] initWithManifestPath:manifestPath];
Tạo công cụ gắn nhãn hình ảnh từ mô hình của bạn
Sau khi định cấu hình các nguồn mô hình, hãy tạo một đối tượng VisionImageLabeler
từ một trong số họ.
Nếu bạn chỉ có mô hình được gói cục bộ, chỉ cần tạo một công cụ gắn nhãn từ
AutoMLLocalModel
đối tượng và định cấu hình ngưỡng điểm tin cậy mà bạn muốn
để yêu cầu (xem Đánh giá mô hình của bạn):
Swift
let options = VisionOnDeviceAutoMLImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = 0 // Evaluate your model in the Firebase console
// to determine an appropriate value.
let labeler = Vision.vision().onDeviceAutoMLImageLabeler(options: options)
Objective-C
FIRVisionOnDeviceAutoMLImageLabelerOptions *options =
[[FIRVisionOnDeviceAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = 0; // Evaluate your model in the Firebase console
// to determine an appropriate value.
FIRVisionImageLabeler *labeler =
[[FIRVision vision] onDeviceAutoMLImageLabelerWithOptions:options];
Nếu có mô hình được lưu trữ từ xa, bạn sẽ phải kiểm tra xem mô hình đó đã được
tải xuống trước khi chạy nó. Bạn có thể kiểm tra trạng thái tải mô hình xuống
bằng cách sử dụng phương thức isModelDownloaded(remoteModel:)
của trình quản lý mô hình.
Mặc dù bạn chỉ phải xác nhận điều này trước khi chạy nhãn, nếu bạn
có cả mô hình được lưu trữ từ xa và mô hình được gói cục bộ,
ý nghĩa để thực hiện bước kiểm tra này khi tạo thực thể cho VisionImageLabeler
: tạo
công cụ gắn nhãn từ mô hình từ xa nếu công cụ đó đã được tải xuống và từ
mô hình khác.
Swift
var options: VisionOnDeviceAutoMLImageLabelerOptions?
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
options = VisionOnDeviceAutoMLImageLabelerOptions(remoteModel: remoteModel)
} else {
options = VisionOnDeviceAutoMLImageLabelerOptions(localModel: localModel)
}
options.confidenceThreshold = 0 // Evaluate your model in the Firebase console
// to determine an appropriate value.
let labeler = Vision.vision().onDeviceAutoMLImageLabeler(options: options)
Objective-C
VisionOnDeviceAutoMLImageLabelerOptions *options;
if ([[FIRModelManager modelManager] isModelDownloaded:remoteModel]) {
options = [[FIRVisionOnDeviceAutoMLImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
options = [[FIRVisionOnDeviceAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = 0.0f; // Evaluate your model in the Firebase console
// to determine an appropriate value.
FIRVisionImageLabeler *labeler = [[FIRVision vision] onDeviceAutoMLImageLabelerWithOptions:options];
Nếu chỉ có một mô hình được lưu trữ từ xa, bạn nên tắt tính năng liên quan đến mô hình đó chức năng (ví dụ: chuyển sang màu xám hoặc ẩn một phần giao diện người dùng) cho đến khi bạn xác nhận mô hình đã được tải xuống.
Bạn có thể biết trạng thái tải xuống mô hình bằng cách đính kèm đối tượng tiếp nhận dữ liệu vào giá trị mặc định
Trung tâm thông báo. Hãy nhớ sử dụng tệp tham chiếu yếu đến self
trong trình quan sát
vì quá trình tải xuống có thể mất chút thời gian và đối tượng gốc có thể
được giải phóng vào thời điểm hoàn tất tải xuống. Ví dụ:
Swift
NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidSucceed, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel, model.name == "your_remote_model" else { return } // The model was downloaded and is available on the device } NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidFail, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel else { return } let error = userInfo[ModelDownloadUserInfoKey.error.rawValue] // ... }
Objective-C
__weak typeof(self) weakSelf = self; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidSucceedNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel]; if ([model.name isEqualToString:@"your_remote_model"]) { // The model was downloaded and is available on the device } }]; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidFailNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; NSError *error = note.userInfo[FIRModelDownloadUserInfoKeyError]; }];
2. Chuẩn bị hình ảnh đầu vào
Sau đó, đối với mỗi hình ảnh bạn muốn gắn nhãn, hãy tạo đối tượng VisionImage
bằng một đối tượng
của các tuỳ chọn được mô tả trong phần này và truyền vào phiên bản của
VisionImageLabeler
(như mô tả trong phần tiếp theo).
Tạo đối tượng VisionImage
bằng UIImage
hoặc
CMSampleBufferRef
.
Cách sử dụng UIImage
:
- Nếu cần, hãy xoay hình ảnh để
imageOrientation
là.up
. - Tạo đối tượng
VisionImage
bằng chế độ xoay chính xácUIImage
Không chỉ định bất kỳ siêu dữ liệu xoay vòng nào—mặc định bạn phải sử dụng giá trị.topLeft
.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Cách sử dụng CMSampleBufferRef
:
-
Tạo đối tượng
VisionImageMetadata
chỉ định của dữ liệu hình ảnh chứa trong Vùng đệmCMSampleBufferRef
.Cách lấy hướng ảnh:
Swift
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 } }
Objective-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; } }
Sau đó, hãy tạo đối tượng siêu dữ liệu:
Swift
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objective-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];
- Tạo đối tượng
VisionImage
bằng Đối tượngCMSampleBufferRef
và siêu dữ liệu xoay:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
3. Chạy công cụ gắn nhãn hình ảnh
Để gắn nhãn cho các đối tượng trong hình ảnh, hãy truyền đối tượng VisionImage
vào phương thức
Phương thức process()
của VisionImageLabeler
:
Swift
labeler.process(image) { labels, error in
guard error == nil, let labels = labels else { return }
// Task succeeded.
// ...
}
Objective-C
[labeler
processImage:image
completion:^(NSArray<FIRVisionImageLabel *> *_Nullable labels, NSError *_Nullable error) {
if (error != nil || labels == nil) {
return;
}
// Task succeeded.
// ...
}];
Nếu gắn nhãn hình ảnh thành công, một mảng các đối tượng VisionImageLabel
sẽ
được chuyển đến trình xử lý hoàn thành. Từ mỗi đối tượng, bạn có thể lấy thông tin
về đối tượng nhận diện được trong hình ảnh.
Ví dụ:
Swift
for label in labels {
let labelText = label.text
let confidence = label.confidence
}
Objective-C
for (FIRVisionImageLabel *label in labels) {
NSString *labelText = label.text;
NSNumber *confidence = label.confidence;
}
Mẹo cải thiện hiệu suất theo thời gian thực
- Điều tiết lệnh gọi đến trình phát hiện. Nếu một khung video mới trong khi trình phát hiện đang chạy, hãy thả khung hình.
- Nếu bạn đang 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. Xem previewOverlayView và FIRDetectionOverlayView trong ứng dụng mẫu Showcase.