Handbuch zur Erkennung von Handmarkierungen für iOS

Mit der MediaPipe-Aufgabe „Hand Landmarker“ können Sie die Markierungen der Hände in einem Bild erkennen. In dieser Anleitung erfahren Sie, wie Sie den Landmarker „Hand“ mit iOS-Apps verwenden. Der in dieser Anleitung beschriebene Code ist auf GitHub verfügbar.

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 App für iOS mit Landmarker-Funktionen für Hände. Im Beispiel wird die Kamera eines iOS-Geräts verwendet, um in einem kontinuierlichen Videostream Handmerkmale zu erkennen. Die App kann auch Handmarkierungen in Bildern und Videos aus der Gerätegalerie erkennen.

Sie können die App als Ausgangspunkt für Ihre eigene iOS-App verwenden oder sich an ihr orientieren, wenn Sie eine vorhandene App ändern. Der Beispielcode für die Landmarker-Funktion für Hände 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 „Hand Landmarker“ vorhanden sind:

    cd mediapipe-samples
    git sparse-checkout init --cone
    git sparse-checkout set examples/hand_landmarker/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 „Hand Landmarker“:

  • HandLandmarkerService.swift: Initialisiert den Hand-Landmarker, verarbeitet die Modellauswahl und führt Inferenzen auf den Eingabedaten aus.
  • CameraViewController.swift: Implementiert die Benutzeroberfläche für den Eingabemodus des Live-Kamerafeeds und visualisiert die Ergebnisse.
  • MediaLibraryViewController.swift: Implementiert die Benutzeroberfläche für den Eingabemodus für Standbilder und Videodateien und visualisiert die Ergebnisse.

Einrichtung

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

Abhängigkeiten

Für „Hand Landmarker“ wird die MediaPipeTasksVision-Bibliothek verwendet, 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 zum Installieren von CocoaPods unter macOS findest du in der Installationsanleitung für CocoaPods. 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 'MyHandLandmarkerApp' 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-Aufgabe „Hand Landmarker“ ist ein trainiertes Modell erforderlich, das mit dieser Aufgabe kompatibel ist. Weitere Informationen zu den verfügbaren trainierten Modellen für die Funktion „Hand Landmarker“ 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 die Property 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 „Hand Landmarker“ erstellen, indem Sie einen ihrer Initializer aufrufen. Der HandLandmarker(options:)-Initialisierer akzeptiert Werte für die Konfigurationsoptionen.

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

Die Aufgabe „Landmark-Erkennung für Hände“ unterstützt drei Eingabedatentypen: Standbilder, Videodateien und Livestreams. Standardmäßig initialisiert HandLandmarker(modelPath:) eine Aufgabe für Standbilder. Wenn Sie möchten, dass Ihre Aufgabe für die Verarbeitung von Videodateien oder Live-Videostreams initialisiert wird, geben Sie mit HandLandmarker(options:) den Ausführungsmodus für Video oder Livestream an. Für den Livestream-Modus ist außerdem die zusätzliche Konfigurationsoption handLandmarkerLiveStreamDelegate erforderlich, mit der der Hand-Landmark-Detektor die Ergebnisse asynchron an den delegierten Dienst 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

import MediaPipeTasksVision

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

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

let handLandmarker = try HandLandmarker(options: options)
    
import MediaPipeTasksVision

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

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

let handLandmarker = try HandLandmarker(options: options)
    
import MediaPipeTasksVision

// Class that conforms to the `HandLandmarkerLiveStreamDelegate` protocol and
// implements the method that the hand landmarker calls once it finishes
// performing landmarks detection in each input frame.
class HandLandmarkerResultProcessor: NSObject, HandLandmarkerLiveStreamDelegate {

  func handLandmarker(
    _ handLandmarker: HandLandmarker,
    didFinishDetection result: HandLandmarkerResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the hand landmarker result or errors here.

  }
}

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

let options = HandLandmarkerOptions()
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 `handLandmarkerLiveStreamDelegate`
// property.
let processor = HandLandmarkerResultProcessor()
options.handLandmarkerLiveStreamDelegate = processor

let handLandmarker = try HandLandmarker(options: options)
    

Objective-C

@import MediaPipeTasksVision;

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

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

MPPHandLandmarker *handLandmarker =
  [[MPPHandLandmarker alloc] initWithOptions:options error:nil];
    
@import MediaPipeTasksVision;

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

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

