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 al momento della creazione. | Gli asset per un rilevatore accurato sono collegati in modo statico alla tua app al momento della creazione. |
Dimensioni app | Fino a 29,6 MB | Fino a 33,2 MB |
Esibizione | iPhone X: ~45 f/s | iPhone X: ~29 f/s |
Prova
- Prova l'app di esempio per vedere un utilizzo di esempio 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', '3.2.0' # If you want to use the accurate implementation: pod 'GoogleMLKit/PoseDetectionAccurate', '3.2.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
funziona in due modalità di rilevamento. Assicurati di scegliere quello che corrisponde
al tuo caso d'uso.
stream
(valore predefinito)- Il rilevatore di posizioni rileva prima la persona più in evidenza nell'immagine, poi esegue il rilevamento. Nei frame successivi, la fase di rilevamento di persone non verrà eseguita, a meno che la persona non sia oscurata o non sia più rilevata con un'affidabilità elevata. Il rilevatore della posa tenterà di tracciare la persona più in evidenza e tornerà alla posa in ogni inferenza. Questo riduce la latenza e semplifica il rilevamento. Utilizza questa modalità per rilevare la posa in uno stream video.
singleImage
- Il rilevatore di posa rileva una persona ed esegue il rilevamento. Il passaggio di rilevamento persone verrà eseguito per ogni immagine, quindi la latenza sarà maggiore e il monitoraggio persone non sarà disponibile. Usa questa modalità se usi il rilevamento della posa su immagini statiche o per cui il tracciamento non è desiderato.
Specifica le opzioni del rilevatore di posa:
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, recupera 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, procedi nel seguente modo per ogni immagine o fotogramma di video:
Se hai abilitato la modalità flusso, devi creare VisionImage
oggetti da CMSampleBuffer
.
Crea un oggetto VisionImage
utilizzando un UIImage
o un
CMSampleBuffer
.
Se usi 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 usi 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'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 dell'immagine del rilevatore di posizioni. Puoi utilizzare il metodo process(image:)
asincrono 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. Ricevere informazioni sulla posa rilevata
Se viene rilevata una persona nell'immagine, l'API di rilevamento delle posizioni 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 si trovava completamente nell'immagine, il modello assegna le coordinate dei punti di riferimento mancanti al di fuori del frame e restituisce valori InFrameConfidence bassi.
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 possa rilevare accuratamente la posa, la persona nell'immagine deve essere rappresentata da sufficienti dati di pixel; per ottenere le migliori prestazioni, il soggetto deve essere di almeno 256 x 256 pixel.
- Se rilevi la posa in un'applicazione in tempo reale, puoi considerare anche le dimensioni complessive delle immagini di input. Le immagini più piccole possono essere elaborate più rapidamente, quindi per ridurre la latenza, acquisisci immagini a risoluzioni più basse, ma tieni a mente i requisiti di risoluzione sopra indicati e assicurati che il soggetto occupi la maggior parte dell'immagine possibile.
- Anche una scarsa messa a fuoco delle immagini può influire sulla precisione. Se non ottieni risultati accettabili, chiedi all'utente di recuperare l'immagine.
Se vuoi utilizzare il rilevamento della posa in un'applicazione in tempo reale, segui queste linee guida per ottenere le migliori frequenze fotogrammi:
- Utilizza l'SDK PoseDetection di base e la modalità di rilevamento
stream
. - Valuta la possibilità di acquisire immagini a una risoluzione più bassa. Tuttavia, tieni presente anche i requisiti di dimensione delle immagini di questa API.
- Per elaborare i frame video, utilizza l'API sincrona
results(in:)
del rilevatore. Richiama questo metodo dalla funzione captureOutput(_, didOutput:from:) di AVCaptureVideoDataOutputSampleBufferDelegate per ottenere in modo sincrono i risultati dal frame video specificato. Mantieni il valore alwaysDiscardsLateVideoFrames di AVCaptureVideoDataOutput per limitare le chiamate al rilevatore. Se un nuovo fotogramma video diventa disponibile mentre il rilevatore è in esecuzione, questo verrà eliminato. - Se utilizzi l'output del rilevatore per sovrapporre i grafici all'immagine di input, ottieni il risultato da ML Kit, quindi esegui il rendering dell'immagine e dell'overlay in un unico passaggio. In questo modo, esegui il rendering sulla superficie del display solo una volta per ogni frame di input elaborato. Per un esempio, consulta le classi previewOverlayView e MLKDetectionOverlayView nell'app di esempio Showcase.
Passaggi successivi
- Per scoprire come utilizzare i punti di riferimento per le pose, consulta i suggerimenti per la classificazione delle pose.
- Consulta l'esempio della guida rapida di ML Kit su GitHub per un esempio di questa API in uso.