L'attività Riconoscimento dei gesti di MediaPipe ti consente di riconoscere i gesti delle mani in tempo reale e fornisce i risultati dei gesti della mano riconosciuti e i punti di riferimento delle mani rilevate. Queste istruzioni ti mostrano come usare il riconoscimento dei gesti con le app per iOS.
Puoi vedere questa attività in azione visualizzando la demo web. Per ulteriori informazioni sulle funzionalità, sui modelli e sulle opzioni di configurazione di questa attività, consulta la Panoramica.
Esempio di codice
Il codice di esempio di MediaPipe Tasks è un'implementazione di base di un'app di riconoscimento gesti per iOS. L'esempio utilizza la fotocamera di un dispositivo iOS fisico per rilevare in modo continuo i gesti delle mani e può utilizzare anche immagini e video della galleria del dispositivo per rilevare in modo statico i gesti.
Puoi utilizzare l'app come punto di partenza per la tua app per iOS o farvi riferimento quando modifichi un'app esistente. Il codice di esempio del riconoscimento gesti è ospitato su GitHub.
Scarica il codice
Le seguenti istruzioni mostrano come creare una copia locale del codice di esempio utilizzando lo strumento a riga di comando git.
Per scaricare il codice di esempio:
Clona il repository git utilizzando il seguente comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
Facoltativamente, configura la tua istanza Git in modo da utilizzare il pagamento sparse, in modo da avere solo i file dell'app di esempio del riconoscimento gesti:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/gesture_recognizer/ios/
Dopo aver creato una versione locale del codice di esempio, puoi installare la libreria di attività MediaPipe, aprire il progetto utilizzando Xcode ed eseguire l'app. Per istruzioni, consulta la Guida alla configurazione per iOS.
Componenti chiave
I seguenti file contengono il codice fondamentale per l'applicazione di esempio del riconoscimento Gesti:
- GestureRecognizerService.swift: inizializza il riconoscimento gesti, gestisce la selezione del modello ed esegue l'inferenza sui dati di input.
- CameraViewController.swift: implementa l'UI per la modalità di inserimento del feed della videocamera in diretta e visualizza i risultati.
- MediaLibraryViewController.swift: implementa l'interfaccia utente per la modalità di input di immagini fisse e video e visualizza i risultati.
Configurazione
In questa sezione vengono descritti i passaggi chiave per configurare l'ambiente di sviluppo e codificare i progetti per l'utilizzo del riconoscimento gesti. Per informazioni generali sulla configurazione dell'ambiente di sviluppo per l'utilizzo delle attività MediaPipe, inclusi i requisiti di versione della piattaforma, consulta la Guida alla configurazione per iOS.
Dipendenze
Il riconoscimento gesti utilizza la libreria MediaPipeTasksVision
, che deve essere installata
utilizzando CocoaPods. La libreria è compatibile con le app Swift e Objective-C e non richiede alcuna configurazione aggiuntiva specifica per la lingua.
Per istruzioni su come installare CocoaPods su macOS, consulta la guida all'installazione di CocoaPods.
Per istruzioni su come creare un Podfile
con i pod necessari per la tua
app, consulta la sezione Utilizzare
CocoaPods.
Aggiungi il pod MediaPipeTasksVision in Podfile
utilizzando il seguente codice:
target 'MyGestureRecognizerApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
Se la tua app include target per il test delle unità, consulta la Guida alla configurazione per iOS per ulteriori informazioni sulla configurazione di Podfile
.
Modello
L'attività Riconoscimento gesti MediaPipe richiede un modello addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per il riconoscimento dei gesti, consulta la sezione Modelli della panoramica delle attività.
Seleziona e scarica un modello, quindi aggiungilo alla directory del progetto utilizzando Xcode. Per istruzioni su come aggiungere file al progetto Xcode, consulta Gestione di file e cartelle nel progetto Xcode.
Utilizza la proprietà BaseOptions.modelAssetPath
per specificare il percorso del modello
nel tuo app bundle. Per un esempio di codice, consulta la sezione successiva.
Creare l'attività
Puoi creare l'attività di riconoscimento gesti chiamando uno dei suoi inizializzatori. L'inizializzazione GestureRecognizer(options:)
accetta valori per le opzioni di configurazione.
Se non hai bisogno di un riconoscimento dei gesti inizializzato con opzioni di configurazione personalizzate, puoi usare l'inizializzazione GestureRecognizer(modelPath:)
per crearne uno con le opzioni predefinite. Per ulteriori informazioni sulle opzioni di configurazione, consulta Panoramica della configurazione.
L'attività Riconoscimento gesti supporta tre tipi di dati di input: immagini fisse, file video e stream video in diretta. Per impostazione predefinita, GestureRecognizer(modelPath:)
inizializza
un'attività per le immagini statiche. Se vuoi che l'attività venga inizializzata allo scopo di elaborare file video o stream video in diretta, utilizza GestureRecognizer(options:)
per specificare la modalità di esecuzione del video o del live streaming. La modalità live streaming richiede anche
l'opzione di configurazione gestureRecognizerLiveStreamDelegate
aggiuntiva, che
consente al riconoscimento gesti di inviare i risultati del riconoscimento dei gesti al delegato
in modo asincrono.
Scegli la scheda corrispondente alla modalità di corsa per vedere come creare l'attività ed eseguire l'inferenza.
Swift
Immagine
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)
Live streaming
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
Immagine
@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];
Live streaming
@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];
Opzioni di configurazione
Questa attività prevede le seguenti opzioni di configurazione per le app per iOS:
Nome opzione | Descrizione | Intervallo di valori | Valore predefinito | |
---|---|---|---|---|
runningMode |
Imposta la modalità di esecuzione per l'attività. Esistono tre
modalità: IMAGE: la modalità per gli input di singole immagini. VIDEO: la modalità per i fotogrammi decodificati di un video. LIVE_STREAM: la modalità per un live streaming di dati di input, ad esempio da una videocamera. In questa modalità, resultListener deve essere chiamato per configurare un listener per ricevere i risultati in modo asincrono. In questa modalità, gestureRecognizerLiveStreamDelegate deve essere impostato su un'istanza di una classe che implementa GestureRecognizerLiveStreamDelegate per ricevere i risultati dell'esecuzione del riconoscimento dei gesti in modo asincrono.
|
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
|
num_hands |
Il numero massimo di mani può essere rilevato dall'GestureRecognizer .
|
Any integer > 0 |
1 |
|
min_hand_detection_confidence |
Il punteggio di affidabilità minimo affinché il rilevamento della mano venga considerato efficace nel modello di rilevamento del palmo. | 0.0 - 1.0 |
0.5 |
|
min_hand_presence_confidence |
Il punteggio di affidabilità minimo del punteggio della presenza di persone nel modello di rilevamento dei punti di riferimento della mano. In modalità Video e in live streaming del Riconoscimento gesti, se il punteggio di sicurezza della presenza della mano del modello del punto di riferimento della mano è inferiore a questa soglia, viene attivato il modello di rilevamento del palmo. Altrimenti, viene utilizzato un algoritmo di tracciamento della mano leggero per determinare la posizione delle lancette e del successivo rilevamento dei punti di riferimento. | 0.0 - 1.0 |
0.5 |
|
min_tracking_confidence |
Il punteggio di affidabilità minimo affinché la registrazione della mano venga considerata riuscita. Si tratta della soglia IoU del riquadro di delimitazione tra le mani nel frame corrente e nell'ultimo frame. In modalità Video e in modalità stream del Riconoscimento di gesti, se il rilevamento non va a buon fine, quest'ultimo attiva il rilevamento delle mani. In caso contrario, il rilevamento della mano viene ignorato. | 0.0 - 1.0 |
0.5 |
|
canned_gestures_classifier_options |
Opzioni per configurare il comportamento predefinito del classificatore di gesti. I gesti predefiniti sono ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"] |
|
|
|
custom_gestures_classifier_options |
Opzioni per configurare il comportamento del classificatore di gesti personalizzati. |
|
|
|
result_listener |
Imposta il listener dei risultati per ricevere i risultati della classificazione in modo asincrono quando il riconoscimento dei gesti è in modalità live streaming.
Può essere utilizzato solo quando la modalità di esecuzione è impostata su LIVE_STREAM |
ResultListener |
N/A | N/A |
Quando la modalità di corsa è impostata su live streaming, il riconoscimento gesti richiede
l'opzione di configurazione gestureRecognizerLiveStreamDelegate
aggiuntiva, che consente
a quest'ultimo di fornire risultati di riconoscimento dei gesti in modo asincrono.
Il delegato deve implementare il metodo gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:)
, che il Riconoscimento gesti chiama dopo l'elaborazione dei risultati dell'esecuzione del riconoscimento dei gesti su ogni frame.
Nome opzione | Descrizione | Intervallo di valori | Valore predefinito |
---|---|---|---|
gestureRecognizerLiveStreamDelegate |
Consente al riconoscimento gesti di ricevere i risultati del riconoscimento dei gesti in modo asincrono in modalità live streaming. La classe la cui istanza è impostata su questa proprietà deve implementare il metodo gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:) . |
Non applicabile | Non impostata |
Preparazione dei dati
Devi convertire l'immagine o il frame di input in un oggetto MPImage
prima di passarlo al Riconoscimento gesti. MPImage
supporta diversi tipi di formati delle immagini per iOS e può utilizzarli in qualsiasi modalità di esecuzione per l'inferenza. Per ulteriori informazioni su MPImage
, consulta la pagina relativa all'API MPImage
Scegli il formato dell'immagine per iOS in base al tuo caso d'uso e alla modalità di esecuzione richiesta dalla tua applicazione.MPImage
accetta i formati di immagine per iOS UIImage
, CVPixelBuffer
e CMSampleBuffer
.
UIImage
Il formato UIImage
è adatto per le seguenti modalità di corsa:
Immagini: le immagini di un app bundle, di una galleria utente o di un file system formattate come
UIImage
immagini possono essere convertite in un oggettoMPImage
.Video: utilizza AVAssetImageGenerator per estrarre fotogrammi video nel formato CGImage, quindi convertili in
UIImage
immagini.
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];
L'esempio inizializza un elemento MPImage
con l'orientamento predefinito UIImage.Orientation.Up. Puoi inizializzare un elemento MPImage
con uno qualsiasi dei valori supportati per
UIImage.Orientation. Il riconoscimento gesti non supporta orientamenti speculari come .upMirrored
,
.downMirrored
, .leftMirrored
e .rightMirrored
.
Per ulteriori informazioni su UIImage
, consulta la documentazione per gli sviluppatori di Apple nell'interfaccia UI.
CVPixelBuffer
Il formato CVPixelBuffer
è ideale per le applicazioni che generano frame e utilizzano il framework CoreImage di iOS per l'elaborazione.
Il formato CVPixelBuffer
è adatto per le seguenti modalità di corsa:
Immagini: le app che generano immagini
CVPixelBuffer
dopo alcune elaborazioni utilizzando il frameworkCoreImage
di iOS possono essere inviate al riconoscimento gesti in modalità di esecuzione delle immagini.Video: i fotogrammi video possono essere convertiti nel formato
CVPixelBuffer
per l'elaborazione e poi inviati al riconoscimento gesti in modalità video.live streaming: le app che utilizzano una fotocamera iOS per generare frame possono essere convertite nel formato
CVPixelBuffer
per l'elaborazione prima di essere inviate al Riconoscimento gesti in modalità live streaming.
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];
Per ulteriori informazioni su CVPixelBuffer
, consulta la documentazione per gli sviluppatori di Apple CVPixelBuffer.
CMSampleBuffer
Il formato CMSampleBuffer
archivia esempi di contenuti multimediali di un tipo di media uniforme ed è
adatto per la modalità di esecuzione live streaming. I fotogrammi in tempo reale delle fotocamere iOS vengono
inviati in modo asincrono nel formato CMSampleBuffer
da iOS
AVCaptureVideoDataOutput.
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];
Per maggiori informazioni su CMSampleBuffer
, consulta la documentazione per gli sviluppatori Apple CMSampleBuffer.
Esegui l'attività
Per eseguire il riconoscimento gesti, usa il metodo recognize()
specifico per la modalità di esecuzione assegnata:
- Immagine statica:
recognize(image:)
- Video:
recognize(videoFrame:timestampInMilliseconds:)
- Live streaming:
recognizeAsync(image:timestampInMilliseconds:)
I seguenti esempi di codice mostrano esempi di base di come eseguire il riconoscimento gesti in queste diverse modalità di esecuzione:
Swift
Immagine
let result = try gestureRecognizer.recognize(image: image)
Video
let result = try gestureRecognizer.recognize( videoFrame: image, timestampInMilliseconds: timestamp)
Live streaming
try gestureRecognizer.recognizeAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
Immagine
MPPGestureRecognizerResult *result = [gestureRecognizer recognizeImage:mppImage error:nil];
Video
MPPGestureRecognizerResult *result = [gestureRecognizer recognizeVideoFrame:image timestampInMilliseconds:timestamp error:nil];
Live streaming
BOOL success = [gestureRecognizer recognizeAsyncImage:image timestampInMilliseconds:timestamp error:nil];
Il codice di esempio consente all'utente di passare da una modalità di elaborazione all'altra, il che potrebbe non essere necessario per il tuo caso d'uso.
Tieni presente quanto riportato di seguito:
Quando l'app è in modalità video o live streaming, devi anche fornire il timestamp del frame di input all'attività Riconoscimento gesti.
Quando viene eseguita in modalità immagine o video, l'attività Riconoscimento gesti blocca il thread corrente finché non completa l'elaborazione dell'immagine o del frame di input. Per evitare di bloccare il thread corrente, esegui l'elaborazione in un thread in background utilizzando i framework per iOS Dispatch o NSOperation.
In esecuzione in modalità live streaming, l'attività di riconoscimento gesti viene restituita immediatamente e non blocca il thread corrente. Richiama il metodo
gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:)
con il risultato del riconoscimento dei gesti dopo l'elaborazione di ogni frame di input. Il riconoscimento gesti richiama questo metodo in modo asincrono su una coda di invio di serie dedicata. Per visualizzare i risultati nell'interfaccia utente, inviali alla coda principale dopo l'elaborazione dei risultati. Se la funzionerecognizeAsync
viene richiamata quando l'attività Riconoscimento gesti è impegnata a elaborare un altro frame, il riconoscimento gesti ignora il nuovo frame di input.
Gestire e visualizzare i risultati
Dopo l'esecuzione dell'inferenza, l'attività Riconoscimento gesti restituisce un
GestureRecognizerResult
che contiene punti di riferimento della mano nelle coordinate dell'immagine,
punti di riferimento della mano nelle coordinate mondiali, mano(mano sinistra/destra) e mano
gestisce le categorie delle mani rilevate.
Di seguito è riportato un esempio dei dati di output di questa attività:
Il risultato GestureRecognizerResult
contiene quattro componenti e ogni componente è un array in cui ogni elemento contiene il risultato rilevato di una singola mano rilevata.
Mano dominante
La mano indica se la mano viene rilevata sia destra che sinistra.
Gesti
Le categorie di gesti riconosciuti delle mani rilevate.
Punti di riferimento
Ci sono 21 punti di riferimento della mano, ciascuno composto dalle coordinate
x
,y
ez
. Le coordinatex
ey
sono normalizzate su [0,0, 1,0] rispettivamente in base alla larghezza e all'altezza dell'immagine. La coordinataz
rappresenta la profondità del punto di riferimento, dove la profondità al polso è l'origine. Più basso è il valore, più il punto di riferimento è vicino alla fotocamera. La grandezza diz
utilizza approssimativamente la stessa scala dix
.Punti di riferimento mondiali
I punti di riferimento a 21 mani sono presentati anche nelle coordinate mondiali. Ogni punto di riferimento è composto da
x
,y
ez
e rappresenta le coordinate 3D del mondo reale in metri con l'origine in corrispondenza del centro geometrico della mano.
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)
Le immagini seguenti mostrano una visualizzazione dell'output dell'attività: