Handbuch zur Bewegungserkennung für iOS

Mit der Aufgabe zur Erkennung von Gesten von MediaPipe können Sie Gesten in Echtzeit erkennen. Außerdem werden die Ergebnisse der erkannten Gesten und die Orientierungspunkte der erkannten Hände angezeigt. In dieser Anleitung erfahren Sie, wie Sie den Gestenerkennungsdienst mit iOS-Anwendungen verwenden.

In der Webdemo können Sie sich diese Aufgabe in Aktion ansehen. Weitere Informationen zu den Funktionen, Modellen und Konfigurationsoptionen dieser Aufgabe finden Sie in der Übersicht.

Codebeispiel

Der Beispielcode für MediaPipe Tasks ist eine grundlegende Implementierung einer Gestenerkennungs-App für iOS. Im Beispiel wird die Kamera eines iOS-Geräts verwendet, um Handgesten kontinuierlich zu erkennen. Außerdem können Bilder und Videos aus der Gerätegalerie verwendet werden, um Gesten statisch zu erkennen.

Sie können die App als Ausgangspunkt für Ihre eigene iOS-App verwenden oder sich bei der Änderung einer vorhandenen App daran orientieren. Der Beispielcode für die Gestenererkennung wird auf GitHub gehostet.

Code herunterladen

In der folgenden Anleitung wird beschrieben, wie Sie mit dem Befehlszeilentool git eine lokale Kopie des Beispielcodes erstellen.

So laden Sie den Beispielcode herunter:

  1. Klonen Sie das Git-Repository mit dem folgenden Befehl:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Optional können Sie Ihre Git-Instanz so konfigurieren, dass eine spärliche Überprüfung verwendet wird, sodass nur die Dateien für die Beispiel-App „Gesture Recognizer“ vorhanden sind:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/gesture_recognizer/ios/
    

Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie die MediaPipe-Aufgabenbibliothek installieren, das Projekt mit Xcode öffnen und die App ausführen. Eine Anleitung finden Sie im Einrichtungsleitfaden für iOS.

Schlüsselkomponenten

Die folgenden Dateien enthalten den wichtigen Code für die Beispielanwendung der Gestenerkennung:

  • GestureRecognizerService.swift: Hier wird der Gestener erkennter initialisiert, die Modellauswahl verarbeitet und die Inferenz auf die Eingabedaten angewendet.
  • CameraViewController.swift: Hier wird die Benutzeroberfläche für den Eingabemodus des Live-Kamerafeeds implementiert und die Ergebnisse werden visualisiert.
  • MediaLibraryViewController.swift: Hier wird die Benutzeroberfläche für den Eingabemodus für Standbilder und Videodateien implementiert und die Ergebnisse werden visualisiert.

Einrichtung

In diesem Abschnitt werden die wichtigsten Schritte zur Einrichtung Ihrer Entwicklungsumgebung und Codeprojekte für die Verwendung des Gestener erkennters beschrieben. Allgemeine Informationen zur Einrichtung der Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich der Anforderungen an die Plattformversion, finden Sie im Einrichtungsleitfaden für iOS.

Abhängigkeiten

Der Gesture Recognizer verwendet die MediaPipeTasksVision-Bibliothek, die mit CocoaPods installiert werden muss. Die Bibliothek ist sowohl mit Swift- als auch mit Objective-C-Apps kompatibel und erfordert keine zusätzliche sprachspezifische Einrichtung.

Eine Anleitung zur Installation von CocoaPods unter macOS finden Sie in der CocoaPods-Installationsanleitung. Eine Anleitung zum Erstellen einer Podfile mit den erforderlichen Pods für Ihre App finden Sie unter CocoaPods verwenden.

Fügen Sie den Pod „MediaPipeTasksVision“ in der Datei Podfile mit dem folgenden Code hinzu:

target 'MyGestureRecognizerApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

