Vous pouvez utiliser ML Kit pour détecter et suivre des objets sur des images 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 leur position dans l'image. Lors de la détection d'objets dans des flux vidéo, chaque objet possède un identifiant que vous pouvez utiliser pour suivre l'objet à travers les images. Vous pouvez également éventuellement activer la classification grossière des objets, qui étiquette les objets avec des descriptions de catégories larges.
Avant que tu commences
- Si vous n'avez pas encore ajouté Firebase à votre application, faites-le en suivant les étapes du 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, assurez-vous d'ouvrir votre projet Xcode à l'aide de son.xcworkspace
. - Dans votre application, importez Firebase :
Rapide
import Firebase
Objectif c
@import Firebase;
1. Configurez le détecteur d'objet
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 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 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 peut produire des résultats incomplets (tels que des cadres de délimitation ou une catégorie non spécifiés) lors des premiers appels du détecteur. De plus, en mode flux, le détecteur attribue des identifiants de suivi aux objets, que vous pouvez utiliser pour suivre des objets à travers les images. Utilisez ce mode lorsque vous souhaitez suivre des objets ou lorsqu'une 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'objet attend que le cadre de sélection d'un objet détecté et (si vous avez activé la classification) la catégorie soient disponibles avant de renvoyer un résultat. En conséquence, la latence de détection est potentiellement plus élevée. De plus, en mode image unique, les identifiants de suivi ne sont pas attribués. Utilisez ce mode si la latence n'est pas critique et que vous ne souhaitez pas gérer des résultats partiels.
Détecter et suivre plusieurs objets false
(par défaut) |true
Qu'il s'agisse de détecter et de suivre jusqu'à cinq objets ou uniquement l'objet le plus visible (par défaut).
Classer les objets false
(par défaut) |true
S'il faut ou non classer les objets détectés en catégories grossières. Lorsqu'il est activé, le détecteur d'objets classe les objets dans les catégories suivantes : articles de mode, nourriture, articles pour la maison, lieux, plantes et 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 visible dans le viseur de l'appareil photo
- Détection de plusieurs objets dans une image statique
Pour configurer l'API pour ces cas d'utilisation :
Rapide
// 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
Objectif 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
:Rapide
let objectDetector = Vision.vision().objectDetector() // Or, to change the default settings: let objectDetector = Vision.vision().objectDetector(options: options)
Objectif c
FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetector]; // Or, to change the default settings: FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetectorWithOptions:options];
2. Exécutez le détecteur d'objet
Pour détecter et suivre des objets, procédez comme suit pour chaque image ou image vidéo. Si vous avez activé le mode flux, vous devez créer des objets VisionImage
à partir de CMSampleBufferRef
s.
Créez un objet
VisionImage
à l'aide d'unUIImage
ou d'unCMSampleBufferRef
.Pour utiliser une
UIImage
:- Si nécessaire, faites pivoter l'image pour que sa propriété
imageOrientation
soit.up
. - Créez un objet
VisionImage
à l'aide duUIImage
correctement pivoté. Ne spécifiez aucune métadonnée de rotation : la valeur par défaut,.topLeft
, doit être utilisée.Rapide
let image = VisionImage(image: uiImage)
Objectif 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 :
Rapide
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 } }
Objectif 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; } }
Ensuite, créez l'objet de métadonnées :
Rapide
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objectif 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 l'objetCMSampleBufferRef
et des métadonnées de rotation :Rapide
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objectif c
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Si nécessaire, faites pivoter l'image pour que sa propriété
Transmettez
VisionImage
à l’une des méthodes de traitement d’image du détecteur d’objets. Vous pouvez utiliser la méthode asynchroneprocess(image:)
ou la méthode synchroneresults()
.Pour détecter des objets de manière asynchrone :
Rapide
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. // ... }
Objectif 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 :
Rapide
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 } // ...
Objectif 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 réussit, il transmet une liste de
VisionObject
au gestionnaire d'achèvement ou renvoie la liste, selon que vous avez appelé la méthode asynchrone ou synchrone.Chaque
VisionObject
contient les propriétés suivantes :frame
Un CGRect
indiquant la position de l'objet dans l'image.trackingID
Entier qui identifie l’objet sur les images. Néant en mode image unique. classificationCategory
La catégorie grossière de l'objet. Si la classification n'est pas activée pour le détecteur d'objets, il s'agit toujours .unknown
.confidence
La valeur de confiance de la classification des objets. Si la classification n'est pas activée pour le détecteur d'objets ou si l'objet est classé comme inconnu, la valeur est nil
.Rapide
// 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 }
Objectif 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éliorer la convivialité et les performances
Pour une expérience utilisateur optimale, suivez ces directives dans votre application :
- La réussite de la détection d'objet dépend de la complexité visuelle de l'objet. Les objets présentant un petit nombre de caractéristiques visuelles peuvent devoir occuper 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 n'entrent pas clairement dans les catégories prises en charge, implémentez une gestion spéciale pour les objets inconnus.
Consultez également l'[application vitrine ML Kit Material Design][showcase-link]{: .external } et la collection de modèles de conception matérielle pour la collection de fonctionnalités basées sur l'apprentissage automatique .
Lorsque vous utilisez le mode streaming dans une application en temps réel, suivez ces directives pour obtenir les meilleures fréquences d'images :
N'utilisez pas la détection d'objets multiples en mode streaming, car la plupart des appareils ne seront pas en mesure de produire des fréquences d'images adéquates.
Désactivez la classification si vous n’en avez pas besoin.
- Accélérez les appels au détecteur. Si une nouvelle image vidéo devient disponible pendant le fonctionnement du détecteur, supprimez l'image.
- Si vous utilisez la sortie du détecteur pour superposer des graphiques sur l'image d'entrée, obtenez d'abord le résultat de ML Kit, puis effectuez le rendu de l'image et la superposition en une seule étape. Ce faisant, vous effectuez un rendu sur la surface d'affichage une seule fois pour chaque image d'entrée. Consultez les classes previewOverlayView et FIRDetectionOverlayView dans l’exemple d’application de présentation pour un exemple.