Vous pouvez utiliser ML Kit pour détecter et suivre des objets dans les images d'une vidéo.
Lorsque vous transmettez des images ML Kit, ML Kit renvoie, pour chaque image, une liste de cinq objets détectés maximum et de leur position dans l'image. Lors de la détection dans les flux vidéo, chaque objet possède un identifiant que vous pouvez utiliser pour suivre entre les images. Vous pouvez également activer la classification grossière des objets, qui leur attribue des libellés avec des descriptions de catégories générales.
Avant de commencer
- Si vous n'avez pas encore ajouté Firebase à votre application, suivez les les étapes décrites dans le guide de démarrage.
- Incluez les bibliothèques ML Kit dans votre Podfile:
pod 'Firebase/MLVision', '6.25.0' pod 'Firebase/MLVisionObjectDetection', '6.25.0'
Après avoir installé ou mis à jour les pods de votre projet, ouvrez votre Xcode projet à l'aide de son.xcworkspace
. - Dans votre application, importez Firebase:
Swift
import Firebase
Objective-C
@import Firebase;
1. Configurer le détecteur d'objets
Pour commencer à détecter et à suivre des objets, créez d'abord une instance de VisionObjectDetector
, en spécifiant éventuellement les paramètres du détecteur que vous souhaitez modifier par rapport aux paramètres par défaut.
Configurez le détecteur d'objets pour votre cas d'utilisation avec un objet
VisionObjectDetectorOptions
. Vous pouvez modifier les paramètres suivants : paramètres:Paramètres du détecteur d'objets Mode de détection .stream
(par défaut) |.singleImage
En mode flux (par défaut), le détecteur d'objets s'exécute avec une latence très faible, mais il peut produire des résultats incomplets (tels que des cadres de délimitation ou des catégories non spécifiés) lors des premières invocations du détecteur. En mode flux, le détecteur attribue également des ID de suivi aux objets, que vous pouvez utiliser pour suivre les objets dans les images. Utilisez ce mode lorsque vous souhaitez suivre des objets ou lorsque la faible latence est importante, par exemple lors du traitement de flux vidéo en temps réel.
En mode "Image unique", le détecteur d'objets attend qu'une cadre de délimitation de l'objet et catégorie (si vous avez activé la classification) sont disponibles avant de renvoyer un résultat. Par conséquent, la latence de détection est potentiellement plus élevée. De plus, dans une seule image, , aucun ID de suivi n'est attribué. Utilisez ce mode si la latence n'est pas critique, et vous ne voulez pas traiter résultats.
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 dans des catégories générales. Lorsqu'il est activé, le détecteur d'objets classe les objets dans les catégories suivantes: articles de mode, alimentation, articles pour la maison, de lieux, de plantes et d’inconnus.
L'API de détection et de suivi d'objets est optimisée pour ces deux cas d'utilisation principaux :
- Détection et suivi en direct de l'objet le plus proéminent de la caméra viseur
- Détection de plusieurs objets dans une image statique
Pour configurer l'API pour ces cas d'utilisation:
Swift
// Live detection and tracking let options = VisionObjectDetectorOptions() options.detectorMode = .stream options.shouldEnableMultipleObjects = false options.shouldEnableClassification = true // Optional // Multiple object detection in static images let options = VisionObjectDetectorOptions() options.detectorMode = .singleImage options.shouldEnableMultipleObjects = true options.shouldEnableClassification = true // Optional
Objective-C
// Live detection and tracking FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init]; options.detectorMode = FIRVisionObjectDetectorModeStream; options.shouldEnableMultipleObjects = NO; options.shouldEnableClassification = YES; // Optional // Multiple object detection in static images FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init]; options.detectorMode = FIRVisionObjectDetectorModeSingleImage; options.shouldEnableMultipleObjects = YES; options.shouldEnableClassification = YES; // Optional
Obtenez une instance de
FirebaseVisionObjectDetector
:Swift
let objectDetector = Vision.vision().objectDetector() // Or, to change the default settings: let objectDetector = Vision.vision().objectDetector(options: options)
Objective-C
FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetector]; // Or, to change the default settings: FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetectorWithOptions:options];
2. Exécuter le détecteur d'objets
Pour détecter et suivre des objets, procédez comme suit pour chaque image ou image de la vidéo.
Si vous avez activé le mode de traitement par flux, vous devez créer des objets VisionImage
à partir de
CMSampleBufferRef
.
Créez un objet
VisionImage
à l'aide d'unUIImage
ou d'unCMSampleBufferRef
.Pour utiliser un
UIImage
:- Si nécessaire, faites pivoter l'image de sorte que son
imageOrientation
est.up
. - Créez un objet
VisionImage
à l'aide de l'UIImage
correctement orienté. Ne spécifiez aucune métadonnée de rotation (valeur par défaut : (.topLeft
).Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Pour utiliser un
CMSampleBufferRef
:-
Créez un objet
VisionImageMetadata
qui spécifie l'orientation des données d'image contenues dans le tamponCMSampleBufferRef
.Pour obtenir l'orientation de l'image:
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; } }
Créez ensuite l'objet de métadonnées :
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];
- Créez un objet
VisionImage
à l'aide de la méthodeCMSampleBufferRef
et les métadonnées de rotation:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Si nécessaire, faites pivoter l'image de sorte que son
Transmettez l'
VisionImage
à l'une des méthodes de traitement d'images du détecteur d'objets. Vous pouvez utiliser la méthodeprocess(image:)
asynchrone ou la méthoderesults()
synchrone.Pour détecter des objets de manière asynchrone :
Swift
objectDetector.process(image) { detectedObjects, error in guard error == nil else { // Error. return } guard let detectedObjects = detectedObjects, !detectedObjects.isEmpty else { // No objects detected. return } // Success. Get object info here. // ... }
Objective-C
[objectDetector processImage:image completion:^(NSArray<FIRVisionObject *> * _Nullable objects, NSError * _Nullable error) { if (error == nil) { return; } if (objects == nil | objects.count == 0) { // No objects detected. return; } // Success. Get object info here. // ... }];
Pour détecter des objets de manière synchrone, procédez comme suit:
Swift
var results: [VisionObject]? = nil do { results = try objectDetector.results(in: image) } catch let error { print("Failed to detect object with error: \(error.localizedDescription).") return } guard let detectedObjects = results, !detectedObjects.isEmpty else { print("Object detector returned no results.") return } // ...
Objective-C
NSError *error; NSArray<FIRVisionObject *> *objects = [objectDetector resultsInImage:image error:&error]; if (error == nil) { return; } if (objects == nil | objects.count == 0) { // No objects detected. return; } // Success. Get object info here. // ...
Si l'appel au processeur d'image aboutit, soit il transmet une liste de
VisionObject
au gestionnaire d'achèvement ou renvoie la liste, en fonction de que vous ayez appelé la méthode synchrone ou asynchrone.Chaque
VisionObject
contient les propriétés suivantes:frame
CGRect
indiquant la position de l'objet dans l'image.trackingID
Entier permettant d'identifier l'objet dans les images. Nil dans un seul le mode Image. classificationCategory
Catégorie approximative de l'objet. Si le détecteur d'objets pour lequel la classification est activée, il s'agit toujours de .unknown
.confidence
Niveau de confiance de la classification des objets. Si l'objet n'a pas de classification activée ou si l'objet est classée comme inconnue, la requête suivante est nil
.Swift
// detectedObjects contains one item if multiple object detection wasn't enabled. for obj in detectedObjects { let bounds = obj.frame let id = obj.trackingID // If classification was enabled: let category = obj.classificationCategory let confidence = obj.confidence }
Objective-C
// The list of detected objects contains one item if multiple // object detection wasn't enabled. for (FIRVisionObject *obj in objects) { CGRect bounds = obj.frame; if (obj.trackingID) { NSInteger id = obj.trackingID.integerValue; } // If classification was enabled: FIRVisionObjectCategory category = obj.classificationCategory; float confidence = obj.confidence.floatValue; }
Amélioration de la convivialité et des performances
Pour une expérience utilisateur optimale, suivez ces consignes dans votre application:
- La réussite de la détection d'objets dépend de la complexité visuelle de l'objet. Les objets comportant un petit nombre de caractéristiques visuelles peuvent avoir besoin de s'étendre sur une plus grande partie de l'image pour être détectés. Vous devez fournir aux utilisateurs des conseils sur la capture d'entrées qui fonctionnent bien avec le type d'objets que vous souhaitez détecter.
- Lorsque vous utilisez la classification, si vous souhaitez détecter des objets qui ne rentrent pas clairement dans les catégories compatibles, implémentez une gestion spéciale pour les objets inconnus.
Consultez également l'[application de démonstration Material Design de ML Kit][showcase-link]{: .external } et la collection Material Design Modèles pour les fonctionnalités optimisées par le machine learning.
Lorsque vous utilisez le mode streaming dans une application en temps réel, suivez ces consignes pour obtenir les meilleurs fréquences d'images :
N'utilisez pas la détection de plusieurs objets en mode streaming, car la plupart des appareils ne pourront pas produire des fréquences d'images adéquates.
Désactivez la classification si vous n'en avez pas besoin.
- Limitez les appels au détecteur. Si un nouveau frame vidéo devient disponible pendant l'exécution du détecteur, supprimez-le.
- Si vous utilisez la sortie du détecteur pour superposer des éléments graphiques à l'image d'entrée, obtenez d'abord le résultat de ML Kit, puis affichez l'image et superposez-la en une seule étape. Cela vous permet d'afficher sur la surface d'affichage une seule fois pour chaque trame d'entrée. Consultez la vue previewOverlayView. et FIRDetectionOverlayView dans l'application exemple Showcase.