MPPHandLandmarker *handLandmarker =
  [[MPPHandLandmarker alloc] initWithOptions:options error:nil];
    
@import MediaPipeTasksVision;

// Class that conforms to the `MPPHandLandmarkerLiveStreamDelegate` protocol
// and implements the method that the hand landmarker calls once it finishes
// performing landmarks detection in each input frame.

@interface APPHandLandmarkerResultProcessor : NSObject 

@end

@implementation APPHandLandmarkerResultProcessor

-   (void)handLandmarker:(MPPHandLandmarker *)handLandmarker
    didFinishDetectionWithResult:(MPPHandLandmarkerResult *)handLandmarkerResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the hand landmarker result or errors here.

}

@end

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

MPPHandLandmarkerOptions *options = [[MPPHandLandmarkerOptions 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 `handLandmarkerLiveStreamDelegate`
// property.
APPHandLandmarkerResultProcessor *processor =
  [APPHandLandmarkerResultProcessor new];
options.handLandmarkerLiveStreamDelegate = processor;

MPPHandLandmarker *handLandmarker =
  [[MPPHandLandmarker 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
running_mode 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 handLandmarkerLiveStreamDelegate auf eine Instanz einer Klasse festgelegt sein, die HandLandmarkerLiveStreamDelegate implementiert, um die Ergebnisse der Erkennung von Handmarkierungen asynchron zu empfangen.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
numHands Die maximale Anzahl von Händen, die vom Landmark-Detektor für Hände erkannt werden. Any integer > 0 1
minHandDetectionConfidence Die Mindestpunktzahl für die Handerkennung, die im Modell für die Handflächenerkennung als erfolgreich gilt. 0.0 - 1.0 0.5
minHandPresenceConfidence Der Mindestwert für die Konfidenz der Anwesenheit der Hand im Modell zur Erkennung von Handmarkierungen. Wenn im Video- und Livestream-Modus der Konfidenzwert für die Präsenz von Händen aus dem Modell für Handmarkierungen unter diesem Grenzwert liegt, löst der Hand-Landmarker das Modell zur Handflächenerkennung aus. Andernfalls bestimmt ein einfacher Algorithmus für die Handerkennung die Position der Hand(en) für die nachfolgenden Markierungserkennungen. 0.0 - 1.0 0.5
minTrackingConfidence Der Mindestwert für die Konfidenz, damit die Handerkennung als erfolgreich gilt. Dies ist der IoU-Grenzwert des Begrenzungsrahmens zwischen den Händen im aktuellen und im letzten Frame. Wenn das Tracking im Video- und Streammodus von „Hand Landmarker“ fehlschlägt, löst „Hand Landmarker“ die Handerkennung aus. Andernfalls wird die Handerkennung übersprungen. 0.0 - 1.0 0.5
result_listener Legt fest, dass der Ergebnisempfänger die Erkennungsergebnisse asynchron empfängt, wenn sich die Landmarker für Hände im Livestream-Modus befinden. Nur anwendbar, wenn der Ausführungsmodus auf LIVE_STREAM gesetzt ist

Wenn der Ausführungsmodus auf „Livestream“ festgelegt ist, benötigt der Landmarker für Hände die zusätzliche Konfigurationsoption handLandmarkerLiveStreamDelegate. Damit kann der Landmarker für Hände die Ergebnisse der Erkennung von Handmarkierungen asynchron liefern. Der Delegate muss die Methode handLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) implementieren, die vom Hand-Landmarker aufgerufen wird, nachdem die Ergebnisse der Erkennung von Handmarkierungen für jeden Frame verarbeitet wurden.

Optionsname Beschreibung Wertebereich Standardwert
handLandmarkerLiveStreamDelegate Ermöglicht es dem Tool „Markierungen für Hände“, die Ergebnisse der Markierungserkennung für Hände im Livestream-Modus asynchron zu empfangen. Die Klasse, deren Instanz auf diese Property festgelegt ist, muss die Methode handLandmarker(_:didFinishDetection: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 Landmarker für Hände ü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 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-Bild 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.

// 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)
    
// 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 ein MPImage mit einem beliebigen der unterstützten Werte von UIImage.Orientation initialisieren. Der Hand-Landmarker unterstützt keine gespiegelten Ausrichtungen wie .upMirrored, .downMirrored, .leftMirrored oder .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-Framework CoreImage zur 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 den Hand Landmarker gesendet werden.

  • Videos: Videoframes können zur Verarbeitung in das CVPixelBuffer-Format konvertiert und dann im Videomodus an den Landmarker für Hände gesendet werden.

  • Livestream: Frames, die von Apps mit einer iOS-Kamera generiert werden, können zur Verarbeitung in das CVPixelBuffer-Format konvertiert werden, bevor sie im Livestream-Modus an den Landmarker für Hände gesendet werden.

// 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)
    
// 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.

// 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)
    
// 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 Landmarkers für die Hand die detect()-Methode, die dem zugewiesenen Ausführungsmodus entspricht:

  • Standbild: detect(image:)
  • Video: detect(videoFrame:timestampInMilliseconds:)
  • Livestream: detectAsync(image:timestampInMilliseconds:)

Swift

let result = try handLandmarker.detect(image: image)
    
let result = try handLandmarker.detect(
    videoFrame: image,
    timestampInMilliseconds: timestamp)
    
try handLandmarker.detectAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

MPPHandLandmarkerResult *result =
  [handLandmarker detectInImage:image error:nil];
    
MPPHandLandmarkerResult *result =
  [handLandmarker detectInVideoFrame:image
             timestampInMilliseconds:timestamp
                               error:nil];
    
BOOL success =
  [handLandmarker detectAsyncInImage:image
             timestampInMilliseconds:timestamp
                               error:nil];
    

Im Codebeispiel für die Landmark-Erkennung für Hände werden die Implementierungen der einzelnen Modi ausführlicher beschrieben. Im Beispielcode kann der Nutzer zwischen Verarbeitungsmodi wechseln, was für Ihren Anwendungsfall möglicherweise nicht erforderlich ist.

Wichtige Hinweise:

  • Wenn Sie die Funktion im Video- oder Livestream-Modus ausführen, müssen Sie der Aufgabe „Landmarker für Hände“ auch den Zeitstempel des Eingabeframes angeben.

  • Wenn die Funktion im Bild- oder Videomodus ausgeführt wird, blockiert die Aufgabe „Hand Landmarker“ den aktuellen Thread, bis die Verarbeitung des Eingabebilds oder ‑frames abgeschlossen ist. Um das Blockieren des aktuellen Threads zu vermeiden, führen Sie die Verarbeitung in einem Hintergrund-Thread mithilfe der iOS-Frameworks Dispatch oder NSOperation aus.

  • Wenn die Ausführung im Livestream-Modus erfolgt, gibt die Aufgabe „Hand Landmarker“ sofort ein Ergebnis zurück und blockiert den aktuellen Thread nicht. Nach der Verarbeitung jedes Eingabeframes wird die Methode handLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) mit dem Ergebnis der Landmarker-Erkennung für die Hand aufgerufen. Der Hand-Markierungstool ruft diese Methode asynchron in einer speziellen seriellen Dispatch-Warteschlange auf. Wenn Sie die Ergebnisse auf der Benutzeroberfläche anzeigen möchten, senden Sie sie nach der Verarbeitung an die Hauptwarteschlange. Wenn die detectAsync-Funktion aufgerufen wird, während die Hand Landmarker-Aufgabe gerade einen anderen Frame verarbeitet, ignoriert der Hand Landmarker den neuen Eingabeframe.

Ergebnisse verarbeiten und anzeigen

Nach der Ausführung der Inference gibt die Aufgabe „Hand Landmarker“ eine HandLandmarkerResult zurück, die Handmarkierungen in Bildkoordinaten, Handmarkierungen in Weltkoordinaten und die Händigkeit(links/rechts) der erkannten Hände enthält.

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

Die HandLandmarkerResult-Ausgabe enthält drei Komponenten. Jede Komponente ist ein Array, wobei jedes Element die folgenden Ergebnisse für eine einzelne erkannte Hand enthält:

  • Links-/Rechtshänder

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

  • 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 Landmarken für die Hand werden ebenfalls in Weltkoordinaten dargestellt. Jedes Landmark besteht aus x, y und z, die 3D-Koordinaten in Metern mit dem Ursprung im geometrischen Mittelpunkt der Hand darstellen.

HandLandmarkerResult:
  Handedness:
    Categories #0:
      index        : 0
      score        : 0.98396
      categoryName : Left
  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 folgende Abbildung zeigt eine Visualisierung der Aufgabenausgabe:

Eine Hand, die einen Daumen nach oben streckt, mit der Skelettstruktur der Hand