ML Kit fornisce due SDK ottimizzati per il rilevamento delle posizioni.
Nome SDK | PoseDetection | PoseDetectionAccurate |
---|---|---|
Implementazione | Gli asset per il rilevatore di base vengono collegati in modo statico alla tua app al momento della creazione. | Gli asset per un rilevatore preciso vengono collegati in modo statico alla tua app al momento della creazione. |
Dimensioni app | Fino a 29,6 MB | Fino a 33,2 MB |
Prestazioni | iPhone X: ~45 f/s | iPhone X: ~29 f/s |
Prova
- Prova l'app di esempio per per vedere un esempio di utilizzo di questa API.
Prima di iniziare
Includi i seguenti pod ML Kit nel 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
xcworkspace
. ML Kit è supportato in Xcode versione 13.2.1 o successiva.
1. Crea un'istanza di PoseDetector
Per rilevare una posa in un'immagine, crea prima un'istanza di PoseDetector
e
o specificare le impostazioni del rilevatore.
PoseDetector
opzioni
Modalità di rilevamento
Il PoseDetector
funziona in due modalità di rilevamento. Assicurati di scegliere quello che corrisponde
il tuo caso d'uso.
stream
(valore predefinito)- Il rilevatore della posa rileva prima la maggior parte di una persona in evidenza nell'immagine ed esegui il rilevamento della posa. Nei frame successivi, la fase di rilevamento della persona non verrà condotta a meno che la persona sono oscurati o non vengono più rilevati con un grado di confidenza elevato. Il rilevatore della posa cercano di tenere traccia della persona più in evidenza e di riprenderne la posa in l'inferenza. In questo modo si riduce la latenza e il rilevamento è più fluido. Usa questa modalità quando quando vuoi rilevare la posa in un video stream.
singleImage
- Il rilevatore della posa rileva una persona e poi esegue la posa il rilevamento automatico. La fase di rilevamento della persona viene eseguita per ogni immagine, quindi la latenza sarà più alta e non c'è il tracciamento delle persone. Usa questa modalità quando usi la posa il rilevamento su immagini statiche o dove il tracciamento non è desiderato.
Specifica le opzioni del rilevatore della 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, 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 posizioni, procedi nel seguente modo per ogni immagine o fotogramma del video.
Se hai abilitato la modalità flusso di dati, 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 nei
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 il metodoCMSampleBuffer
oggetto e 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 il VisionImage
a uno dei metodi di elaborazione delle immagini del rilevatore della posa. 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 era completamente all'interno dell'immagine, il modello assegna le coordinate dei punti di riferimento mancanti al di fuori dell'inquadratura e li mostra Valori 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é il kit ML rilevi con precisione la posa, la persona visibile nell'immagine deve essere rappresentati da una quantità sufficiente di dati di pixel; per ottenere le migliori prestazioni, l'oggetto essere di almeno 256 x 256 pixel.
- Se rilevi la posa in un'applicazione in tempo reale, valuta anche le dimensioni complessive delle immagini di input. Le immagini più piccole possono essere elaborate più velocemente. Per ridurre la latenza, acquisire immagini a risoluzioni più basse senza rinunciare tieni conto dei requisiti di risoluzione di cui sopra e assicurati che l'argomento rispetti i la maggior parte dell'immagine.
- Anche una scarsa messa a fuoco dell'immagine 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 di fotogrammi:
- Utilizza l'SDK PoseDetection di base e la modalità di rilevamento
stream
. - Prova ad acquisire immagini a una risoluzione inferiore. Tuttavia, tieni presente anche i requisiti relativi alle dimensioni immagine di questa API.
- Per elaborare i fotogrammi video, utilizza l'API sincrona
results(in:)
del rilevatore. Chiama questo metodo dall'elemento AVCaptureVideoDataOutputSampleBufferDelegate captureOutput(_, didOutput:from:) per ottenere in modo sincrono i risultati dal frame video specificato. Mantieni l'attributo alwaysDiscardsLateVideoFrames di AVCaptureVideoDataOutput per limitare le chiamate al rilevatore. Se diventa disponibile un nuovo fotogramma video mentre il rilevatore è in esecuzione, verrà eliminato. - Se utilizzi l'output del rilevatore per sovrapporre elementi grafici all'immagine di input, ottieni il risultato da ML Kit, quindi 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. Consulta le previewOverlayView e. MLKDetectionOverlayView nell'app di esempio Showcase.
Passaggi successivi
- Per scoprire come utilizzare i punti di riferimento per le pose per classificare le pose, consulta i Suggerimenti per la classificazione delle posizioni.
- Consulta l'esempio della guida rapida ML Kit su GitHub per un esempio di questa API in uso.