Handbuch zur Bewegungserkennung für iOS

Mit der Aufgabe „MediaPipe-Gestenerkennung“ können Sie Gesten in Echtzeit erkennen und erhalten die Ergebnisse der erkannten Gesten und Markierungen der erkannten Hände. In dieser Anleitung erfahren Sie, wie Sie die Bewegungserkennung in iOS-Apps verwenden.

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

Codebeispiel

Der Beispielcode für MediaPipe Tasks ist die grundlegende Implementierung einer App zur Gestenerkennung für iOS. In diesem Beispiel wird die Kamera eines iOS-Geräts verwendet, um kontinuierlich Handgesten zu erkennen. Es können auch 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 darauf zurückgreifen, wenn Sie eine vorhandene App ändern. Der Beispielcode für die Gestenerkennung wird auf GitHub gehostet.

Code herunterladen

In der folgenden Anleitung erfahren Sie, wie Sie mit dem git-Befehlszeilentool 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 die Git-Instanz für die Verwendung von Sparse-Checkout konfigurieren, sodass Sie nur die Dateien für die Beispielanwendung für die Gestenerkennung haben:

    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 Beispiel-App für die Gestenerkennung:

Einrichtung

In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten der Entwicklungsumgebung und Codeprojekte für die Verwendung der Gestenerkennung beschrieben. Allgemeine Informationen zum Einrichten 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

Die Gestenerkennung verwendet die MediaPipeTasksVision-Bibliothek, die mit CocoaPods installiert werden muss. Die Bibliothek ist sowohl mit Swift- als auch mit Objective-C-Anwendungen 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 eines Podfile mit den erforderlichen Pods für Ihre Anwendung finden Sie unter CocoaPods verwenden.

Fügen Sie den MediaPipeTasksVision-Pod mit dem folgenden Code in Podfile ein:

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

Falls Ihre App Ziele für Einheitentests enthält, finden Sie im Einrichtungsleitfaden für iOS weitere Informationen zum Einrichten von Podfile.

Modell

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

Wählen Sie ein Modell aus, laden Sie es herunter und fügen Sie es Ihrem Projektverzeichnis mithilfe von Xcode hinzu. Eine Anleitung zum Hinzufügen von Dateien zu Ihrem Xcode-Projekt finden Sie unter Dateien und Ordner in einem 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 ihrer Initialisierer aufrufen. Der GestureRecognizer(options:)-Initialisierer akzeptiert Werte für die Konfigurationsoptionen.

Wenn Sie keine Gestenerkennung mit benutzerdefinierten Konfigurationsoptionen initialisieren müssen, können Sie mit dem GestureRecognizer(modelPath:)-Initialisierer eine Bewegungserkennung mit den Standardoptionen erstellen. Weitere Informationen zu Konfigurationsoptionen finden Sie in der Konfigurationsübersicht.

Die Aufgabe zur Bewegungserkennung 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 zur Verarbeitung von Videodateien oder Live-Videostreams initialisiert wird, geben Sie den Video- oder Livestream-Ausführungsmodus mit GestureRecognizer(options:) an. Für den Livestream-Modus ist außerdem die zusätzliche Konfigurationsoption gestureRecognizerLiveStreamDelegate erforderlich. Dadurch kann die Bewegungserkennung Ergebnisse der Gestenerkennung asynchron an den Bevollmächtigten senden.

Wählen Sie den Tab für Ihren 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

Diese Aufgabe bietet die folgenden Konfigurationsoptionen für iOS-Apps:

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

IMAGE: Der Modus für Einzelbildeingaben.

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

