Lorsque vous transmettez une image à ML Kit, celui-ci détecte jusqu'à cinq objets dans l'image ainsi que la position de chaque objet dans l'image. Lorsque vous détectez des objets dans flux vidéo, chaque objet possède un identifiant unique que vous pouvez utiliser pour suivre d'une image à l'autre.
Vous pouvez utiliser un modèle de classification d'images personnalisé pour classer les objets détecté. Consultez Modèles personnalisés avec ML Kit pour découvrir des conseils sur les exigences de compatibilité des modèles, où trouver des modèles pré-entraînés, et comment entraîner vos propres modèles.
Il existe deux façons d'intégrer un modèle personnalisé. Vous pouvez grouper le modèle en le plaçant dans le dossier de composants de votre application, ou vous pouvez le télécharger depuis Firebase. Le tableau suivant compare les deux options.
Modèle groupé | Modèle hébergé |
---|---|
Le modèle fait partie du fichier .ipa de votre application, qui
augmente sa taille. |
Le modèle ne fait pas partie du fichier .ipa de votre application. Il est
hébergé en important dans
Firebase Machine Learning. |
Le modèle est disponible immédiatement, même lorsque l'appareil Android est hors connexion | Le modèle est téléchargé à la demande |
Aucun projet Firebase n'est nécessaire | Nécessite un projet Firebase |
Vous devez publier à nouveau votre application pour mettre à jour le modèle | Déployer les mises à jour du modèle sans publier à nouveau votre application |
Pas de tests A/B intégrés | Tests A/B faciles avec Firebase Remote Config |
Essayer
- Consultez l'application de démarrage rapide Vision. pour découvrir un exemple d'utilisation du modèle groupé application de démarrage rapide automl pour exemple d'utilisation du modèle hébergé.
- Voir la présentation Material Design app pour une implémentation de bout en bout de cette API.
Avant de commencer
Incluez les bibliothèques ML Kit dans votre Podfile:
Pour regrouper un modèle avec votre application:
pod 'GoogleMLKit/ObjectDetectionCustom', '15.5.0'
Pour télécharger un modèle de manière dynamique depuis Firebase, ajoutez le
LinkFirebase
la dépendance:pod 'GoogleMLKit/ObjectDetectionCustom', '15.5.0' pod 'GoogleMLKit/LinkFirebase', '15.5.0'
Après avoir installé ou mis à jour les pods de votre projet, ouvrez votre projet Xcode à l'aide de son
.xcworkspace
. ML Kit est compatible avec Xcode version 13.2.1 ou supérieur.Si vous souhaitez télécharger un modèle, assurez-vous ajouter Firebase à votre projet iOS ; si vous ne l'avez pas déjà fait. Cela n'est pas nécessaire lorsque vous regroupez les du modèle.
1. Charger le modèle
Configurer la source d'un modèle local
Pour empaqueter le modèle avec votre application:
Copiez le fichier de modèle (se terminant généralement par
.tflite
ou.lite
) dans votre Xcode. projet, en prenant soin de sélectionnerCopy bundle resources
lorsque vous le faites. La sera inclus dans l'app bundle et disponible pour ML Kit.Créez l'objet
LocalModel
en spécifiant le chemin d'accès au fichier de modèle:Swift
let localModel = LocalModel(path: localModelFilePath)
Objective-C
MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath];
Configurer une source de modèle hébergé sur 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
let firebaseModelSource = FirebaseModelSource( name: "your_remote_model") // The name you assigned in // the Firebase console. let remoteModel = CustomRemoteModel(remoteModelSource: firebaseModelSource)
Objective-C
MLKFirebaseModelSource *firebaseModelSource = [[MLKFirebaseModelSource alloc] initWithName:@"your_remote_model"]; // The name you assigned in // the Firebase console. MLKCustomRemoteModel *remoteModel = [[MLKCustomRemoteModel alloc] initWithRemoteModelSource:firebaseModelSource];
Ensuite, démarrez la tâche de téléchargement du modèle, en spécifiant les conditions dans lesquelles que vous souhaitez autoriser le téléchargement. Si le modèle ne figure pas sur l'appareil, ou si un modèle plus récent du modèle est disponible, la tâche téléchargera 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] downloadModel:remoteModel conditions:downloadConditions];
De nombreuses applications lancent la tâche de téléchargement dans leur code d'initialisation, vous pouvez le faire à tout moment avant d'avoir besoin d'utiliser le modèle.
2. Configurer le détecteur d'objets
Une fois les sources de modèle configurées, configurez le détecteur d'objets pour votre
avec un objet CustomObjectDetectorOptions
. Vous pouvez modifier
les paramètres suivants:
Paramètres du détecteur d'objets | |
---|---|
Mode de détection |
STREAM_MODE (par défaut) | SINGLE_IMAGE_MODE
Dans Dans |
Détecter et suivre plusieurs objets |
false (par défaut) | true
Permet de détecter et de suivre jusqu'à cinq objets, ou seulement les plus objet proéminent (par défaut). |
Classer des objets |
false (par défaut) | true
Indique si les objets détectés doivent être classés ou non à l'aide de la classe
un modèle de classificateur personnalisé. Pour utiliser votre classification personnalisée :
vous devez le définir sur |
Seuil de confiance de la classification |
Score de confiance minimal des étiquettes détectées. Si ce champ n'est pas défini, spécifié par les métadonnées du modèle sera utilisé. Si le modèle ne contient pas de métadonnées spécifiez un seuil de classificateur, un seuil par défaut de 0.0 utilisé. |
Nombre maximal d'étiquettes par objet |
Nombre maximal d'étiquettes par objet que le détecteur retour. Si cette règle n'est pas configurée, la valeur par défaut de 10 est utilisée. |
Si vous ne disposez que d'un modèle groupé localement, il vous suffit de créer un détecteur d'objets à partir de
votre objet LocalModel
:
Swift
let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true options.classificationConfidenceThreshold = NSNumber(value: 0.5) options.maxPerObjectLabelCount = 3
Objective-C
MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; options.classificationConfidenceThreshold = @(0.5); options.maxPerObjectLabelCount = 3;
Si vous disposez d'un modèle hébergé à distance, vous devrez vérifier qu'il a été
téléchargée avant
de l’exécuter. Vous pouvez vérifier l'état du téléchargement du modèle
à l'aide de la méthode isModelDownloaded(remoteModel:)
du gestionnaire de modèles.
Il suffit de vérifier avant d'exécuter le détecteur d'objets,
vous disposez à la fois d'un modèle hébergé à distance et d'un modèle groupé localement, cela peut rendre
d'effectuer cette vérification lors de l'instanciation de ObjectDetector
: créez une
du modèle distant s'il a été téléchargé et à partir du modèle local
sinon.
Swift
var options: CustomObjectDetectorOptions! if (ModelManager.modelManager().isModelDownloaded(remoteModel)) { options = CustomObjectDetectorOptions(remoteModel: remoteModel) } else { options = CustomObjectDetectorOptions(localModel: localModel) } options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true options.classificationConfidenceThreshold = NSNumber(value: 0.5) options.maxPerObjectLabelCount = 3
Objective-C
MLKCustomObjectDetectorOptions *options; if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) { options = [[MLKCustomObjectDetectorOptions alloc] initWithRemoteModel:remoteModel]; } else { options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; } options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; options.classificationConfidenceThreshold = @(0.5); options.maxPerObjectLabelCount = 3;
Si vous ne disposez que d'un modèle hébergé à distance, vous devez désactiver les paramètres (par exemple, griser ou masquer une partie de l'interface utilisateur), vous confirmez 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 modèle
Centre de notifications. Veillez à utiliser une référence faible à self
dans l'observateur
, car les téléchargements peuvent prendre un certain temps et que l'objet d'origine peut être
libérées une fois le téléchargement terminé. Exemple :
Swift
NotificationCenter.default.addObserver( forName: .mlkitModelDownloadDidSucceed, 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: .mlkitModelDownloadDidFail, 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]; }];
L'API de détection et de suivi des objets est optimisée pour ces deux utilisations principales cas:
- Détection et suivi en direct de l'objet le plus proéminent de la caméra viseur.
- La détection de plusieurs objets à partir d'une image statique.
Pour configurer l'API pour ces cas d'utilisation:
Swift
// Live detection and tracking let options = CustomObjectDetectorOptions(localModel: localModel) options.shouldEnableClassification = true options.maxPerObjectLabelCount = 3 // Multiple object detection in static images let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableMultipleObjects = true options.shouldEnableClassification = true options.maxPerObjectLabelCount = 3
Objective-C
// Live detection and tracking MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.shouldEnableClassification = YES; options.maxPerObjectLabelCount = 3; // Multiple object detection in static images MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableMultipleObjects = YES; options.shouldEnableClassification = YES; options.maxPerObjectLabelCount = 3;
3. Préparer l'image d'entrée
Créez un objet VisionImage
à l'aide d'un UIImage
ou d'un
CMSampleBuffer
Si vous utilisez un UIImage
, procédez comme suit:
- Créez un objet
VisionImage
avecUIImage
. Veillez à spécifier le bon.orientation
.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Si vous utilisez un CMSampleBuffer
, procédez comme suit:
-
Spécifiez l'orientation des données d'image contenues dans le
CMSampleBuffer
Pour obtenir l'orientation de l'image:
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; } }
- Créez un objet
VisionImage
à l'aide de la méthode ObjetCMSampleBuffer
et orientation: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];
4. Créer et exécuter le détecteur d'objets
Créez un détecteur d'objets:
Swift
let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
Utilisez ensuite le détecteur:
De manière asynchrone:
Swift
objectDetector.process(image) { objects, error in guard error == nil, let objects = objects, !objects.isEmpty else { // Handle the error. return } // Show results. }
Objective-C
[objectDetector processImage:image completion:^(NSArray
*_Nullable objects, NSError *_Nullable error) { if (objects.count == 0) { // Handle the error. return; } // Show results. }]; De manière synchrone:
Swift
var objects: [Object] do { objects = try objectDetector.results(in: image) } catch let error { // Handle the error. return } // Show results.
Objective-C
NSError *error; NSArray
*objects = [objectDetector resultsInImage:image error:&error]; // Show results or handle the error.
5. Obtenir des informations sur les objets étiquetés
Si l'appel au processeur d'image aboutit, soit il transmet une liste de
Object
au gestionnaire d'achèvement ou renvoie la liste, en fonction de
que vous ayez appelé la méthode synchrone ou asynchrone.
Chaque Object
contient les propriétés suivantes:
frame |
Un CGRect indiquant la position de l'objet dans
l'image. |
||||||
trackingID |
Entier qui identifie l'objet dans toutes les images, ou "nil" dans SINGLE_IMAGE_MODE | ||||||
labels |
|
Swift
// objects contains one item if multiple object detection wasn't enabled. for object in objects { let frame = object.frame let trackingID = object.trackingID let description = object.labels.enumerated().map { (index, label) in "Label \(index): \(label.text), \(label.confidence), \(label.index)" }.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]; } }
Garantir une expérience utilisateur optimale
Pour une expérience utilisateur optimale, suivez ces consignes dans votre application:
- La réussite d'une détection d'objets dépend de sa complexité visuelle. Dans pour être détectés, les objets dotés d'un petit nombre de caractéristiques visuelles peuvent avoir besoin pour occuper une plus grande partie de l'image. Vous devez fournir aux utilisateurs des conseils sur en capturant une entrée qui fonctionne bien avec le type d'objets que vous souhaitez détecter.
- Quand vous utilisez la classification, si vous souhaitez détecter les objets qui ne tombent pas correctement dans les catégories prises en charge, implémenter un traitement spécial pour les d'objets.
Consultez également les [Application de présentation Material Design de ML Kit][showcase-link]{: .external } et Material Design Modèles pour la collection de caractéristiques basées sur le machine learning.
Amélioration des performances
Si vous souhaitez utiliser la détection d'objets dans une application en temps réel, suivez ces pour obtenir des fréquences d'images optimales:Lorsque vous utilisez le mode de traitement par flux dans une application en temps réel, n'utilisez pas plusieurs la détection d'objets, car la plupart des appareils ne sont pas en mesure de produire des fréquences d'images adéquates.
- Pour traiter les images vidéo, utilisez l'API synchrone
results(in:)
du détecteur. Appeler cette méthode à partir deAVCaptureVideoDataOutputSampleBufferDelegate
<ph type="x-smartling-placeholder"></ph>captureOutput(_, didOutput:from:)
pour obtenir les résultats d'une vidéo donnée de manière synchrone. cadre. Conserver <ph type="x-smartling-placeholder"></ph> deAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
en tant quetrue
afin de limiter les appels au détecteur. Si un nouveau l'image vidéo devient disponible pendant l'exécution du détecteur, elle est ignorée. - Si vous utilisez la sortie du détecteur pour superposer des graphiques sur l'image d'entrée, récupérez d'abord le résultat à partir de ML Kit, puis effectuez le rendu de l'image. et les superposer en une seule étape. Cela vous permet d'afficher sur la surface d'affichage une seule fois pour chaque trame d'entrée traitée. Affichez la vue updatePreviewOverlayViewWithLastFrame. dans l'exemple de démarrage rapide de ML Kit.