Guida al rilevamento dei punti di riferimento in posa per iOS

L'attività Posa punto di riferimento consente di rilevare punti di riferimento di corpi umani in un'immagine o video. Puoi utilizzare questa attività per identificare le posizioni chiave del corpo, analizzare la postura, e classificare i movimenti. Questa attività utilizza modelli di machine learning (ML) che funzionano con singole immagini o video. L'attività restituisce le posizioni del corpo nell'immagine e in coordinate mondiali tridimensionali.

Queste istruzioni ti mostrano come utilizzare la posizione di riferimento con le app per iOS. Il codice descritto in queste istruzioni è disponibile su GitHub.

Puoi vedere questa attività in azione visualizzando questo Web una demo. Per ulteriori informazioni su funzionalità, modelli e opzioni di configurazione di questa attività, controlla Panoramica.

Esempio di codice

Il codice di esempio relativo alle attività di MediaPipe è un'implementazione di base di un programma di riferimento per posizioni per iOS. L'esempio utilizza la fotocamera su un dispositivo iOS fisico per rilevare rilevare le posizioni in un video stream continuo. L'app può anche rilevare le pose di immagini e video dalla galleria del dispositivo.

Puoi utilizzare l'app come punto di partenza per la tua app per iOS o fare riferimento all'app quando modifichi un'app esistente. Il codice di esempio di Pose Taper è ospitato su GitHub.

Scarica il codice

Le seguenti istruzioni mostrano come creare una copia locale dell'esempio utilizzando lo strumento a riga di comando git.

Per scaricare il codice di esempio:

  1. Clona il repository git utilizzando il comando seguente:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Facoltativamente, configura la tua istanza Git per l'utilizzo di un pagamento sparso, in modo da avere solo i file per l'app di esempio Pose Highlighter:

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

Dopo aver creato una versione locale del codice di esempio, puoi installare nella libreria di attività MediaPipe, apri il progetto con Xcode ed esegui l'app. Per istruzioni, vedi la Guida alla configurazione per iOS.

Componenti chiave

I file seguenti contengono il codice cruciale per l'esempio di POSA applicazione:

  • PoseLandmarkerService.swift: Inizializza lo strumento di riferimento, gestisce la selezione del modello ed esegue l'inferenza sui dati di input.
  • CameraViewController: Implementa l'interfaccia utente per la modalità di immissione del feed della videocamera in diretta e visualizza la punti di riferimento.
  • MediaLibraryViewController.swift: Implementa l'interfaccia utente per la modalità di immissione di file di immagini e video e che visualizza i punti di riferimento.

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e progetti di codice per usare Pose Highlighter. Per informazioni generali sulla configurazione dell'ambiente di sviluppo per l'uso di attività MediaPipe, inclusa la versione della piattaforma consulta la Guida alla configurazione per iOS.

Dipendenze

Punto di riferimento di posa utilizza la libreria MediaPipeTasksVision, che deve essere installata utilizzando CocoaPods. La raccolta è 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 l'articolo CocoaPods Guida all'installazione. Per istruzioni su come creare un elemento Podfile con i pod necessari per il tuo consulta la sezione Utilizzo CocoaPods.

Aggiungi il pod MediaPipeTasksVision in Podfile utilizzando il seguente codice:

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

Se la tua app include target dei test delle unità, consulta la Guida alla configurazione per iOS per ulteriori informazioni sulla configurazione il tuo Podfile.

Modello

L'attività Punto di riferimento di MediaPipe richiede un bundle addestrato che sia compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per Pose punto di riferimento, consulta la panoramica dell'attività Modelli .

Utilizza la download_models.sh copione per scaricare i modelli e aggiungerli alla directory del progetto utilizzando Xcode. Per istruzioni su come aggiungere file al progetto Xcode, consulta Gestire i file e cartelle in Xcode progetto.

Utilizza la proprietà BaseOptions.modelAssetPath per specificare il percorso del modello nel tuo app bundle. Per un esempio di codice, consulta la sezione successiva.

Crea l'attività

Puoi creare l'attività Pose Taper richiamando uno dei suoi inizializzatori. La L'inizializzazione di PoseLandmarker(options:) accetta valori per la configurazione le opzioni di CPU e memoria disponibili.

Se non hai bisogno di un POS Pose Highlighter inizializzato con una configurazione personalizzata puoi usare l'inizializzatore PoseLandmarker(modelPath:) per creare Posa punto di riferimento con le opzioni predefinite. Per ulteriori informazioni sulla configurazione vedi Panoramica della configurazione.

