Posen mit ML Kit für iOS erkennen

ML Kit bietet zwei optimierte SDKs für die Posenerkennung.

SDK-NamePoseDetectionPoseDetectionAccurate
ImplementierungAssets für den Basisdetektor werden beim Erstellen statisch mit Ihrer App verknüpft.Assets für den genauen Detektor werden beim Erstellen statisch mit Ihrer App verknüpft.
App-GrößeBis zu 29,6 MBBis zu 33,2 MB
LeistungiPhone X: ~45 fpsiPhone X: ~29 fps

Jetzt ausprobieren

  • In der Beispiel-App finden Sie ein Beispiel für die Verwendung dieser API.

Hinweis

  1. Fügen Sie die folgenden ML Kit-Pods in Ihre Podfile-Datei ein:

    # 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'
    
  2. 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

Wenn Sie eine Pose in einem Bild erkennen möchten, erstellen Sie zuerst eine Instanz von PoseDetector und geben Sie optional die Detektoreinstellungen an.

Optionen für PoseDetector

Erkennungsmodus

Die PoseDetector funktioniert in zwei Erkennungsmodi. Wählen Sie die Option aus, die Ihrem Anwendungsfall entspricht.

stream (Standard)
Der Detektor für die Posenerkennung erkennt zuerst die am deutlichsten sichtbare Person im Bild und führt dann die Posenerkennung aus. In nachfolgenden Frames wird der Schritt zur Personenerkennung nicht durchgeführt, es sei denn, die Person wird verdeckt oder nicht mehr mit hoher Konfidenz erkannt. Der Pose Detector versucht, die am deutlichsten sichtbare Person zu verfolgen und ihre Pose bei jeder Inferenz zurückzugeben. Dadurch wird die Latenz verringert und die Erkennung verbessert. Verwenden Sie diesen Modus, wenn Sie die Pose in einem Videostream erkennen möchten.
singleImage
Der Haltungsdetektor erkennt eine Person und führt dann die Haltungserkennung aus. Der Schritt zur Personenentdeckung wird für jedes Bild ausgeführt, sodass die Latenz höher ist und keine Personenverfolgung stattfindet. 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 Posenerkennung 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 angegebenen Optionen:

Swift

let poseDetector = PoseDetector.poseDetector(options: options)

Objective-C

MLKPoseDetector *poseDetector =
    [MLKPoseDetector poseDetectorWithOptions:options];

2. Eingabebild vorbereiten

Führen Sie für jedes Bild oder jeden Frame des Videos die folgenden Schritte aus, um Posen zu erkennen. Wenn Sie den Streammodus aktiviert haben, müssen Sie VisionImage-Objekte aus CMSampleBuffers 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 dem UIImage. Achten Sie darauf, die richtige .orientation anzugeben.

    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 im CMSampleBuffer an.

    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 dem CMSampleBuffer-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

Übergebe das VisionImage an eine der Bildverarbeitungsmethoden des Pose Detectors. 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 Bildes 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 Eingabebildes ab:

  • Damit das ML Kit die Pose genau erkennen kann, sollte die Person im Bild durch ausreichend 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 niedrigerer Auflösung aufnehmen. Beachten Sie jedoch die oben genannten Auflösungsanforderungen und achten Sie darauf, dass das Motiv so viel wie möglich vom Bild einnimmt.
  • Auch ein unscharfes Bild kann die Genauigkeit beeinträchtigen. Wenn Sie keine akzeptablen Ergebnisse erhalten, bitten Sie den Nutzer, das Bild noch einmal aufzunehmen.

Wenn Sie die Posenerkennung in einer Echtzeitanwendung verwenden möchten, beachten Sie die folgenden Richtlinien, um die besten Framerates zu erzielen:

  • Verwenden Sie das Basis-PoseDetection SDK und den Erkennungsmodus stream.
  • Versuchen Sie, Bilder mit einer niedrigeren Auflösung aufzunehmen. Beachten Sie jedoch auch die Anforderungen dieser API an die Bildabmessungen.
  • Verwenden Sie zum Verarbeiten von Videoframes die synchrone API results(in:) 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 „true“, um Aufrufe an den Detektor zu drosseln. Wenn ein neuer Videoframe verfügbar wird, während der Detektor ausgeführt wird, wird er verworfen.
  • Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken über 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. Dadurch wird für jeden verarbeiteten Eingabeframe nur einmal auf der Anzeigeoberfläche gerendert. Beispiele finden Sie in den Klassen previewOverlayView und MLKDetectionOverlayView in der Beispiel-App.

Nächste Schritte