ML Kit fornisce due SDK ottimizzati per il rilevamento della postura.
Nome SDK | PoseDetection | PoseDetectionAccurate |
---|---|---|
Implementazione | Gli asset per il rilevatore di base sono collegati staticamente alla tua app al momento della creazione. | Gli asset per il rilevatore accurato sono collegati staticamente alla tua app al momento della compilazione. |
Dimensioni app | Fino a 29,6 MB | Fino a 33,2 MB |
Rendimento | iPhone X: ~45FPS | iPhone X: ~29FPS |
Prova
- Prova l'app di esempio per vedere un esempio di utilizzo di questa API.
Prima di iniziare
Includi i seguenti pod 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
specifica facoltativamente le impostazioni del rilevatore.
PoseDetector
opzioni
Modalità di rilevamento
Il PoseDetector
funziona 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 frame successivi, il passaggio di rilevamento delle persone non verrà eseguito a meno che la persona non venga oscurata o non venga più rilevata con un alto livello di confidenza. Il rilevatore di pose tenterà di tracciare la persona più in evidenza e restituirà la sua posa in ogni inferenza. In questo modo si riduce la latenza e si semplifica il rilevamento. Utilizza questa modalità quando vuoi rilevare la postura in un flusso video.
singleImage
- Il rilevatore di postura rileva una persona e poi esegue il rilevamento della postura. Il passaggio di rilevamento delle persone verrà eseguito per ogni immagine, quindi la latenza sarà maggiore e non è previsto il tracciamento delle persone. Utilizza questa modalità quando utilizzi il rilevamento della postura su immagini statiche o quando non è necessario il monitoraggio.
Specifica le opzioni del rilevatore di postura:
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
. Trasmetti le opzioni che hai specificato:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Prepara l'immagine di input
Per rilevare le pose, esegui le seguenti operazioni per ogni immagine o frame del video.
Se hai attivato la modalità flusso, 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.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 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'oggettoCMSampleBuffer
e l'orientamento: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. Ottenere informazioni sulla postura rilevata
Se viene rilevata una persona nell'immagine, l'API Pose Detection passa un array di oggetti Pose
al gestore di 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 al di fuori dell'inquadratura e assegna loro valori InFrameConfidence bassi.
Se non è stata 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 la posa in modo accurato, la persona nell'immagine deve essere rappresentata da dati pixel sufficienti; per un rendimento ottimale, il soggetto deve essere di almeno 256 x 256 pixel.
- Se rilevi la posa in un'applicazione in tempo reale, potresti anche prendere in considerazione le dimensioni complessive delle immagini di input. Le immagini più piccole possono essere elaborate più velocemente, quindi per ridurre la latenza, acquisisci immagini a risoluzioni inferiori, ma tieni presenti i requisiti di risoluzione sopra indicati e assicurati che il soggetto occupi la maggior parte dell'immagine possibile.
- Anche una messa a fuoco scadente dell'immagine può influire sull'accuratezza. Se non ottieni risultati accettabili, chiedi all'utente di acquisire nuovamente l'immagine.
Se vuoi utilizzare il rilevamento della postura in un'applicazione in tempo reale, segui queste linee guida per ottenere i migliori frame rate:
- Utilizza l'SDK PoseDetection di base e la modalità di rilevamento
stream
. - Valuta la possibilità di acquisire immagini a una risoluzione inferiore. Tuttavia, tieni presente anche i requisiti di dimensione delle immagini di questa API.
- Per l'elaborazione dei frame video, utilizza l'
results(in:)
API sincrona del rilevatore. Chiama questo metodo dalla funzione captureOutput(_, didOutput:from:) di AVCaptureVideoDataOutputSampleBufferDelegate per ottenere in modo sincrono i risultati dal frame video specificato. Mantieni AVCaptureVideoDataOutput's alwaysDiscardsLateVideoFrames su true per limitare le chiamate al rilevatore. Se un nuovo frame video diventa disponibile durante l'esecuzione del rilevatore, verrà eliminato. - Se utilizzi l'output del rilevatore per sovrapporre elementi grafici all'immagine di input, prima ottieni il risultato da ML Kit, poi esegui il rendering dell'immagine e della sovrapposizione in un unico passaggio. In questo modo, il rendering sulla superficie di visualizzazione viene eseguito 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 punti di riferimento della postura per classificare le pose, consulta Suggerimenti per la classificazione delle pose.
- Per un esempio di utilizzo di questa API, consulta l'esempio di guida rapida di ML Kit su GitHub.