L'attività Punti di riferimento per posizioni supporta tre tipi di dati di input: immagini fisse, file video e video stream in diretta. Per impostazione predefinita, PoseLandmarker(modelPath:) inizializza una per le immagini statiche. Se vuoi che l'attività venga inizializzata per elaborare il video file o stream video in diretta, usa PoseLandmarker(options:) per specificare il video modalità di corsa o live streaming. La modalità live streaming richiede anche di configurazione di poseLandmarkerLiveStreamDelegate, che attiva Posa punto di riferimento per consegnare al delegato i risultati del rilevamento della posizione del punto di riferimento in modo asincrono.

Scegli la scheda corrispondente alla tua modalità di corsa per vedere come creare l'attività ed eseguire l'inferenza.

Swift

Immagine

import MediaPipeTasksVision

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

let options = PoseLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.minPoseDetectionConfidence = minPoseDetectionConfidence
options.minPosePresenceConfidence = minPosePresenceConfidence
options.minTrackingConfidence = minTrackingConfidence
options.numPoses = numPoses

let poseLandmarker = try PoseLandmarker(options: options)
    

Video

import MediaPipeTasksVision

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

let options = PoseLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.minPoseDetectionConfidence = minPoseDetectionConfidence
options.minPosePresenceConfidence = minPosePresenceConfidence
options.minTrackingConfidence = minTrackingConfidence
options.numPoses = numPoses

let poseLandmarker = try PoseLandmarker(options: options)
    

Live streaming

import MediaPipeTasksVision

// Class that conforms to the `PoseLandmarkerLiveStreamDelegate` protocol and
// implements the method that the pose landmarker calls once it finishes
// performing pose landmark detection in each input frame.
class PoseLandmarkerResultProcessor: NSObject, PoseLandmarkerLiveStreamDelegate {

  func poseLandmarker(
    _ poseLandmarker: PoseLandmarker,
    didFinishDetection result: PoseLandmarkerResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the pose landmarker result or errors here.

  }
}

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

let options = PoseLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.minPoseDetectionConfidence = minPoseDetectionConfidence
options.minPosePresenceConfidence = minPosePresenceConfidence
options.minTrackingConfidence = minTrackingConfidence
options.numPoses = numPoses

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

let poseLandmarker = try PoseLandmarker(options: options)
    

Objective-C

Immagine

@import MediaPipeTasksVision;

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

