Nachdem Sie Ihr eigenes Modell mit AutoML Vision Edge trainiert haben , können Sie es in Ihrer App zum Beschriften von Bildern verwenden.
Bevor Sie beginnen
- Wenn Sie Firebase noch nicht zu Ihrer App hinzugefügt haben, befolgen Sie dazu die Schritte im Leitfaden „Erste Schritte“ .
- Fügen Sie die ML-Kit-Bibliotheken in Ihre Pod-Datei ein:
pod 'Firebase/MLVision', '6.25.0' pod 'Firebase/MLVisionAutoML', '6.25.0'
Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, stellen Sie sicher, dass Sie Ihr Xcode-Projekt mit seinem.xcworkspace
öffnen. - Importieren Sie Firebase in Ihre App:
Schnell
import Firebase
Ziel c
@import Firebase;
1. Laden Sie das Modell
ML Kit führt Ihre AutoML-generierten Modelle auf dem Gerät aus. Sie können ML Kit jedoch so konfigurieren, dass Ihr Modell entweder remote von Firebase, vom lokalen Speicher oder von beiden geladen wird.
Durch das Hosten des Modells auf Firebase können Sie das Modell aktualisieren, ohne eine neue App-Version zu veröffentlichen, und Sie können Remote Config und A/B-Tests verwenden, um verschiedene Modelle dynamisch für verschiedene Benutzergruppen bereitzustellen.
Wenn Sie sich dafür entscheiden, das Modell nur durch Hosten mit Firebase bereitzustellen und es nicht mit Ihrer App zu bündeln, können Sie die anfängliche Downloadgröße Ihrer App reduzieren. Beachten Sie jedoch, dass, wenn das Modell nicht mit Ihrer App gebündelt ist, alle modellbezogenen Funktionen erst verfügbar sind, wenn Ihre App das Modell zum ersten Mal herunterlädt.
Durch die Bündelung Ihres Modells mit Ihrer App können Sie sicherstellen, dass die ML-Funktionen Ihrer App auch dann funktionieren, wenn das von Firebase gehostete Modell nicht verfügbar ist.
Konfigurieren Sie eine von Firebase gehostete Modellquelle
Um das remote gehostete Modell zu verwenden, erstellen Sie ein AutoMLRemoteModel
Objekt und geben Sie dabei den Namen an, den Sie dem Modell beim Veröffentlichen zugewiesen haben:
Schnell
let remoteModel = AutoMLRemoteModel(
name: "your_remote_model" // The name you assigned in the Firebase console.
)
Ziel c
FIRAutoMLRemoteModel *remoteModel = [[FIRAutoMLRemoteModel alloc]
initWithName:@"your_remote_model"]; // The name you assigned in the Firebase console.
Starten Sie dann die Aufgabe zum Herunterladen des Modells und geben Sie die Bedingungen an, unter denen Sie den Download zulassen möchten. Wenn sich das Modell nicht auf dem Gerät befindet oder eine neuere Version des Modells verfügbar ist, lädt die Aufgabe das Modell asynchron von Firebase herunter:
Schnell
let downloadConditions = ModelDownloadConditions(
allowsCellularAccess: true,
allowsBackgroundDownloading: true
)
let downloadProgress = ModelManager.modelManager().download(
remoteModel,
conditions: downloadConditions
)
Ziel c
FIRModelDownloadConditions *downloadConditions =
[[FIRModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
[[FIRModelManager modelManager] downloadRemoteModel:remoteModel
conditions:downloadConditions];
Viele Apps starten die Download-Aufgabe in ihrem Initialisierungscode, Sie können dies jedoch jederzeit tun, bevor Sie das Modell verwenden müssen.
Konfigurieren Sie eine lokale Modellquelle
So bündeln Sie das Modell mit Ihrer App:
- Extrahieren Sie das Modell und seine Metadaten aus dem Zip-Archiv, das Sie von der Firebase-Konsole heruntergeladen haben, in einen Ordner:
your_model_directory |____dict.txt |____manifest.json |____model.tflite
Alle drei Dateien müssen sich im selben Ordner befinden. Wir empfehlen Ihnen, die Dateien so zu verwenden, wie Sie sie heruntergeladen haben, ohne Änderungen (einschließlich der Dateinamen). - Kopieren Sie den Ordner in Ihr Xcode-Projekt und achten Sie dabei darauf, Ordnerverweise erstellen auszuwählen. Die Modelldatei und die Metadaten werden im App-Bundle enthalten und für ML Kit verfügbar sein.
- Erstellen Sie ein
AutoMLLocalModel
Objekt und geben Sie den Pfad zur Modellmanifestdatei an:Schnell
guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return true } let localModel = AutoMLLocalModel(manifestPath: manifestPath)
Ziel c
NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; FIRAutoMLLocalModel *localModel = [[FIRAutoMLLocalModel alloc] initWithManifestPath:manifestPath];
Erstellen Sie aus Ihrem Modell einen Bildbeschrifter
Nachdem Sie Ihre Modellquellen konfiguriert haben, erstellen Sie aus einer davon ein VisionImageLabeler
Objekt.
Wenn Sie nur über ein lokal gebündeltes Modell verfügen, erstellen Sie einfach einen Labeler aus Ihrem AutoMLLocalModel
Objekt und konfigurieren Sie den Schwellenwert für die Konfidenzbewertung, den Sie benötigen möchten (siehe Bewerten Sie Ihr Modell ):
Schnell
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)
Ziel 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];
Wenn Sie über ein remote gehostetes Modell verfügen, müssen Sie überprüfen, ob es heruntergeladen wurde, bevor Sie es ausführen. Sie können den Status der Modell-Download-Aufgabe mithilfe der Methode isModelDownloaded(remoteModel:)
des Modellmanagers überprüfen.
Obwohl Sie dies nur bestätigen müssen, bevor Sie den Labeler ausführen, kann es sinnvoll sein, diese Prüfung bei der Instanziierung des VisionImageLabeler
durchzuführen, wenn Sie sowohl ein remote gehostetes Modell als auch ein lokal gebündeltes Modell haben: Erstellen Sie einen Labeler aus dem Remote-Modell, wenn dies der Fall ist heruntergeladen wurden, andernfalls vom lokalen Modell.
Schnell
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)
Ziel 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];
Wenn Sie nur über ein remote gehostetes Modell verfügen, sollten Sie modellbezogene Funktionen deaktivieren (z. B. einen Teil Ihrer Benutzeroberfläche ausgrauen oder ausblenden), bis Sie bestätigen, dass das Modell heruntergeladen wurde.
Sie können den Modell-Download-Status abrufen, indem Sie Beobachter an das Standard-Benachrichtigungscenter anhängen. Stellen Sie sicher, dass Sie im Beobachterblock einen schwachen Verweis auf self
verwenden, da Downloads einige Zeit dauern können und das ursprüngliche Objekt bis zum Abschluss des Downloads freigegeben werden kann. Zum Beispiel:
Schnell
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] // ... }
Ziel 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. Bereiten Sie das Eingabebild vor
Erstellen Sie dann für jedes Bild, das Sie beschriften möchten, ein VisionImage
Objekt mit einer der in diesem Abschnitt beschriebenen Optionen und übergeben Sie es an eine Instanz von VisionImageLabeler
(im nächsten Abschnitt beschrieben).
Erstellen Sie ein VisionImage
Objekt mit einem UIImage
oder einem CMSampleBufferRef
.
So verwenden Sie ein UIImage
:
- Drehen Sie das Bild bei Bedarf so, dass seine
imageOrientation
Eigenschaft.up
hat. - Erstellen Sie ein
VisionImage
Objekt mit dem korrekt gedrehtenUIImage
. Geben Sie keine Rotationsmetadaten an – der Standardwert.topLeft
muss verwendet werden.Schnell
let image = VisionImage(image: uiImage)
Ziel c
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
So verwenden Sie ein CMSampleBufferRef
:
Erstellen Sie ein
VisionImageMetadata
Objekt, das die Ausrichtung der imCMSampleBufferRef
Puffer enthaltenen Bilddaten angibt.So erhalten Sie die Bildausrichtung:
Schnell
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 } }
Ziel 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; } }
Erstellen Sie dann das Metadatenobjekt:
Schnell
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Ziel 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];
- Erstellen Sie ein
VisionImage
Objekt mit demCMSampleBufferRef
-Objekt und den Rotationsmetadaten:Schnell
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Ziel c
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
3. Führen Sie den Bildbeschrifter aus
Um Objekte in einem Bild zu beschriften, übergeben Sie das VisionImage
Objekt an die Methode process()
von VisionImageLabeler
:
Schnell
labeler.process(image) { labels, error in
guard error == nil, let labels = labels else { return }
// Task succeeded.
// ...
}
Ziel c
[labeler
processImage:image
completion:^(NSArray<FIRVisionImageLabel *> *_Nullable labels, NSError *_Nullable error) {
if (error != nil || labels == nil) {
return;
}
// Task succeeded.
// ...
}];
Wenn die Bildbeschriftung erfolgreich ist, wird ein Array von VisionImageLabel
Objekten an den Abschlusshandler übergeben. Von jedem Objekt können Sie Informationen über ein im Bild erkanntes Merkmal erhalten.
Zum Beispiel:
Schnell
for label in labels {
let labelText = label.text
let confidence = label.confidence
}
Ziel c
for (FIRVisionImageLabel *label in labels) {
NSString *labelText = label.text;
NSNumber *confidence = label.confidence;
}
Tipps zur Verbesserung der Echtzeitleistung
- Gasrufe an den Detektor. Wenn ein neues Videobild verfügbar wird, während der Detektor läuft, löschen Sie das Bild.
- Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken auf dem Eingabebild zu überlagern, rufen Sie zunächst das Ergebnis vom ML Kit ab und rendern Sie dann das Bild und überlagern Sie es in einem einzigen Schritt. Auf diese Weise rendern Sie für jeden Eingaberahmen nur einmal auf der Anzeigeoberfläche. Ein Beispiel finden Sie in den Klassen „previewOverlayView “ und „FIRDetectionOverlayView“ in der Showcase-Beispiel-App.