ML Kit bietet zwei optimierte SDKs für die Erkennung von Posen.
SDK-Name | PoseDetection | PoseDetectionAccurate |
---|---|---|
Implementierung | Assets für den Basisdetektor werden zur Build-Zeit statisch mit Ihrer App verknüpft. | Assets für einen genauen Detektor werden zur Build-Zeit 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
- Beispiel-App ausprobieren, um ein Beispiel für die Verwendung dieser API zu sehen.
Hinweis
Fügen Sie Ihrer Podfile-Datei die folgenden ML Kit-Pods hinzu:
# 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'
Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie Ihr Xcode-Projekt mit der Datei
xcworkspace
. ML Kit wird in Xcode-Version 13.2.1 oder höher unterstützt.
1. Instanz von PoseDetector
erstellen
Um eine Pose in einem Bild zu erkennen, erstellen Sie zuerst eine Instanz von PoseDetector
und geben Sie optional die Einstellungen für den Detektor an.
Optionen für PoseDetector
Erkennungsmodus
Die PoseDetector
arbeitet in zwei Erkennungsmodi. Wählen Sie die Option aus, die am besten zu Ihrem Anwendungsfall passt.
stream
(Standard)- Der Pose-Detektor erkennt zuerst die wichtigste Person im Bild und führt dann die Pose-Erkennung durch. In nachfolgenden Frames wird die Personenerkennung nicht durchgeführt, es sei denn, die Person wird verdeckt oder nicht mehr mit hoher Wahrscheinlichkeit erkannt. Der Pose-Detektor versucht, die wichtigste Person zu verfolgen und ihre Pose bei jeder Inferenz 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 Pose-Detektor erkennt eine Person und führt dann die Pose-Erkennung aus. Die Personenerkennung wird für jedes Bild ausgeführt. Daher ist die Latenz höher und es gibt keine Personenverfolgung. Verwenden Sie diesen Modus, wenn Sie die Posenerkennung für statische Bilder verwenden oder kein Tracking gewünscht ist.
Geben Sie die Optionen für die Erkennung von Körperhaltungen an:
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;
Rufen Sie schließlich eine Instanz von PoseDetector
ab. Übergeben Sie die von Ihnen angegebenen Optionen:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Eingabebild vorbereiten
So erkennen Sie Posen für jedes Bild oder jeden Videoframes:
Wenn Sie den Streamingmodus aktiviert haben, müssen Sie VisionImage
-Objekte aus CMSampleBuffer
s 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, dass Sie die richtige.orientation
angeben.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
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 ab:
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; } }
- Erstellen Sie ein
VisionImage
-Objekt mit demCMSampleBuffer
-Objekt und der Ausrichtung: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. Bild verarbeiten
Übergeben Sie VisionImage
an eine der Bildverarbeitungsmethoden des Pose-Detektors. Sie können entweder die asynchrone Methode process(image:)
oder die synchrone Methode results()
verwenden.
So erkennen Sie Objekte synchron:
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.
So erkennen Sie Objekte asynchron:
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. Informationen zur erkannten Pose abrufen
Wenn eine Person im Bild erkannt wird, übergibt die Pose Detection API entweder ein Array von Pose
-Objekten an den Completion-Handler oder gibt das Array zurück, je nachdem, ob Sie die asynchrone oder synchrone Methode aufgerufen haben.
Wenn die Person nicht vollständig im Bild zu sehen war, weist das Modell den fehlenden Landmarken Koordinaten außerhalb des Rahmens zu und gibt ihnen niedrige InFrameConfidence-Werte.
Wenn keine Person erkannt wurde, ist das Array leer.
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; } }
Tipps zur Leistungsverbesserung
Die Qualität der Ergebnisse hängt von der Qualität des Eingabebilds ab:
- Damit ML Kit Posen genau erkennen kann, muss die Person im Bild durch genügend Pixeldaten dargestellt werden. Für eine optimale Leistung sollte das Motiv mindestens 256 × 256 Pixel groß sein.
- Wenn Sie die Pose 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 niedrigeren Auflösungen aufnehmen. Beachten Sie jedoch die oben genannten Anforderungen an die Auflösung und sorgen Sie dafür, dass das Motiv so viel wie möglich vom Bild einnimmt.
- Eine schlechte Bildschärfe kann sich ebenfalls auf die Genauigkeit auswirken. Wenn Sie keine akzeptablen Ergebnisse erhalten, bitten Sie den Nutzer, das Bild noch einmal aufzunehmen.
Wenn Sie die Erkennung von Körperhaltungen in einer Echtzeitanwendung verwenden möchten, sollten Sie die folgenden Richtlinien beachten, um die besten Framerates zu erzielen:
- Verwenden Sie das Basis-SDK für die Posenerkennung und den
stream
-Erkennungsmodus. - Nehmen Sie Bilder mit einer niedrigeren Auflösung auf. Beachten Sie jedoch auch die Anforderungen an die Bildabmessungen für diese API.
- Verwenden Sie für die Verarbeitung von Videoframes die synchrone
results(in:)
-API des Detektors. Rufen Sie diese Methode aus der Funktion captureOutput(_, didOutput:from:) des AVCaptureVideoDataOutputSampleBufferDelegate auf, um synchron Ergebnisse aus dem angegebenen Videobild zu erhalten. Lassen Sie AVCaptureVideoDataOutput's alwaysDiscardsLateVideoFrames auf „true“, um Aufrufe des Detektors zu drosseln. Wenn ein neuer Videoframes verfügbar wird, während der Detektor ausgeführt wird, wird er verworfen. - Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken auf das Eingabebild zu legen, rufen Sie zuerst das Ergebnis von ML Kit ab und rendern Sie dann das Bild und das Overlay in einem einzigen Schritt. Dadurch wird für jeden verarbeiteten Eingabe-Frame nur einmal auf die Displayoberfläche gerendert. Ein Beispiel finden Sie in den Klassen previewOverlayView und MLKDetectionOverlayView in der Showcase-Beispiel-App.
Nächste Schritte
- Informationen zur Verwendung von Landmarken für die Körperhaltung zur Klassifizierung von Posen finden Sie unter Tipps zur Klassifizierung von Posen.
- Ein Beispiel für die Verwendung dieser API finden Sie im ML Kit-Schnellstartbeispiel auf GitHub.