Une fois que vous avez entraîné votre propre modèle à l'aide d'AutoML Vision Edge, vous pouvez l'utiliser dans votre application pour étiqueter des images.
Il existe deux façons d'intégrer des modèles entraînés à partir d'AutoML Vision Edge. Vous pouvez regrouper le modèle en copiant ses fichiers dans votre projet Xcode ou le télécharger de manière dynamique depuis Firebase.
| Options de regroupement de modèles | |
|---|---|
| Regroupé dans votre application | 
 | 
| Hébergé avec Firebase | 
 | 
Avant de commencer
- Incluez les bibliothèques ML Kit dans votre fichier Podfile : - Pour regrouper un modèle avec votre application : - pod 'GoogleMLKit/ImageLabelingCustom'- Pour télécharger un modèle de manière dynamique depuis Firebase, ajoutez la dépendance - LinkFirebase:- pod 'GoogleMLKit/ImageLabelingCustom' pod 'GoogleMLKit/LinkFirebase'
- Après avoir installé ou mis à jour les pods de votre projet, ouvrez votre projet Xcode à l'aide de son fichier - .xcworkspace. ML Kit est compatible avec Xcode version 12.2 ou ultérieure.
- Si vous souhaitez télécharger un modèle, assurez-vous d'ajouter Firebase à votre projet Android, si ce n'est pas déjà fait. Cette étape n'est pas nécessaire lorsque vous regroupez le modèle. 
1. Charger le modèle
Configurer une source de modèle local
Pour regrouper le modèle avec votre application :
- Extrayez le modèle et ses métadonnées de l'archive ZIP que vous avez téléchargée depuis la console Firebase dans un dossier : - your_model_directory |____dict.txt |____manifest.json |____model.tflite- Les trois fichiers doivent se trouver dans le même dossier. Nous vous recommandons d'utiliser les fichiers tels que vous les avez téléchargés, sans les modifier (y compris les noms de fichiers). 
- Copiez le dossier dans votre projet Xcode en veillant à sélectionner Create folder references (Créer des références de dossier). Le fichier de modèle et les métadonnées seront inclus dans le bundle de l'application et disponibles pour ML Kit. 
- Créez un objet - LocalModelen spécifiant le chemin d'accès au fichier manifeste du modèle :- Swift- guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return true } let localModel = LocalModel(manifestPath: manifestPath)- Objective-C- NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithManifestPath:manifestPath];
Configurer une source de modèle hébergée par Firebase
Pour utiliser le modèle hébergé à distance, créez un objet CustomRemoteModel en spécifiant le nom que vous avez attribué au modèle lors de sa publication :
Swift
// Initialize the model source with the name you assigned in
// the Firebase console.
let remoteModelSource = FirebaseModelSource(name: "your_remote_model")
let remoteModel = CustomRemoteModel(remoteModelSource: remoteModelSource)
Objective-C
// Initialize the model source with the name you assigned in
// the Firebase console.
MLKFirebaseModelSource *firebaseModelSource =
    [[MLKFirebaseModelSource alloc] initWithName:@"your_remote_model"];
MLKCustomRemoteModel *remoteModel =
    [[MLKCustomRemoteModel alloc] initWithRemoteModelSource:firebaseModelSource];
Lancez ensuite la tâche de téléchargement du modèle en spécifiant les conditions dans lesquelles vous souhaitez autoriser le téléchargement. Si le modèle n'est pas sur l'appareil ou si une version plus récente du modèle est disponible, la tâche télécharge le modèle de manière asynchrone depuis Firebase :
Swift
let downloadConditions = ModelDownloadConditions(
  allowsCellularAccess: true,
  allowsBackgroundDownloading: true
)
let downloadProgress = ModelManager.modelManager().download(
  remoteModel,
  conditions: downloadConditions
)
Objective-C
MLKModelDownloadConditions *downloadConditions =
    [[MLKModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
                                         allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
    [[MLKModelManager modelManager] downloadRemoteModel:remoteModel
                                             conditions:downloadConditions];
De nombreuses applications lancent la tâche de téléchargement dans leur code d'initialisation, mais vous pouvez le faire à tout moment avant d'avoir besoin d'utiliser le modèle.
Créer un outil de classification d'images à partir de votre modèle
Après avoir configuré vos sources de modèle, créez un objet ImageLabeler à partir de l'une d'elles.
Si vous ne disposez que d'un modèle groupé localement, créez simplement un outil de libellisation à partir de votre objet LocalModel et configurez le seuil de score de confiance que vous souhaitez exiger (voir Évaluer votre modèle) :
Swift
let options = CustomImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = NSNumber(value: 0.0)  // Evaluate your model in the Cloud console
                                                    // to determine an appropriate value.
let imageLabeler = ImageLabeler.imageLabeler(options)
Objective-C
CustomImageLabelerOptions *options =
    [[CustomImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = @(0.0f);  // Evaluate your model in the Cloud console
                                        // to determine an appropriate value.
MLKImageLabeler *imageLabeler =
    [MLKImageLabeler imageLabelerWithOptions:options];
Si vous disposez d'un modèle hébergé à distance, vous devrez vérifier qu'il a été téléchargé avant de l'exécuter. Vous pouvez vérifier l'état de la tâche de téléchargement du modèle à l'aide de la méthode isModelDownloaded(remoteModel:) du gestionnaire de modèles.
Bien que vous n'ayez qu'à confirmer cela avant d'exécuter le labeler, si vous disposez à la fois d'un modèle hébergé à distance et d'un modèle fourni localement, il peut être judicieux d'effectuer cette vérification lors de l'instanciation de ImageLabeler : créez un labeler à partir du modèle distant s'il a été téléchargé, et à partir du modèle local dans le cas contraire.
Swift
var options: CustomImageLabelerOptions
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
  options = CustomImageLabelerOptions(remoteModel: remoteModel)
} else {
  options = CustomImageLabelerOptions(localModel: localModel)
}
options.confidenceThreshold = NSNumber(value: 0.0)  // Evaluate your model in the Firebase console
                                                    // to determine an appropriate value.
let imageLabeler = ImageLabeler.imageLabeler(options: options)
Objective-C
MLKCustomImageLabelerOptions *options;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
  options = [[MLKCustomImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
  options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = @(0.0f);  // Evaluate your model in the Firebase console
                                        // to determine an appropriate value.
MLKImageLabeler *imageLabeler =
    [MLKImageLabeler imageLabelerWithOptions:options];
Si vous ne disposez que d'un modèle hébergé à distance, vous devez désactiver les fonctionnalités liées au modèle (par exemple, griser ou masquer une partie de votre UI) jusqu'à ce que vous confirmiez que le modèle a été téléchargé.
Vous pouvez obtenir l'état du téléchargement du modèle en associant des observateurs au centre de notifications par défaut. Veillez à utiliser une référence faible à self dans le bloc d'observateur, car les téléchargements peuvent prendre un certain temps et l'objet d'origine peut être libéré avant la fin du téléchargement. Exemple :
Swift
NotificationCenter.default.addObserver(
    forName: .mlkitMLModelDownloadDidSucceed,
    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: .mlkitMLModelDownloadDidFail,
    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:MLKModelDownloadDidSucceedNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;
              MLKRemoteModel *model = note.userInfo[MLKModelDownloadUserInfoKeyRemoteModel];
              if ([model.name isEqualToString:@"your_remote_model"]) {
                // The model was downloaded and is available on the device
              }
            }];
[NSNotificationCenter.defaultCenter
    addObserverForName:MLKModelDownloadDidFailNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;
              NSError *error = note.userInfo[MLKModelDownloadUserInfoKeyError];
            }];
2. Préparer l'image d'entrée
Créez un objet VisionImage à l'aide d'un UIImage ou d'un CMSampleBufferRef.
Si vous utilisez un UIImage, procédez comme suit :
- Créez un objet VisionImageavecUIImage. Veillez à spécifier le.orientationapproprié.Swiftlet image = VisionImage(image: uiImage) visionImage.orientation = image.imageOrientation Objective-CMLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation; 
Si vous utilisez un CMSampleBufferRef, procédez comme suit :
- 
    Spécifiez l'orientation des données d'image contenues dans le tampon CMSampleBufferRef.Pour obtenir l'orientation de l'image : Swiftfunc 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 position == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return position == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return position == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return position == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } } 
- Créez un objet VisionImageà l'aide de l'objetCMSampleBufferRefet de l'orientation :Swiftlet image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition) Objective-CMLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition]; 
3. Exécuter l'outil de classification d'images
Asynchrone :
Swift
imageLabeler.process(image) { labels, error in
    guard error == nil, let labels = labels, !labels.isEmpty else {
        // Handle the error.
        return
    }
    // Show results.
}
Objective-C
[imageLabeler
    processImage:image
      completion:^(NSArray<MLKImageLabel *> *_Nullable labels,
                   NSError *_Nullable error) {
        if (label.count == 0) {
            // Handle the error.
            return;
        }
        // Show results.
     }];
De manière synchrone :
Swift
var labels: [ImageLabel]
do {
    labels = try imageLabeler.results(in: image)
} catch let error {
    // Handle the error.
    return
}
// Show results.
Objective-C
NSError *error;
NSArray<MLKImageLabel *> *labels =
    [imageLabeler resultsInImage:image error:&error];
// Show results or handle the error.
4. Obtenir des informations sur les objets étiquetés
Si l'opération d'étiquetage d'image aboutit, elle renvoie un tableau ImageLabel. Chaque ImageLabel représente un élément identifié dans l'image. Vous pouvez obtenir la description textuelle de chaque libellé (si elle est disponible dans les métadonnées du fichier de modèle TensorFlow Lite), le score de confiance et l'index.
Exemple :
Swift
for label in labels {
  let labelText = label.text
  let confidence = label.confidence
  let index = label.index
}
Objective-C
for (MLKImageLabel *label in labels) {
  NSString *labelText = label.text;
  float confidence = label.confidence;
  NSInteger index = label.index;
}
Conseils pour améliorer les performances en temps réel
Si vous souhaitez étiqueter des images dans une application en temps réel, suivez ces consignes pour obtenir les meilleures fréquences d'images :
- Limitez les appels au détecteur. Si une nouvelle image vidéo devient disponible pendant l'exécution du détecteur, supprimez-la.
- Si vous utilisez la sortie du détecteur pour superposer des éléments graphiques sur l'image d'entrée, obtenez d'abord le résultat, puis affichez l'image et superposez-la en une seule étape. Vous effectuez ainsi le rendu sur la surface d'affichage une seule fois pour chaque frame d'entrée. Pour obtenir un exemple, consultez les classes previewOverlayView et FIRDetectionOverlayView dans l'application exemple de présentation.