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:
Klonen Sie das Git-Repository mit dem folgenden Befehl:
git clone https://github.com/google-ai-edge/mediapipe-samples
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:
- GestureRecognizerService.swift: Initialisiert die Gestenerkennung, verarbeitet die Modellauswahl und führt eine Inferenz für die Eingabedaten aus.
- CameraViewController.swift: Implementiert die UI für den Eingabemodus des Live-Kamerafeeds und visualisiert die Ergebnisse.
- MediaLibraryViewController.swift: Implementiert die UI für den Eingabemodus für Standbilder und Videodateien und visualisiert die Ergebnisse.
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"] |
|
|
|
custom_gestures_classifier_options |
Optionen zum Konfigurieren des Verhaltens des benutzerdefinierten Gestenklassifikators. |
|
|
|
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 einMPImage
-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 demCoreImage
-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 FunktionrecognizeAsync
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
- undz
-Koordinaten bestehen. Die Koordinatenx
undy
werden entsprechend der Bildbreite bzw. -höhe auf [0,0, 1,0] normalisiert. Diez
-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 vonz
wird ungefähr gleich groß wie beix
verwendet.Sehenswürdigkeiten der Welt
Die 21 Sehenswürdigkeiten sind ebenfalls in Weltkoordinaten dargestellt. Jede Sehenswürdigkeit besteht aus
x
,y
undz
. 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: