Po wytrenowaniu model z użyciem AutoML Vision Edge, możesz go używać w swojej aplikacji do oznaczania etykietami obrazów.
Zanim zaczniesz
- Jeśli nie masz jeszcze w aplikacji dodanej Firebase, wykonaj czynności podane w przewodniku dla początkujących.
- Umieść biblioteki ML Kit w pliku Podfile:
Po zainstalowaniu lub zaktualizowaniu podów projektu otwórz Xcode projektu korzystającego z:pod 'Firebase/MLVision', '6.25.0' pod 'Firebase/MLVisionAutoML', '6.25.0'
.xcworkspace
. - W aplikacji zaimportuj Firebase:
Swift
import Firebase
Objective-C
@import Firebase;
1. Wczytaj model
ML Kit uruchamia modele wygenerowane przez AutoML na urządzeniu. Możesz jednak: skonfiguruj ML Kit, aby ładował Twój model zdalnie z Firebase, pamięci lokalnej lub obu tych metod.
Hostując model w Firebase, możesz go aktualizować bez konieczności jego publikowania nową wersję aplikacji. Możesz używać Remote Config i A/B Testing, dynamicznie udostępniać różne modele różnym grupom użytkowników.
Jeśli zdecydujesz się udostępniać model tylko poprzez hosting w Firebase, a nie pakietu z aplikacją, możesz zmniejszyć początkowy rozmiar pobieranej aplikacji. Pamiętaj jednak, że jeśli do aplikacji nie dołączony jest model, funkcje związane z modelem będą dostępne dopiero po pobraniu przez aplikację z użyciem modelu po raz pierwszy.
Jeśli połączysz model z aplikacją, będziesz mieć pewność, że funkcje ML w aplikacji będą działać. działają też wtedy, gdy model hostowany przez Firebase jest niedostępny.
Skonfiguruj źródło modelu hostowanego w Firebase
Aby używać modelu hostowanego zdalnie, utwórz obiekt AutoMLRemoteModel
,
określając nazwę przypisaną do modelu podczas jego publikowania:
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.
Następnie uruchom zadanie pobierania modelu, określając warunki, które którym chcesz zezwolić na pobieranie. Jeśli nie ma modelu na urządzeniu lub jest on nowszy gdy dostępna będzie wersja modelu, zadanie asynchronicznie pobierze model z 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];
Wiele aplikacji rozpoczyna zadanie pobierania w kodzie inicjowania, możesz to zrobić w dowolnym momencie, zanim trzeba będzie skorzystać z modelu.
Skonfiguruj źródło modelu lokalnego
Aby połączyć model z aplikacją:
- Wyodrębnij model i jego metadane z pobranego archiwum ZIP
z konsoli Firebase do folderu:
Wszystkie 3 pliki muszą znajdować się w tym samym folderze. Zalecamy używanie plików jako pobrane bez modyfikacji (łącznie z nazwami plików).your_model_directory |____dict.txt |____manifest.json |____model.tflite
- Skopiuj folder do projektu Xcode, wybierając go Utwórz odwołania do folderów. Plik modelu i metadane zostaną uwzględnione w pakiecie aplikacji i będą dostępne dla ML Kit.
- Utwórz obiekt
AutoMLLocalModel
, określając ścieżkę do pliku manifestu modelu plik: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];
Tworzenie osoby oznaczającej obrazy na podstawie modelu
Po skonfigurowaniu źródeł modeli utwórz obiekt VisionImageLabeler
od jednego z nich.
Jeśli masz tylko model scalony lokalnie, po prostu utwórz osobę oznaczającą etykietami na podstawie
AutoMLLocalModel
obiekt i skonfiguruj odpowiedni próg wskaźnika ufności
wymagane (zobacz Ocena modelu):
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];
Jeśli masz model hostowany zdalnie, musisz sprawdzić, czy został
pobrane przed uruchomieniem. Stan pobierania modelu możesz sprawdzić
za pomocą metody isModelDownloaded(remoteModel:)
menedżera modeli.
Chociaż trzeba to potwierdzić tylko przed uruchomieniem osoby oznaczającej etykietami,
korzystają zarówno z modelu hostowanego zdalnie, jak i z pakietu lokalnego, może to sprawić,
warto przeprowadzić tę kontrolę przy tworzeniu wystąpienia VisionImageLabeler
: create
osoby oznaczającej etykietami z modelu zdalnego, jeśli został on pobrany, oraz z modelu lokalnego
w inny sposób.
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];
Jeśli masz tylko model hostowany zdalnie, wyłącz powiązany z nim model funkcji – na przykład wyszarzenia lub ukrycia części interfejsu – do potwierdzasz, że model został pobrany.
Stan pobierania modelu możesz sprawdzić, dołączając obserwatorów do wartości domyślnej.
Centrum powiadomień. Pamiętaj, aby w obserwatorium używać słabego odniesienia do self
bo pobieranie może trochę potrwać, a źródłowy obiekt
zwolniony do momentu zakończenia pobierania. Przykład:
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. Przygotowywanie obrazu wejściowego
Następnie dla każdego obrazu, który chcesz oznaczyć etykietą, utwórz obiekt VisionImage
za pomocą jednego
z opcji opisanych w tej sekcji i przekazać ją do instancji
VisionImageLabeler
(opisane w następnej sekcji).
Utwórz obiekt VisionImage
za pomocą UIImage
lub
CMSampleBufferRef
.
Aby użyć karty UIImage
:
- W razie potrzeby obróć zdjęcie, tak by jego
imageOrientation
właściwość to.up
. - Utwórz obiekt
VisionImage
przy użyciu prawidłowo wykonanej rotacjiUIImage
Nie określaj żadnych metadanych rotacji – są to metadane domyślne..topLeft
.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Aby użyć karty CMSampleBufferRef
:
-
Utwórz obiekt
VisionImageMetadata
, który określa orientacji danych zdjęć zawartych w BuforCMSampleBufferRef
.Aby sprawdzić orientację obrazu:
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; } }
Następnie utwórz obiekt metadanych:
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];
- Utwórz obiekt
VisionImage
za pomocą ObiektCMSampleBufferRef
i metadane rotacji:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
3. Uruchamianie oznaczania obrazów
Aby oznaczyć etykietami obiekty na obrazie, przekaż obiekt VisionImage
do funkcji
Metoda process()
użytkownika 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.
// ...
}];
Jeśli oznaczenie obrazów zostanie oznaczone etykietami, zostanie tablica VisionImageLabel
obiektów
przekazywane do modułu obsługi uzupełniania. Informacje o każdym obiekcie
o funkcji rozpoznanej na zdjęciu.
Przykład:
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;
}
Wskazówki dotyczące poprawy skuteczności w czasie rzeczywistym
- Ogranicz wywołania do detektora. Jeśli nowa klatka wideo dostępnych, gdy detektor jest uruchomiony, upuść ramkę.
- Jeśli używasz danych wyjściowych detektora do nakładania grafiki na obrazu wejściowego, najpierw pobierz wynik z ML Kit, a następnie wyrenderuj obraz i nakładanie nakładek w jednym kroku. W ten sposób renderowanie na powierzchni tylko raz na każdą ramkę wejściową. Zobacz previewOverlayView. i FIRDetectionOverlayView w aplikacji z funkcją prezentacji.