Wenn Ihre App Unit-Testziele enthält, finden Sie im Einrichtungsleitfaden für iOS weitere Informationen zur Einrichtung Ihrer Podfile.

Modell

Für die MediaPipe-Gestenererkennung ist ein trainiertes Modell erforderlich, das mit dieser Aufgabe kompatibel ist. Weitere Informationen zu den verfügbaren trainierten Modellen für den Gestenerkennungsdienst finden Sie in der Aufgabenübersicht im Abschnitt Modelle.

Wählen Sie ein Modell aus, laden Sie es herunter und fügen Sie es mit Xcode Ihrem Projektverzeichnis hinzu. Eine Anleitung zum Hinzufügen von Dateien zu Ihrem Xcode-Projekt finden Sie unter Dateien und Ordner in Ihrem Xcode-Projekt verwalten.

Verwenden Sie das Attribut BaseOptions.modelAssetPath, um den Pfad zum Modell in Ihrem App-Bundle anzugeben. Ein Codebeispiel finden Sie im nächsten Abschnitt.

Aufgabe erstellen

Sie können die Aufgabe zur Bewegungserkennung erstellen, indem Sie einen seiner Initialisierer aufrufen. Der GestureRecognizer(options:)-Initialisierer akzeptiert Werte für die Konfigurationsoptionen.

Wenn Sie keinen Gestenerkner benötigen, der mit benutzerdefinierten Konfigurationsoptionen initialisiert wird, können Sie mit der GestureRecognizer(modelPath:)-Initialisierung einen Gestenerkner mit den Standardoptionen erstellen. Weitere Informationen zu den Konfigurationsoptionen finden Sie unter Konfigurationsübersicht.

Die Aufgabe „Gestenerkennung“ unterstützt drei Eingabedatentypen: Standbilder, Videodateien und Live-Videostreams. Standardmäßig initialisiert GestureRecognizer(modelPath:) eine Aufgabe für Standbilder. Wenn Sie möchten, dass die Aufgabe für die Verarbeitung von Videodateien oder Live-Videostreams initialisiert wird, verwenden Sie GestureRecognizer(options:), um den Video- oder Livestream-Ausführungsmodus anzugeben. Für den Livestream-Modus ist außerdem die zusätzliche Konfigurationsoption gestureRecognizerLiveStreamDelegate erforderlich, mit der der Gesterkenner die Ergebnisse der Gestenererkennung asynchron an den Delegaten senden kann.

Wählen Sie den Tab für den aktuellen Ausführungsmodus aus, um zu erfahren, wie Sie die Aufgabe erstellen und die Inferenz ausführen.

Swift

Bild

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "gesture_recognizer",
                                      ofType: "task")

let options = GestureRecognizerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

let gestureRecognizer = try GestureRecognizer(options: options)
    

Video

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "gesture_recognizer",
                                      ofType: "task")

let options = GestureRecognizerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

let gestureRecognizer = try GestureRecognizer(options: options)
    

Livestream

import MediaPipeTasksVision

// Class that conforms to the `GestureRecognizerLiveStreamDelegate` protocol and
// implements the method that the gesture recognizer calls once it finishes
// performing recognizing hand gestures in each input frame.
class GestureRecognizerResultProcessor: NSObject, GestureRecognizerLiveStreamDelegate {