LIVE_STREAM: Der Modus für einen Livestream der Eingabedaten, z. B. von einer Kamera. In diesem Modus muss resultListener aufgerufen werden, um einen Listener einzurichten, der die Ergebnisse asynchron empfängt. In diesem Modus muss gestureRecognizerLiveStreamDelegate auf eine Instanz einer Klasse festgelegt werden, die GestureRecognizerLiveStreamDelegate implementiert, um die Ergebnisse der asynchronen Gestenerkennung zu empfangen.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
num_hands Die maximale Anzahl von Händen kann von GestureRecognizer erkannt werden. Any integer > 0 1
min_hand_detection_confidence Der Mindestkonfidenzwert für die Handerkennung, um im Handflächenerkennungsmodell als erfolgreich zu gelten. 0.0 - 1.0 0.5
min_hand_presence_confidence Der minimale Konfidenzwert für die Handpräsenz im Modell zur Erkennung von Handmarkierungen. Wenn im Video- und Livestream-Modus der Bewegungserkennung der Konfidenzwert für die Anwesenheitserkennung vom Modell für Handmarkierungen unter diesem Grenzwert liegt, wird das Handflächenerkennungsmodell ausgelöst. Andernfalls wird ein leichter Algorithmus zur Handverfolgung verwendet, um die Position der Hand(en) für die nachfolgende Erkennung von Sehenswürdigkeiten zu bestimmen. 0.0 - 1.0 0.5
min_tracking_confidence Der Mindestkonfidenzwert, der für eine erfolgreiche Verfolgung der Handzeichen erforderlich ist. Dies ist der IoU-Grenzwert des Begrenzungsrahmens zwischen Händen im aktuellen und im letzten Frame. Wenn im Video- und Streammodus der Bewegungserkennung die Bewegungserkennung fehlschlägt, löst die Bewegungserkennung die Handerkennung aus, wenn das Tracking fehlschlägt. 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. Vordefinierte Touch-Gesten sind ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
  • Sprache für Anzeigenamen: das für Anzeigenamen, die gegebenenfalls über die TFLite-Modellmetadaten angegeben werden.
  • Max. Ergebnisse: Die maximale Anzahl der Klassifizierungsergebnisse mit der höchsten Punktzahl, die zurückgegeben werden sollen. Wenn < 0, werden alle verfügbaren Ergebnisse zurückgegeben.
  • Punktzahl-Schwellenwert: Der Wert, unter dem Ergebnisse abgelehnt werden. Wenn dieser Wert auf 0 gesetzt ist, werden alle verfügbaren Ergebnisse zurückgegeben.
  • Kategorie-Zulassungsliste: Die Zulassungsliste mit Kategorienamen. Wenn das Feld nicht leer ist, werden Klassifizierungsergebnisse herausgefiltert, die nicht in diesem Satz enthalten sind. Sich gegenseitig ausschließend mit Sperrliste
  • Kategorie-Sperrliste: die Sperrliste der Kategorienamen Wenn das Feld nicht leer ist, werden Klassifizierungsergebnisse herausgefiltert, die zu dieser Kategorie gehören. Schließt sich gegenseitig aus mit Zulassungsliste.
    • Sprache für Anzeigenamen: any string
    • Max. Ergebnisse: any integer
    • Punktzahl-Schwellenwert: 0.0-1.0
    • Zulassungsliste für Kategorien: vector of strings
    • Sperrliste für Kategorien: vector of strings
    • Sprache für Anzeigenamen: "en"
    • Max. Ergebnisse: -1
    • Punktzahl-Schwellenwert: 0
    • Zulassungsliste für Kategorien: leer
    • Sperrliste für Kategorien: leer
    custom_gestures_classifier_options Optionen zum Konfigurieren des Verhaltens des benutzerdefinierten Gestenklassifikators.
  • Sprache für Anzeigenamen: das für Anzeigenamen, die gegebenenfalls über die TFLite-Modellmetadaten angegeben werden.
  • Max. Ergebnisse: Die maximale Anzahl der Klassifizierungsergebnisse mit der höchsten Punktzahl, die zurückgegeben werden sollen. Wenn < 0, werden alle verfügbaren Ergebnisse zurückgegeben.
  • Punktzahl-Schwellenwert: Der Wert, unter dem Ergebnisse abgelehnt werden. Wenn dieser Wert auf 0 gesetzt ist, werden alle verfügbaren Ergebnisse zurückgegeben.
  • Kategorie-Zulassungsliste: Die Zulassungsliste mit Kategorienamen. Wenn das Feld nicht leer ist, werden Klassifizierungsergebnisse herausgefiltert, die nicht in diesem Satz enthalten sind. Sich gegenseitig ausschließend mit Sperrliste
  • Kategorie-Sperrliste: die Sperrliste der Kategorienamen Wenn das Feld nicht leer ist, werden Klassifizierungsergebnisse herausgefiltert, die zu dieser Kategorie gehören. Schließt sich gegenseitig aus mit Zulassungsliste.
    • Sprache für Anzeigenamen: any string
    • Max. Ergebnisse: any integer
    • Punktzahl-Schwellenwert: 0.0-1.0
    • Zulassungsliste für Kategorien: vector of strings
    • Sperrliste für Kategorien: vector of strings
    • Sprache für Anzeigenamen: "en"
    • Max. Ergebnisse: -1
    • Punktzahl-Schwellenwert: 0
    • Zulassungsliste für Kategorien: leer
    • Sperrliste für Kategorien: leer
    result_listener Legt den Ergebnis-Listener so fest, dass er die Klassifizierungsergebnisse asynchron empfängt, wenn sich die Gestenerkennung im Livestream-Modus befindet. Kann nur verwendet werden, wenn der Laufmodus auf LIVE_STREAM festgelegt ist ResultListener

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

    Optionsname Beschreibung Wertebereich Standardwert
    gestureRecognizerLiveStreamDelegate Aktiviert die Bewegungserkennung, um die Ergebnisse der Bewegungserkennung im Livestream-Modus asynchron zu empfangen. Die Klasse, deren Instanz auf dieses Attribut festgelegt ist, muss die Methode gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:) implementieren. Nicht zutreffend Nicht festgelegt

    Daten vorbereiten

    Sie müssen das Eingabebild oder den Eingaberahmen in ein MPImage-Objekt konvertieren, bevor Sie es an die Gestenerkennung übergeben. MPImage unterstützt verschiedene Arten von iOS-Bildformaten und kann in jedem Ausführungsmodus für die Inferenz verwendet werden. Weitere Informationen zu MPImage finden Sie in der MPImage API.

    Wählen Sie ein iOS-Bildformat basierend auf Ihrem Anwendungsfall und dem Ausführungsmodus Ihrer Anwendung aus.MPImage akzeptiert die iOS-Bildformate UIImage, CVPixelBuffer und CMSampleBuffer.

    UIImage

    Das Format UIImage eignet sich gut für die folgenden Ausführungsmodi:

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

    • Videos: Extrahieren Sie Videoframes mit AVAssetImageGenerator in das CGImage und konvertieren Sie sie dann in UIImage-Bilder.

    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 ein MPImage mit der Standardausrichtung UIImage.Orientation.Up initialisiert. Sie können ein MPImage mit jedem der unterstützten UIImage.Orientation-Werte initialisieren. Die Bewegungserkennung unterstützt keine gespiegelten Ausrichtungen wie .upMirrored, .downMirrored, .leftMirrored, .rightMirrored.

    Weitere Informationen zu UIImage finden Sie in der Apple-Entwicklerdokumentation UIImage.

    CVPixelBuffer

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

    Das Format CVPixelBuffer eignet sich gut für die folgenden Ausführungsmodi:

    • Bilder: Apps, die nach einiger Verarbeitung CVPixelBuffer-Bilder mit dem CoreImage-Framework von iOS generieren, können im Bildausführungsmodus an die Gestenerkennung gesendet werden.

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

    • Livestream: Apps, bei denen Frames mit einer iOS-Kamera erstellt werden, können zur Verarbeitung in das CVPixelBuffer-Format konvertiert werden, bevor sie im Livestream-Modus an die Bewegungserkennung 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.

    CMSampleBuffer

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

    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 finden Sie in der Entwicklerdokumentation zu CMSampleBuffer von Apple.

    Task ausführen

    Verwenden Sie zum Ausführen der Bewegungserkennung die Methode recognize(), die für den zugewiesenen Ausführungsmodus spezifisch ist:

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

    Die folgenden Codebeispiele enthalten grundlegende Beispiele dafür, wie die Gestenerkennung in den verschiedenen Ausführungsmodi ausgeführt wird:

    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 können Nutzer zwischen den Verarbeitungsmodi wechseln, die für Ihren Anwendungsfall möglicherweise nicht erforderlich sind.

    Wichtige Hinweise:

    • Im Video- oder Livestream-Modus müssen Sie auch den Zeitstempel des Eingabeframes für die Aufgabe zur Gestenerkennung bereitstellen.

    • Im Bild- oder Videomodus blockiert die Aufgabe zur Bewegungserkennung den aktuellen Thread, bis die Verarbeitung des Eingabebilds oder -frames abgeschlossen ist. Damit der aktuelle Thread nicht blockiert wird, führen Sie die Verarbeitung mithilfe von iOS Dispatch- oder NSOperation-Frameworks in einem Hintergrundthread aus.

    • Im Livestream-Modus wird die Aufgabe zur Bewegungserkennung sofort zurückgegeben und der aktuelle Thread nicht blockiert. Nach der Verarbeitung jedes Eingabe-Frames wird die Methode gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:) mit dem Ergebnis der Bewegungserkennung aufgerufen. Die Bewegungserkennung ruft diese Methode in einer dedizierten seriellen Weiterleitungswarteschlange asynchron auf. Damit Ergebnisse auf der Benutzeroberfläche angezeigt werden, müssen Sie die Ergebnisse nach der Verarbeitung der Ergebnisse an die Hauptwarteschlange weiterleiten. Wenn die Funktion recognizeAsync aufgerufen wird, während die Aufgabe zur Gestenerkennung damit beschäftigt ist, einen weiteren Frame zu verarbeiten, wird der neue Eingabeframe von der Gestenerkennung ignoriert.

    Ergebnisse verarbeiten und anzeigen

    Beim Ausführen der Inferenz gibt die Aufgabe „Gestenerkennung“ eine GestureRecognizerResult zurück, die Handmarkierungen in Bildkoordinaten, Handmarkierungen in Weltkoordinaten, Händigkeit(links/rechts) und Handgestenkategorien der erkannten Hände enthält.

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

    Das Ergebnis-GestureRecognizerResult enthält vier Komponenten, wobei jede Komponente ein Array ist, in dem jedes Element das erkannte Ergebnis einer einzelnen erkannten Hand enthält.

    • Händigkeit

      Die Händigkeit gibt an, ob die erkannten Hände Links- oder Rechtshänder sind.

    • Gesten

      Die erkannten Gestenkategorien der erkannten Hände.

    • Landmarken

      Es gibt 21 Landschaftsmarkierungen, die jeweils aus x-, y- und z-Koordinaten bestehen. Die Koordinaten x und y werden entsprechend der Bildbreite bzw. -höhe auf [0,0, 1,0] normalisiert. Die z-Koordinate stellt die Tiefe der Sehenswürdigkeit dar, wobei die Tiefe am Handgelenk als Ausgangspunkt dient. Je kleiner der Wert, desto näher liegt das Denkmal an der Kamera. Die Größe von z wird ungefähr gleich groß wie bei x verwendet.

    • Sehenswürdigkeiten der Welt

      Die 21 Sehenswürdigkeiten sind ebenfalls in Weltkoordinaten dargestellt. Jede Sehenswürdigkeit besteht aus x, y und z. Diese stellen reale 3D-Koordinaten in Metern mit dem Ursprung im geometrischen Mittelpunkt des Hand dar.

    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: