ML Kit fornisce due SDK ottimizzati per il rilevamento della posa.
Nome SDK | PoseDetection | PoseDetectionAccurate |
---|---|---|
Implementazione | Gli asset per il rilevatore di base sono collegati in modo statico alla tua app in fase di compilazione. | Gli asset per il rilevamento accurato sono collegati in modo statico alla tua app in fase di compilazione. |
Dimensioni app | Fino a 29,6 MB | Fino a 33,2 MB |
Prestazioni | iPhone X: circa 45 FPS | iPhone X: circa 29 FPS |
Prova
- Prova l'app di esempio per vedere un esempio di utilizzo di questa API.
Prima di iniziare
Includi i seguenti pod di ML Kit nel tuo 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'
Dopo aver installato o aggiornato i pod del progetto, apri il progetto Xcode utilizzando il relativo
xcworkspace
. ML Kit è supportato in Xcode versione 13.2.1 o successive.
1. Crea un'istanza di PoseDetector
Per rilevare una posa in un'immagine, crea prima un'istanza di PoseDetector
e, facoltativamente, specifica le impostazioni del rilevatore.
PoseDetector
opzioni
Modalità di rilevamento
PoseDetector
opera in due modalità di rilevamento. Assicurati di scegliere quello che corrisponde al tuo caso d'uso.
stream
(valore predefinito)- Il rilevatore di pose rileva prima la persona più prominente nell'immagine e poi esegue il rilevamento della posa. Nei fotogrammi successivi, la fase di rilevamento delle persone non verrà eseguita a meno che la persona non venga obscured o non venga più rilevata con un'elevata confidenza. Il rilevatore di pose tenterà di monitorare la persona più in evidenza e restituirà la sua posa in ogni deduzione. In questo modo si riduce la latenza e si semplifica il rilevamento. Utilizza questa modalità quando vuoi rilevare la posa in uno stream video.
singleImage
- Il rilevatore di pose rileva una persona ed esegue il rilevamento della posa. Il passaggio di rilevamento delle persone verrà eseguito per ogni immagine, pertanto la latenza sarà più elevata e non è previsto il monitoraggio delle persone. Utilizza questa modalità quando utilizzi il rilevamento delle pose su immagini statiche o quando non è necessario il monitoraggio.
Specifica le opzioni del rilevatore di 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;
Infine, ottieni un'istanza di PoseDetector
. Passa le opzioni specificate:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Prepara l'immagine di input
Per rilevare le pose, svolgi i seguenti passaggi per ogni immagine o fotogramma del video.
Se hai attivato la modalità di streaming, devi creare oggetti VisionImage
da
CMSampleBuffer
.
Crea un oggetto VisionImage
utilizzando un UIImage
o un
CMSampleBuffer
.
Se utilizzi un UIImage
, segui questi passaggi:
- Crea un oggetto
VisionImage
conUIImage
. Assicurati di specificare il valore.orientation
corretto.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Se utilizzi un CMSampleBuffer
, segui questi passaggi:
-
Specifica l'orientamento dei dati dell'immagine contenuti in
CMSampleBuffer
.Per ottenere l'orientamento dell'immagine:
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; } }
- Crea un oggetto
VisionImage
utilizzando l'orientamento e l'oggettoCMSampleBuffer
: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. Elabora l'immagine
Passa VisionImage
a uno dei metodi di elaborazione delle immagini del rilevatore di pose. Puoi utilizzare il metodo asincrono process(image:)
o il metodo sincrono results()
.
Per rilevare gli oggetti in modo sincrono:
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.
Per rilevare gli oggetti in modo asincrono:
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. Visualizzare le informazioni sulla posa rilevata
Se nell'immagine viene rilevata una persona, l'API di rilevamento delle pose passa un array di oggetti Pose
al gestore del completamento o restituisce l'array, a seconda che tu abbia chiamato il metodo asincrono o sincrono.
Se la persona non era completamente all'interno dell'immagine, il modello assegna le coordinate dei punti di riferimento mancanti all'esterno dell'inquadratura e li assegna a valori bassi di InFrameConfidence.
Se non viene rilevata alcuna persona, l'array è vuoto.
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; } }
Suggerimenti per migliorare il rendimento
La qualità dei risultati dipende dalla qualità dell'immagine di input:
- Affinché ML Kit rilevi con precisione la posa, la persona nell'immagine deve essere rappresentata da dati pixel sufficienti. Per il massimo rendimento, l'oggetto deve essere di almeno 256 x 256 pixel.
- Se rilevi la posa in un'applicazione in tempo reale, ti consigliamo di prendere in considerazione anche le dimensioni complessive delle immagini di input. Le immagini più piccole possono essere elaborate più velocemente, quindi per ridurre la latenza, acquisisci le immagini a risoluzioni inferiori, ma tieni presente i requisiti di risoluzione sopra indicati e assicurati che l'oggetto occupi il più possibile l'immagine.
- Anche la scarsa messa a fuoco delle immagini può influire sull'accuratezza. Se non ottieni risultati accettabili, invita l'utente a acquisire di nuovo l'immagine.
Se vuoi utilizzare il rilevamento delle pose in un'applicazione in tempo reale, segui queste linee guida per ottenere le frequenze frame migliori:
- Utilizza l'SDK di base PoseDetection e la modalità di rilevamento
stream
. - Valuta la possibilità di acquisire le immagini a una risoluzione inferiore. Tuttavia, tieni presente anche i requisiti relativi alle dimensioni delle immagini di questa API.
- Per l'elaborazione dei frame video, utilizza l'API sincrona
results(in:)
del rilevatore. Chiama questo metodo dalla funzione captureOutput(_, didOutput:from:) di AVCaptureVideoDataOutputSampleBufferDelegate per ottenere in modo sincrono i risultati dal frame video specificato. Mantieni alwaysDiscardsLateVideoFrames di AVCaptureVideoDataOutput impostato su true per limitare le chiamate al rilevatore. Se un nuovo frame video diventa disponibile mentre il rilevatore è in esecuzione, verrà eliminato. - Se utilizzi l'output del rilevatore per sovrapporre la grafica all'immagine di input, ottieni prima il risultato da ML Kit, quindi esegui il rendering dell'immagine e del overlay in un unico passaggio. In questo modo, esegui il rendering sulla superficie di visualizzazione una sola volta per ogni frame di input elaborato. Per un esempio, consulta le classi previewOverlayView e MLKDetectionOverlayView nell'app di esempio della vetrina.
Passaggi successivi
- Per scoprire come utilizzare i landmark delle pose per classificarle, consulta Suggerimenti per la classificazione delle pose.
- Consulta l'esempio di guida rapida di ML Kit su GitHub per un esempio di questa API in uso.