ML Kit bietet zwei optimierte SDKs für die Körperhaltungserkennung.
SDK-Name | PoseDetection | PoseDetectionAccurate |
---|---|---|
Implementierung | Assets für den Basis-Detektor werden bei der Buildzeit statisch mit Ihrer App verknüpft. | Assets für den genauen Detector werden während der Buildzeit statisch mit Ihrer App verknüpft. |
App-Größe | Bis zu 29,6 MB | Bis zu 33,2 MB |
Leistung | iPhone X: ca. 45 fps | iPhone X: ca. 29 fps |
Jetzt ausprobieren
- In der Beispielanwendung sehen Sie ein Beispiel für die Verwendung dieser API.
Hinweis
Fügen Sie Ihrer Podfile-Datei die folgenden ML Kit-Pods hinzu:
# If you want to use the base implementation: pod 'GoogleMLKit/PoseDetection', '7.0.0' # If you want to use the accurate implementation: pod 'GoogleMLKit/PoseDetectionAccurate', '7.0.0'
Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie Ihr Xcode-Projekt über die
xcworkspace
. ML Kit wird in Xcode Version 13.2.1 oder höher unterstützt.
1. Instanz von PoseDetector
erstellen
Wenn Sie eine Pose in einem Bild erkennen möchten, erstellen Sie zuerst eine Instanz von PoseDetector
und geben Sie optional die Einstellungen für den Detector an.
Optionen für PoseDetector
Erkennungsmodus
Der PoseDetector
kann in zwei Erkennungsmodi betrieben werden. Achten Sie darauf, die Option auszuwählen, die zu Ihrem Anwendungsfall passt.
stream
(Standard)- Die Positionserkennung erkennt zuerst die am stärksten hervortretende Person im Bild und führt dann die Positionserkennung durch. In den nachfolgenden Frames wird der Schritt zur Personenerkennung nur ausgeführt, wenn die Person verdeckt ist oder nicht mehr mit hoher Wahrscheinlichkeit erkannt wird. Der Körperhaltungs-Detektor versucht, die am stärksten hervortretende Person zu verfolgen und ihre Körperhaltung bei jeder Erkennung zurückzugeben. Dadurch wird die Latenz verringert und die Erkennung optimiert. Verwenden Sie diesen Modus, wenn Sie die Körperhaltung in einem Videostream erkennen möchten.
singleImage
- Der Haltungsdetektor erkennt eine Person und führt dann die Haltungserkennung aus. Der Schritt zur Personenerkennung wird für jedes Bild ausgeführt. Daher ist die Latenz höher und es erfolgt kein Personen-Tracking. Verwenden Sie diesen Modus, wenn Sie die Körperhaltungserkennung auf statischen Bildern verwenden oder wenn kein Tracking gewünscht ist.
Geben Sie die Optionen für die Körperhaltungserkennung an:
// 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
// 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;
Rufen Sie abschließend eine Instanz von PoseDetector
ab. Übergeben Sie die von Ihnen angegebenen Optionen:
let poseDetector = PoseDetector.poseDetector(options: options)
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Eingabebild vorbereiten
Führen Sie für jedes Bild oder jeden Videoframe die folgenden Schritte aus, um Posen zu erkennen.
Wenn Sie den Stream-Modus aktiviert haben, müssen Sie VisionImage
-Objekte aus CMSampleBuffer
-Objekten erstellen.
Erstellen Sie ein VisionImage
-Objekt mit einem UIImage
oder einem CMSampleBuffer
.
Wenn Sie ein UIImage
verwenden, gehen Sie so vor:
- Erstellen Sie ein
VisionImage
-Objekt mit demUIImage
. Achten Sie darauf, die richtige.orientation
anzugeben.let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Wenn Sie ein CMSampleBuffer
verwenden, gehen Sie so vor:
-
Geben Sie die Ausrichtung der Bilddaten an, die in
CMSampleBuffer
enthalten sind.So rufen Sie die Bildausrichtung auf:
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 } }
- (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; } }
- Erstellen Sie ein
VisionImage
-Objekt mit demCMSampleBuffer
-Objekt und der Ausrichtung:let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. Bild verarbeiten
Übergeben Sie VisionImage
an eine der Bildverarbeitungsmethoden des Positionserkennungstools. Sie können entweder die asynchrone Methode process(image:)
oder die synchrone Methode results()
verwenden.
So erkennen Sie Objekte synchron:
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.
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.
So erkennen Sie Objekte asynchron:
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. }
[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. Informationen zur erkannten Pose abrufen
Wenn im Bild eine Person erkannt wird, übergibt die API zur Körperhaltungserkennung entweder ein Array von Pose
-Objekten an den Abschluss-Handler oder gibt das Array zurück. Das hängt davon ab, ob Sie die asynchrone oder die synchrone Methode aufgerufen haben.
Wenn die Person nicht vollständig im Bild ist, weist das Modell den fehlenden Markierungen Koordinaten außerhalb des Bildes zu und gibt ihnen niedrige Werte für die Konfidenz im Bild.
Wenn keine Person erkannt wurde, ist das Array leer.
for pose in detectedPoses { let leftAnkleLandmark = pose.landmark(ofType: .leftAnkle) if leftAnkleLandmark.inFrameLikelihood > 0.5 { let position = leftAnkleLandmark.position } }
for (MLKPose *pose in detectedPoses) { MLKPoseLandmark *leftAnkleLandmark = [pose landmarkOfType:MLKPoseLandmarkTypeLeftAnkle]; if (leftAnkleLandmark.inFrameLikelihood > 0.5) { MLKVision3DPoint *position = leftAnkleLandmark.position; } }
Tipps zur Leistungsverbesserung
Die Qualität der Ergebnisse hängt von der Qualität des Eingabebilds ab:
- Damit ML Kit die Körperhaltung genau erkennen kann, muss die Person auf dem Bild durch ausreichend Pixeldaten dargestellt werden. Für eine optimale Leistung sollte das Motiv mindestens 256 × 256 Pixel groß sein.
- Wenn Sie die Körperhaltung in einer Echtzeitanwendung erkennen, sollten Sie auch die Gesamtabmessungen der Eingabebilder berücksichtigen. Kleinere Bilder können schneller verarbeitet werden. Um die Latenz zu verringern, sollten Sie Bilder mit niedrigerer Auflösung aufnehmen. Beachten Sie dabei jedoch die oben genannten Auflösungsanforderungen und achten Sie darauf, dass das Motiv möglichst viel Platz auf dem Bild einnimmt.
- Auch ein unscharfer Bildfokus kann sich auf die Genauigkeit auswirken. Wenn Sie keine zufriedenstellenden Ergebnisse erhalten, bitten Sie den Nutzer, das Bild noch einmal aufzunehmen.
Wenn Sie die Körperhaltungserkennung in einer Echtzeitanwendung verwenden möchten, beachten Sie die folgenden Richtlinien, um die beste Framerate zu erzielen:
- Verwende das Basis-PoseDetection SDK und den
stream
-Erkennungsmodus. - Sie können auch Bilder mit niedrigerer Auflösung aufnehmen. Beachten Sie jedoch auch die Anforderungen an die Bildabmessungen dieser API.
- Verwenden Sie für die Verarbeitung von Videoframes die synchrone
results(in:)
API des Detektors. Rufen Sie diese Methode über die Funktion captureOutput(_, didOutput:from:) des AVCaptureVideoDataOutputSampleBufferDelegate auf, um synchron Ergebnisse aus dem angegebenen Videoframe abzurufen. Lassen Sie alwaysDiscardsLateVideoFrames von AVCaptureVideoDataOutput auf „wahr“ gesetzt, um Aufrufe an den Detektor zu drosseln. Wenn während der Laufzeit des Detektors ein neuer Videoframe verfügbar wird, wird er verworfen. - Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken auf das Eingabebild zu legen, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern Sie dann das Bild und das Overlay in einem einzigen Schritt. So wird für jeden verarbeiteten Eingabeframe nur einmal auf die Displayoberfläche gerendert. Eines dieser Beispiele sind die Klassen previewOverlayView und MLKDetectionOverlayView in der Beispiel-App.
Nächste Schritte
- Informationen dazu, wie Sie anhand von Positionsmarkierungen Posen klassifizieren, finden Sie unter Tipps zur Positionsklassifizierung.
- Ein Beispiel für die Verwendung dieser API finden Sie im ML Kit-Beispiel für die Schnellstartanleitung auf GitHub.