  func gestureRecognizer(
    _ gestureRecognizer: GestureRecognizer,
    didFinishRecognition result: GestureRecognizerResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the gesture recognizer result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "gesture_recognizer",
  ofType: "task")

let options = GestureRecognizerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

// Assign an object of the class to the `gestureRecognizerLiveStreamDelegate`
// property.
let processor = GestureRecognizerResultProcessor()
options.gestureRecognizerLiveStreamDelegate = processor

let gestureRecognizer = try GestureRecognizer(options: options)
    

Objective-C

Bild

@import MediaPipeTasksVision;

NSString *modelPath =
  [[NSBundle mainBundle] pathForResource:@"gesture_recognizer"
                                  ofType:@"task"];

MPPGestureRecognizerOptions *options =
  [[MPPGestureRecognizerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

MPPGestureRecognizer *gestureRecognizer =
      [[MPPGestureRecognizer alloc] initWithOptions:options error:nil];
    

Video

@import MediaPipeTasksVision;

NSString *modelPath =
  [[NSBundle mainBundle] pathForResource:@"gesture_recognizer"
                                  ofType:@"task"];

MPPGestureRecognizerOptions *options =
  [[MPPGestureRecognizerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

MPPGestureRecognizer *gestureRecognizer =
      [[MPPGestureRecognizer alloc] initWithOptions:options error:nil];
    

Livestream

@import MediaPipeTasksVision;

// Class that conforms to the `MPPGestureRecognizerLiveStreamDelegate` protocol
// and implements the method that the gesture recognizer calls once it finishes
// performing gesture recognition on each input frame.

@interface APPGestureRecognizerResultProcessor : NSObject 

@end

@implementation APPGestureRecognizerResultProcessor

-   (void)gestureRecognizer:(MPPGestureRecognizer *)gestureRecognizer
    didFinishRecognitionWithResult:(MPPGestureRecognizerResult *)gestureRecognizerResult
           timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                             error:(NSError *)error {

    // Process the gesture recognizer result or errors here.

}

@end

NSString *modelPath =
  [[NSBundle mainBundle] pathForResource:@"gesture_recognizer"
                                  ofType:@"task"];

MPPGestureRecognizerOptions *options =
  [[MPPGestureRecognizerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

// Assign an object of the class to the `gestureRecognizerLiveStreamDelegate`
// property.
APPGestureRecognizerResultProcessor *processor =
  [APPGestureRecognizerResultProcessor new];
options.gestureRecognizerLiveStreamDelegate = processor;

MPPGestureRecognizer *gestureRecognizer =
      [[MPPGestureRecognizer alloc] initWithOptions:options error:nil];
    

Konfigurationsoptionen

Für diese Aufgabe stehen die folgenden Konfigurationsoptionen für iOS-Apps zur Verfügung:

Option Beschreibung Wertebereich Standardwert
runningMode Legt den Ausführungsmodus für die Aufgabe fest. Es gibt drei Modi:

IMAGE: Der Modus für Eingaben mit einem einzelnen Bild.

VIDEO: Der Modus für decodierte Frames eines Videos.

LIVE_STREAM: Der Modus für einen Livestream von Eingabedaten, z. B. von einer Kamera. In diesem Modus muss resultListener aufgerufen werden, um einen Listener für den asynchronen Empfang von Ergebnissen einzurichten. In diesem Modus muss gestureRecognizerLiveStreamDelegate auf eine Instanz einer Klasse festgelegt sein, die GestureRecognizerLiveStreamDelegate implementiert, um die Ergebnisse der Gestenererkennung asynchron zu empfangen.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
num_hands Die maximale Anzahl von Händen, die vom GestureRecognizer erkannt werden kann. Any integer > 0 1
min_hand_detection_confidence Die Mindestpunktzahl für die Handerkennung, die im Modell für die Handflächenerkennung als erfolgreich gilt. 0.0 - 1.0 0.5
min_hand_presence_confidence Der Mindestwert der Konfidenz der Anwesenheit der Hand im Modell zur Erkennung von Handmarkierungen. Im Video- und Livestreammodus der Gestenerkennung wird das Handflächenerkennungsmodell ausgelöst, wenn der Wert für die Hand-Anwesenheitserkennung des Modells für die Hand-Sehenswürdigkeit unter diesem Grenzwert liegt. Andernfalls wird ein einfacher Algorithmus für die Handerkennung verwendet, um die Position der Hand(en) für die anschließende Markierungserkennung zu bestimmen. 0.0 - 1.0 0.5
min_tracking_confidence Der minimale Konfidenzwert für das Hand-Tracking, um als erfolgreich zu gelten. Dies ist der IoU-Grenzwert des Begrenzungsrahmens zwischen den Händen im aktuellen und im letzten Frame. Wenn die Erkennung im Video- und Streammodus der Gestenererkennung fehlschlägt, löst die Gestenererkennung die Handerkennung aus. Andernfalls wird die Handerkennung übersprungen. 0.0 - 1.0 0.5
canned_gestures_classifier_options Optionen zum Konfigurieren des Verhaltens des Klassifikators für gespeicherte Gesten. Die vorgefertigten Touch-Gesten sind ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
  • Gebietsschema für Anzeigenamen: Das Gebietsschema, das für Anzeigenamen verwendet werden soll, die über die TFLite-Modellmetadaten angegeben werden, sofern vorhanden.
  • Max. Ergebnisse: Die maximale Anzahl der Klassifizierungsergebnisse mit der höchsten Punktzahl, die zurückgegeben werden sollen. Wenn der Wert kleiner als 0 ist, werden alle verfügbaren Ergebnisse zurückgegeben.
  • Grenzwert für die Punktzahl: Die Punktzahl, unter der Ergebnisse abgelehnt werden. Wenn der Wert auf „0“ festgelegt ist, werden alle verfügbaren Ergebnisse zurückgegeben.
  • Zulassungsliste für Kategorien: die Zulassungsliste für Kategorienamen. Wenn die Liste nicht leer ist, werden Klassifizierungsergebnisse, deren Kategorie nicht in dieser Liste enthalten ist, herausgefiltert. Schließt „denylist“ aus.
  • Kategorie-Sperreliste: Die Sperrliste der Kategorienamen. Wenn die Liste nicht leer ist, werden Klassifizierungsergebnisse herausgefiltert, deren Kategorie zu dieser Liste gehört. Schließt die Zulassungsliste aus.
    • Sprache für Anzeigenamen: any string
    • Maximale Ergebnisse: any integer
    • Bewertungsgrenzwert: 0.0-1.0
    • Zulassungsliste für Kategorien: vector of strings
    • Sperrliste für Kategorie: vector of strings
    • Sprache für Anzeigenamen: "en"
    • Maximale Ergebnisse: -1
    • Punktzahl-Schwellenwert: 0
    • Zulassungsliste für Kategorien: leer
    • Kategorie-Sperliste: leer
    custom_gestures_classifier_options Optionen zum Konfigurieren des Verhaltens des Klassifikators für benutzerdefinierte Touch-Gesten.
  • Gebietsschema für Anzeigenamen: Das Gebietsschema, das für Anzeigenamen verwendet werden soll, die über die TFLite-Modellmetadaten angegeben werden, sofern vorhanden.
  • Max. Ergebnisse: Die maximale Anzahl der Klassifizierungsergebnisse mit der höchsten Punktzahl, die zurückgegeben werden sollen. Wenn der Wert kleiner als 0 ist, werden alle verfügbaren Ergebnisse zurückgegeben.
  • Grenzwert für die Punktzahl: Die Punktzahl, unter der Ergebnisse abgelehnt werden. Wenn der Wert auf „0“ festgelegt ist, werden alle verfügbaren Ergebnisse zurückgegeben.
  • Zulassungsliste für Kategorien: die Zulassungsliste für Kategorienamen. Wenn die Liste nicht leer ist, werden Klassifizierungsergebnisse, deren Kategorie nicht in dieser Liste enthalten ist, herausgefiltert. Schließt „denylist“ aus.
  • Kategorie-Sperreliste: Die Sperrliste der Kategorienamen. Wenn die Liste nicht leer ist, werden Klassifizierungsergebnisse herausgefiltert, deren Kategorie zu dieser Liste gehört. Schließt die Zulassungsliste aus.
    • Sprache für Anzeigenamen: any string
    • Maximale Ergebnisse: any integer
    • Bewertungsgrenzwert: 0.0-1.0
    • Zulassungsliste für Kategorien: vector of strings
    • Sperrliste für Kategorie: vector of strings
    • Sprache für Anzeigenamen: "en"
    • Maximale Ergebnisse: -1
    • Punktzahl-Schwellenwert: 0
    • Zulassungsliste für Kategorien: leer
    • Kategorie-Sperliste: leer
    result_listener Legt fest, dass der Ergebnisempfänger die Klassifizierungsergebnisse asynchron empfängt, wenn sich die Gesterkenner im Livestream-Modus befindet. Kann nur verwendet werden, wenn der Ausführungsmodus auf LIVE_STREAM festgelegt ist. ResultListener

    Wenn der Laufmodus auf Livestream festgelegt ist, erfordert die Gestenerkennung die zusätzliche Konfigurationsoption gestureRecognizerLiveStreamDelegate. Dadurch kann die Gestenerkennung Ergebnisse asynchron liefern. Der Bevollmächtigte muss die Methode gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:) implementieren, die von der Gestenerkennung aufgerufen wird, nachdem die Ergebnisse der Gestenerkennung für jeden Frame verarbeitet wurden.

    Optionsname Beschreibung Wertebereich Standardwert
    gestureRecognizerLiveStreamDelegate Ermöglicht es dem Gestenerkennungssystem, die Ergebnisse der Gestenererkennung im Livestream-Modus asynchron zu empfangen. Die Klasse, deren Instanz auf diese Property festgelegt ist, muss die Methode gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:) implementieren. Nicht zutreffend Nicht festgelegt

    Daten vorbereiten

    Sie müssen das Eingabebild oder den Eingabeframe in ein MPImage-Objekt konvertieren, bevor Sie es an den Gestenerkennungsdienst übergeben. MPImage unterstützt verschiedene Arten von iOS-Bildformaten und kann sie in jedem Betriebsmodus für die Inferenz verwenden. Weitere Informationen zu MPImage finden Sie in der MPImage API.

    Wählen Sie ein iOS-Bildformat entsprechend Ihrem Anwendungsfall und dem erforderlichen Ausführungsmodus Ihrer Anwendung aus.MPImage unterstützt die iOS-Bildformate UIImage, CVPixelBuffer und CMSampleBuffer.

    UIImage

    Das UIImage-Format eignet sich gut für die folgenden Laufmodi:

    • Bilder: Bilder aus einem App-Bundle, einer Nutzergalerie oder einem Dateisystem, das als UIImage-Bilder formatiert ist, können in ein MPImage-Objekt umgewandelt werden.

    • Videos: Mit dem AVAssetImageGenerator können Sie Videoframes im CGImage-Format extrahieren und dann in UIImage-Bilder konvertieren.

    Swift

    // Load an image on the user's device as an iOS `UIImage` object.
    
    // Convert the `UIImage` object to a MediaPipe's Image object having the default
    // orientation `UIImage.Orientation.up`.
    let image = try MPImage(uiImage: image)
        

    Objective-C

    // Load an image on the user's device as an iOS `UIImage` object.
    
    // Convert the `UIImage` object to a MediaPipe's Image object having the default
    // orientation `UIImageOrientationUp`.
    MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
        

    Im Beispiel wird eine MPImage mit der Standardausrichtung UIImage.Orientation.Up initialisiert. Sie können MPImage mit jedem der unterstützten Werte für UIImage.Orientation initialisieren. Der Gestenerkennungsdienst unterstützt keine gespiegelten Ausrichtungen wie .upMirrored, .downMirrored, .leftMirrored und .rightMirrored.

    Weitere Informationen zu UIImage finden Sie in der Apple Developer-Dokumentation zu UIImage.

    CVPixelBuffer

    Das CVPixelBuffer-Format eignet sich gut für Anwendungen, die Frames generieren und das iOS-CoreImage-Framework für die Verarbeitung verwenden.

    Das CVPixelBuffer-Format eignet sich gut für die folgenden Laufmodi:

    • Bilder: Apps, die nach einer Verarbeitung mit dem CoreImage-Framework von iOS CVPixelBuffer-Bilder generieren, können im Modus „Bild ausführen“ an die Gesterkenner gesendet werden.

    • Videos: Videoframes können zur Verarbeitung in das CVPixelBuffer-Format konvertiert und dann im Videomodus an den Gestenerkennungsdienst gesendet werden.

    • Livestream: Apps, die eine iOS-Kamera zum Generieren von Frames verwenden, können zur Verarbeitung in das CVPixelBuffer-Format konvertiert werden, bevor sie im Livestream-Modus an die Gestenerkennung gesendet werden.

    Swift

    // Obtain a CVPixelBuffer.
    
    // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default
    // orientation `UIImage.Orientation.up`.
    let image = try MPImage(pixelBuffer: pixelBuffer)
        

    Objective-C

    // Obtain a CVPixelBuffer.
    
    // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the
    // default orientation `UIImageOrientationUp`.
    MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
        

    Weitere Informationen zu CVPixelBuffer findest du in der CVPixelBuffer-Entwicklerdokumentation von Apple.

    CMSampleBuffer

    Im CMSampleBuffer-Format werden Mediensamples eines einheitlichen Medientyps gespeichert. Es eignet sich gut für den Livestream-Ausführungsmodus. Live-Frames von iOS-Kameras werden asynchron im CMSampleBuffer-Format von iOS AVCaptureVideoDataOutput bereitgestellt.

    Swift

    // Obtain a CMSampleBuffer.
    
    // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default
    // orientation `UIImage.Orientation.up`.
    let image = try MPImage(sampleBuffer: sampleBuffer)
        

    Objective-C

    // Obtain a `CMSampleBuffer`.
    
    // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the
    // default orientation `UIImageOrientationUp`.
    MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
        

    Weitere Informationen zu CMSampleBuffer findest du in der CMSampleBuffer-Entwicklerdokumentation von Apple.

    Aufgabe ausführen

    Verwenden Sie zum Ausführen des Gestenerkennungsmoduls die für den zugewiesenen Ausführungsmodus spezifische recognize()-Methode:

    • Standbild: recognize(image:)
    • Video: recognize(videoFrame:timestampInMilliseconds:)
    • Livestream: recognizeAsync(image:timestampInMilliseconds:)

    Die folgenden Codebeispiele zeigen einfache Beispiele für die Ausführung des Gestener erkennters in diesen verschiedenen Ausführungsmodi:

    Swift

    Bild

    let result = try gestureRecognizer.recognize(image: image)
        

    Video

    let result = try gestureRecognizer.recognize(
      videoFrame: image,
      timestampInMilliseconds: timestamp)
        

    Livestream

    try gestureRecognizer.recognizeAsync(
      image: image,
      timestampInMilliseconds: timestamp)
        

    Objective-C

    Bild

      MPPGestureRecognizerResult *result =
        [gestureRecognizer recognizeImage:mppImage
                                    error:nil];
        

    Video

    MPPGestureRecognizerResult *result =
      [gestureRecognizer recognizeVideoFrame:image
                     timestampInMilliseconds:timestamp
                                       error:nil];
        

    Livestream

    BOOL success =
      [gestureRecognizer recognizeAsyncImage:image
                     timestampInMilliseconds:timestamp
                                       error:nil];
        

    Mit dem Beispielcode kann der Nutzer zwischen Verarbeitungsmodi wechseln, die für Ihren Anwendungsfall möglicherweise nicht erforderlich sind.

    Wichtige Hinweise:

    • Wenn Sie die Erkennung im Video- oder Livestream-Modus ausführen, müssen Sie der Aufgabe „Gestenerkennung“ auch den Zeitstempel des Eingabeframes angeben.

    • Wenn die Ausführung im Bild- oder Videomodus erfolgt, blockiert die Gestenererkennungsaufgabe den aktuellen Thread, bis die Verarbeitung des Eingabebilds oder ‑frames abgeschlossen ist. Damit der aktuelle Thread nicht blockiert wird, führen Sie die Verarbeitung in einem Hintergrundthread mit den iOS-Frameworks Dispatch oder NSOperation aus.

    • Wenn die Ausführung im Livestream-Modus erfolgt, gibt die Aufgabe „Gestenerkennung“ sofort ein Ergebnis zurück und blockiert den aktuellen Thread nicht. Nach der Verarbeitung jedes Eingabeframes wird die Methode gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:) mit dem Ergebnis der Gestenererkennung aufgerufen. Die Gestenerkennung ruft diese Methode asynchron in einer dedizierten Warteschlange für die serielle Weiterleitung auf. Wenn Sie Ergebnisse in der Benutzeroberfläche anzeigen möchten, senden Sie sie nach der Verarbeitung an die Hauptwarteschlange. Wenn die Funktion recognizeAsync aufgerufen wird, während die Gestenerkennungsaufgabe gerade einen anderen Frame verarbeitet, wird der neue Eingabeframe ignoriert.

    Ergebnisse verarbeiten und anzeigen

    Nach der Ausführung der Inference gibt die Aufgabe „Geste erkennen“ eine GestureRecognizerResult zurück, die Handmarkierungen in Bildkoordinaten, Handmarkierungen in Weltkoordinaten, die Handdominanz(linke/rechte Hand) und die Kategorien der erkannten Handgesten enthält.

    Im Folgenden sehen Sie ein Beispiel für die Ausgabedaten dieser Aufgabe:

    Die resultierende GestureRecognizerResult enthält vier Komponenten, wobei jede Komponente ein Array ist, wobei jedes Element das erkannte Ergebnis einer einzelnen erkannten Hand enthält.

    • Links-/Rechtshänder

      „Handedness“ gibt an, ob die erkannten Hände links- oder rechtshändig sind.

    • Touch-Gesten

      Die erkannten Gestenkategorien der erkannten Hände.

    • Landmarken

      Es gibt 21 Landmarken für die Hand, die jeweils aus x-, y- und z-Koordinaten bestehen. Die Koordinaten x und y werden durch die Bildbreite bzw. -höhe auf [0, 0; 1, 0] normalisiert. Die z-Koordinate steht für die Markierungstiefe. Die Tiefe am Handgelenk ist der Ursprung. Je kleiner der Wert, desto näher ist das Wahrzeichen an der Kamera. Die Größe von z wird ungefähr auf derselben Skala wie x dargestellt.

    • Sehenswürdigkeiten der Welt

      Die 21 Markierungen für die Hand werden ebenfalls in Weltkoordinaten dargestellt. Jede Sehenswürdigkeit besteht aus x, y und z, die reale 3D-Koordinaten in Metern darstellen, deren Ursprung am geometrischen Mittelpunkt der Hand liegt.

    GestureRecognizerResult:
      Handedness:
        Categories #0:
          index        : 0
          score        : 0.98396
          categoryName : Left
      Gestures:
        Categories #0:
          score        : 0.76893
          categoryName : Thumb_Up
      Landmarks:
        Landmark #0:
          x            : 0.638852
          y            : 0.671197
          z            : -3.41E-7
        Landmark #1:
          x            : 0.634599
          y            : 0.536441
          z            : -0.06984
        ... (21 landmarks for a hand)
      WorldLandmarks:
        Landmark #0:
          x            : 0.067485
          y            : 0.031084
          z            : 0.055223
        Landmark #1:
          x            : 0.063209
          y            : -0.00382
          z            : 0.020920
        ... (21 world landmarks for a hand)
    

    Die folgenden Bilder zeigen eine Visualisierung der Aufgabenausgabe: