ML Kit fournit deux SDK optimisés pour la détection de poses.
| Nom du SDK | PoseDetection | PoseDetectionAccurate |
|---|---|---|
| Implémentation | Les éléments du détecteur de base sont liés de manière statique à votre application au moment de la compilation. | Les éléments du détecteur précis sont liés de manière statique à votre application au moment de la compilation. |
| Taille de l'application | Jusqu'à 29,6 Mo | Jusqu'à 33,2 Mo |
| Performances | iPhone X : environ 45 FPS | iPhone X : environ 29 FPS |
Essayer
- Essayez l'application exemple pour voir un exemple d'utilisation de cette API.
Avant de commencer
Incluez les pods ML Kit suivants dans votre Podfile :
# If you want to use the base implementation: pod 'GoogleMLKit/PoseDetection', '8.0.0' # If you want to use the accurate implementation: pod 'GoogleMLKit/PoseDetectionAccurate', '8.0.0'Une fois que vous avez 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 ultérieure.
1. Créer une instance de PoseDetector
Pour détecter une pose dans une image, créez d'abord une instance de PoseDetector et spécifiez éventuellement les paramètres du détecteur.
Options PoseDetector
Mode de détection
Le PoseDetector fonctionne dans deux modes de détection. Veillez à choisir celui qui correspond à votre cas d'utilisation.
stream(par défaut)- Le détecteur de pose détecte d'abord la personne la plus visible dans l'image, puis exécute la détection de pose. Dans les images suivantes, l'étape de détection de la personne n'est pas effectuée, sauf si la personne est masquée ou n'est plus détectée avec un niveau de confiance élevé. Le détecteur de pose tente de suivre la personne la plus visible et renvoie sa pose dans chaque inférence. Cela réduit la latence et facilite la détection. Utilisez ce mode lorsque vous souhaitez détecter une pose dans un flux vidéo.
singleImage- Le détecteur de pose détecte une personne, puis exécute la détection de pose. L'étape de détection de la personne est exécutée pour chaque image. La latence est donc plus élevée et il n'y a pas de suivi de la personne. Utilisez ce mode lorsque vous utilisez la détection de pose sur des images statiques ou lorsque le suivi n'est pas souhaité.
Spécifiez les options du détecteur de pose :
Swift
// Base pose detector with streaming, when depending on the PoseDetection SDK let options = PoseDetectorOptions() options.detectorMode = .stream // Accurate pose detector on static images, when depending on the // PoseDetectionAccurate SDK let options = AccuratePoseDetectorOptions() options.detectorMode = .singleImage
Objective-C
// Base pose detector with streaming, when depending on the PoseDetection SDK MLKPoseDetectorOptions *options = [[MLKPoseDetectorOptions alloc] init]; options.detectorMode = MLKPoseDetectorModeStream; // Accurate pose detector on static images, when depending on the // PoseDetectionAccurate SDK MLKAccuratePoseDetectorOptions *options = [[MLKAccuratePoseDetectorOptions alloc] init]; options.detectorMode = MLKPoseDetectorModeSingleImage;
Enfin, obtenez une instance de PoseDetector. Transmettez les options que vous avez spécifiées :
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Préparer l'image d'entrée
Pour détecter les poses, 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 CMSampleBuffers.
Créez un VisionImage objet à l'aide d'un UIImage ou d'un
CMSampleBuffer.
Si vous utilisez un UIImage, procédez comme suit :
- Créez un
VisionImageobjet avec leUIImage. Veillez à spécifier le.orientationcorrect.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 l'CMSampleBufferobjet et de l'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];
3. Traiter l'image
Transmettez le VisionImage à l'une des méthodes de traitement d'image du détecteur de pose. Vous pouvez utiliser la méthode asynchrone process(image:) ou la méthode synchrone results().
Pour détecter des objets de manière synchrone :
Swift
var results: [Pose] do { results = try poseDetector.results(in: image) } catch let error { print("Failed to detect pose with error: \(error.localizedDescription).") return } guard let detectedPoses = results, !detectedPoses.isEmpty else { print("Pose detector returned no results.") return } // Success. Get pose landmarks here.
Objective-C
NSError *error; NSArray*poses = [poseDetector resultsInImage:image error:&error]; if (error != nil) { // Error. return; } if (poses.count == 0) { // No pose detected. return; } // Success. Get pose landmarks here.
Pour détecter des objets de manière asynchrone :
Swift
poseDetector.process(image) { detectedPoses, error in guard error == nil else { // Error. return } guard !detectedPoses.isEmpty else { // No pose detected. return } // Success. Get pose landmarks here. }
Objective-C
[poseDetector processImage:image completion:^(NSArray* _Nullable poses, NSError * _Nullable error) { if (error != nil) { // Error. return; } if (poses.count == 0) { // No pose detected. return; } // Success. Get pose landmarks here. }];
4. Obtenir des informations sur la pose détectée
Si une personne est détectée dans l'image, l'API de détection de pose transmet un tableau d'objets Pose au gestionnaire de saisie semi-automatique ou renvoie le tableau, selon que vous avez appelé la méthode asynchrone ou synchrone.
Si la personne n'était pas complètement dans l'image, le modèle attribue les coordonnées des points de repère manquants en dehors du cadre et leur attribue de faibles valeurs InFrameConfidence.
Si aucune personne n'a été détectée, le tableau est vide.
Swift
for pose in detectedPoses { let leftAnkleLandmark = pose.landmark(ofType: .leftAnkle) if leftAnkleLandmark.inFrameLikelihood > 0.5 { let position = leftAnkleLandmark.position } }
Objective-C
for (MLKPose *pose in detectedPoses) { MLKPoseLandmark *leftAnkleLandmark = [pose landmarkOfType:MLKPoseLandmarkTypeLeftAnkle]; if (leftAnkleLandmark.inFrameLikelihood > 0.5) { MLKVision3DPoint *position = leftAnkleLandmark.position; } }
Conseils pour améliorer les performances
La qualité de vos résultats dépend de la qualité de l'image d'entrée :
- Pour que ML Kit détecte précisément la pose, la personne dans l'image doit être représentée par suffisamment de données de pixels. Pour des performances optimales, le sujet doit faire au moins 256 x 256 pixels.
- Si vous détectez une pose dans une application en temps réel, vous pouvez également tenir compte des dimensions globales des images d'entrée. Les images plus petites peuvent être traitées plus rapidement. Par conséquent, pour réduire la latence, capturez des images à des résolutions inférieures, mais gardez à l'esprit les exigences de résolution ci-dessus et assurez-vous que le sujet occupe la plus grande partie possible de l'image.
- Une mauvaise mise au point de l'image peut également avoir un impact sur la précision. Si vous n'obtenez pas de résultats acceptables, demandez à l'utilisateur de recapturer l'image.
Si vous souhaitez utiliser la détection de pose dans une application en temps réel, suivez ces consignes pour obtenir les meilleures fréquences d'images :
- Utilisez le SDK PoseDetection de base et le mode de détection
stream. - Envisagez de capturer des images à une résolution inférieure. Toutefois, gardez également à l'esprit les exigences de cette API en termes de dimensions d'image.
- Pour traiter les images vidéo, utilisez l'API synchrone
results(in:)du détecteur. Appelez cette méthode à partir de la fonction AVCaptureVideoDataOutputSampleBufferDelegate's captureOutput(_, didOutput:from:) pour obtenir de manière synchrone les résultats de l'image vidéo donnée. Conservez la valeur true pour AVCaptureVideoDataOutput's alwaysDiscardsLateVideoFrames afin de limiter les appels au détecteur. Si une nouvelle image vidéo devient disponible pendant l'exécution du détecteur, elle est supprimée. - 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 n'effectuez le rendu sur la surface d'affichage qu'une seule fois pour chaque image d'entrée traitée. Pour obtenir un exemple, consultez les previewOverlayView et MLKDetectionOverlayView dans l'application exemple de présentation.
Étapes suivantes
- Pour savoir comment utiliser les points de repère de pose pour classer les poses, consultez Conseils pour la classification des poses.
- Pour voir un exemple d'utilisation de cette API, consultez l'exemple de démarrage rapide de ML Kit sur GitHub.