MPPPoseLandmarkerOptions *options = [[MPPPoseLandmarkerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.minPoseDetectionConfidence = minPoseDetectionConfidence;
options.minPosePresenceConfidence = minPosePresenceConfidence;
options.minTrackingConfidence = minTrackingConfidence;
options.numPoses = numPoses;

MPPPoseLandmarker *poseLandmarker =
  [[MPPPoseLandmarker alloc] initWithOptions:options error:nil];
    

Video

@import MediaPipeTasksVision;

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

MPPPoseLandmarkerOptions *options = [[MPPPoseLandmarkerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.minPoseDetectionConfidence = minPoseDetectionConfidence;
options.minPosePresenceConfidence = minPosePresenceConfidence;
options.minTrackingConfidence = minTrackingConfidence;
options.numPoses = numPoses;

MPPPoseLandmarker *poseLandmarker =
  [[MPPPoseLandmarker alloc] initWithOptions:options error:nil];
    

Live streaming

@import MediaPipeTasksVision;

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

@interface APPPoseLandmarkerResultProcessor : NSObject 

@end

@implementation APPPoseLandmarkerResultProcessor

-   (void)poseLandmarker:(MPPPoseLandmarker *)poseLandmarker
    didFinishDetectionWithResult:(MPPPoseLandmarkerResult *)poseLandmarkerResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the pose landmarker result or errors here.

}

@end

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

MPPPoseLandmarkerOptions *options = [[MPPPoseLandmarkerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.minPoseDetectionConfidence = minPoseDetectionConfidence;
options.minPosePresenceConfidence = minPosePresenceConfidence;
options.minTrackingConfidence = minTrackingConfidence;
options.numPoses = numPoses;

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

MPPPoseLandmarker *poseLandmarker =
  [[MPPPoseLandmarker alloc] initWithOptions:options error:nil];
    

Nota: se utilizzi la modalità video o live streaming, Pose Highlighter utilizza il monitoraggio della mano per evitare di attivare il modello di rilevamento del palmo su ogni frame, il che aiuta per ridurre la latenza.

Opzioni di configurazione

Questa attività include le seguenti opzioni di configurazione per le app per iOS:

Nome opzione Descrizione Intervallo di valori Valore predefinito
running_mode Imposta la modalità di esecuzione per l'attività. Esistono tre tipi di modalità:

IMAGE: la modalità per gli input di immagini singole.

VIDEO: la modalità per i fotogrammi decodificati di un video.

LIVE_STREAM: la modalità per un live streaming di input dati, ad esempio quelli di una videocamera. In questa modalità, è necessario impostare poseLandmarkerLiveStreamDelegate su un'istanza di una classe che implementa PoseLandmarkerLiveStreamDelegate per ricevere i risultati di rilevamento dei punti di riferimento delle posizioni in modo asincrono.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
num_poses Il numero massimo di pose che possono essere rilevate dal Punto di riferimento per la posa. Integer > 0 1
min_pose_detection_confidence Il punteggio di confidenza minimo per il rilevamento della posizione viene considerata riuscita. Float [0.0,1.0] 0.5
min_pose_presence_confidence Il punteggio di confidenza minimo della presenza della posa il punteggio nel rilevamento dei punti di riferimento della posizione. Float [0.0,1.0] 0.5
min_tracking_confidence Il punteggio di confidenza minimo per il monitoraggio della posizione per essere considerate efficaci. Float [0.0,1.0] 0.5
output_segmentation_masks Consente di stabilire se mostrare o meno una maschera di segmentazione per l'oggetto rilevato posa. Boolean False
result_callback Imposta il listener dei risultati per ricevere i risultati dei punti di riferimento in modo asincrono quando l'app Luogo di riferimento è in modalità live streaming. Può essere utilizzato solo quando la modalità di corsa è impostata su LIVE_STREAM ResultListener N/A

Configurazione del live streaming

Quando la modalità di corsa è impostata sul live streaming, il Pose Scoreer richiede un'opzione di configurazione poseLandmarkerLiveStreamDelegate aggiuntiva, consente a Pose Highlighter di fornire risultati di rilevamento dei punti di riferimento delle posa in modo asincrono. Il delegato deve implementare poseLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) metodo, che viene chiamato da Pose Taper dopo aver elaborato i risultati di una posa. il rilevamento dei punti di riferimento in ogni frame.

Nome opzione Descrizione Intervallo di valori Valore predefinito
poseLandmarkerLiveStreamDelegate Consente a Pose Scoreer di ricevere i risultati dell'esecuzione della posa il rilevamento dei punti di riferimento in modo asincrono in modalità live streaming. La classe è impostato su questa proprietà, deve implementare poseLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) . Non applicabile Non impostato

Preparazione dei dati

Devi convertire l'immagine o il frame di input in un oggetto MPImage prima e passarlo a Pose Taper. MPImage supporta diversi tipi di immagini iOS e possono utilizzarli in qualsiasi modalità di esecuzione per l'inferenza. Per ulteriori informazioni informazioni su MPImage, consulta le API MPImage

Scegli un formato dell'immagine iOS in base al tuo caso d'uso e alla modalità di corsa richiede l'applicazione.MPImage accetta UIImage, CVPixelBuffer e CMSampleBuffer formati dell'immagine per iOS.

UIImage

Il formato UIImage è adatto alle seguenti modalità di corsa:

  • Immagini: immagini da un app bundle, una galleria utente o un file system formattato come UIImage immagini possono essere convertite in un oggetto MPImage.

  • Video: utilizza AVAssetImageGenerator per estrarre i fotogrammi video 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 MPImage con il valore predefinito UIImage.Orientation.Up orientamento. Puoi inizializzare MPImage con uno qualsiasi dei UIImage.Orientation e i relativi valori. Pose Taper non supporta orientamenti speculari come .upMirrored, .downMirrored, .leftMirrored e .rightMirrored.

Per ulteriori informazioni su UIImage, fai riferimento a UIImage Apple Developer Documentazione.

CVPixelBuffer

Il formato CVPixelBuffer è adatto per le applicazioni che generano frame e utilizza la classe CoreImage per iOS per l'elaborazione dei dati.

Il formato CVPixelBuffer è adatto alle seguenti modalità di corsa:

  • Immagini: app che generano CVPixelBuffer immagini dopo un'elaborazione utilizzando il framework CoreImage di iOS possono essere inviate a modalità di esecuzione delle immagini.

  • Video: i fotogrammi possono essere convertiti nel formato CVPixelBuffer per in modalità video, per poi inviarla a "Posioratrice di punti" in modalità video.

  • live streaming: le app che utilizzano una fotocamera iOS per generare fotogrammi possono essere convertite nel formato CVPixelBuffer per l'elaborazione prima di essere inviati al Posa punto di riferimento 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 CVPixelBuffer Apple Sviluppatore Documentazione.

CMSampleBuffer

Il formato CMSampleBuffer archivia campioni multimediali di un tipo di supporto uniforme e Si adatta alla modalità di corsa in live streaming. I fotogrammi in diretta delle fotocamere iOS sono pubblicato 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 ulteriori informazioni su CMSampleBuffer, consulta l'articolo CMSampleBuffer Apple Sviluppatore Documentazione.

Esegui l'attività

Per eseguire questa funzione, utilizza il metodo detect() specifico per modalità di corsa:

  • Immagine statica: detect(image:)
  • Video: detect(videoFrame:timestampInMilliseconds:)
  • Live streaming: detectAsync(image:timestampInMilliseconds:)

I seguenti esempi di codice mostrano semplici esempi di come eseguire Pose accedere a diverse modalità di corsa:

Swift

Immagine

let result = try poseLandmarker.detect(image: image)
    

Video

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

Live streaming

try poseLandmarker.detectAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

Immagine

MPPPoseLandmarkerResult *result =
  [poseLandmarker detectImage:image error:nil];
    

Video

MPPPoseLandmarkerResult *result =
  [poseLandmarker detectVideoFrame:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

Live streaming

BOOL success =
  [poseLandmarker detectAsyncImage:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

L'esempio di codice di Pose Taper mostra le implementazioni di ciascuna di queste modalità in modo più dettagliato detect(image:), detect(videoFrame:timestampInMilliseconds:), e detectAsync(image:timestampInMilliseconds:). Il codice di esempio consente all'utente di passare da una modalità di elaborazione all'altra che potrebbe non essere necessaria per il tuo utilizzo per verificare se è così.

Tieni presente quanto segue:

  • Quando l'esecuzione avviene in modalità video o live streaming, devi fornire anche il timestamp del frame di input all'attività Punti di riferimento in posizioni.

  • Quando viene eseguita in modalità immagine o video, l'attività Punti di riferimento blocca il thread corrente finché non termina l'elaborazione dell'immagine o del frame di input. A evitare di bloccare il thread corrente, esegui l'elaborazione in background thread utilizzando iOS Dispatch o NSOperation i modelli di machine learning.

  • Quando l'attività viene eseguita in modalità live streaming, l'attività Punto di riferimento torna immediatamente. e non blocca il thread corrente. Richiamo poseLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) metodo con il risultato del punto di riferimento per la posa dopo l'elaborazione di ogni frame di input. La Pose Taper richiama questo metodo in modo asincrono su un numero seriale dedicato di tracciamento delle chiamate. Per visualizzare i risultati sull'interfaccia utente, invia il metodo i risultati alla coda principale dopo l'elaborazione dei risultati. Se detectAsync viene chiamata quando l'attività Segnaposto di posizioni è impegnata a elaborare un'altra frame, il riquadro di riferimento ignora il nuovo frame di input.

Gestire e visualizzare i risultati

Dopo l'esecuzione dell'inferenza, l'attività Punti di riferimento in posizioni restituisce un PoseLandmarkerResult che contiene le coordinate di ogni punto di riferimento di posa.

Di seguito è riportato un esempio dei dati di output di questa attività:

PoseLandmarkerResult:
  Landmarks:
    Landmark #0:
      x            : 0.638852
      y            : 0.671197
      z            : 0.129959
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.634599
      y            : 0.536441
      z            : -0.06984
      visibility   : 0.999909
      presence     : 0.999958
    ... (33 landmarks per pose)
  WorldLandmarks:
    Landmark #0:
      x            : 0.067485
      y            : 0.031084
      z            : 0.055223
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.063209
      y            : -0.00382
      z            : 0.020920
      visibility   : 0.999976
      presence     : 0.999998
    ... (33 world landmarks per pose)
  SegmentationMasks:
    ... (pictured below)

L'output contiene sia le coordinate normalizzate (Landmarks) sia il mondo coordinate (WorldLandmarks) per ogni punto di riferimento.

L'output contiene le seguenti coordinate normalizzate (Landmarks):

  • x e y: coordinate dei punti di riferimento normalizzate tra 0,0 e 1,0 in base al larghezza (x) e altezza (y) dell'immagine.

  • z: la profondità del punto di riferimento, con la profondità nel punto centrale dei fianchi come origine dati. Più basso è il valore, più il punto di riferimento è vicino alla fotocamera. La magnitude z utilizza più o meno la stessa scala di x.

  • visibility: la probabilità che il punto di riferimento sia visibile all'interno dell'immagine.

L'output contiene le seguenti coordinate del mondo (WorldLandmarks):

  • x, y e z: coordinate 3dimensionali del mondo reale in metri, con parte centrale dei fianchi come origine.

  • visibility: la probabilità che il punto di riferimento sia visibile all'interno dell'immagine.

L'immagine seguente mostra una visualizzazione dell'output dell'attività:

La maschera di segmentazione facoltativa rappresenta la probabilità che ciascun pixel appartenga a una persona rilevata. Nell'immagine di seguito è riportata una maschera di segmentazione output dell'attività:

Il codice di esempio di Pose Taper illustra come visualizzare che consentono di analizzare i dati e visualizzare i risultati.