Leitfaden zur Erkennung von Positionsmarkierungen für Android

Mit der Aufgabe „MediaPipe Pose Landmarker“ können Sie Sehenswürdigkeiten menschlicher Körpers in einem Bild oder Video. Sie können diese Aufgabe nutzen, um wichtige Körperregionen zu identifizieren, und kategorisieren Sie Bewegungen. Bei dieser Aufgabe werden Modelle für maschinelles Lernen (ML) verwendet, mit einzelnen Bildern oder Videos arbeiten. Die Aufgabe gibt Text und Markierungen im Bild aus und in dreidimensionalen Weltkoordinaten angegeben werden.

Das in dieser Anleitung beschriebene Codebeispiel ist auf GitHub Weitere Informationen zu Funktionen, Modellen und Konfigurationsoptionen Sehen Sie sich die Übersicht an.

Codebeispiel

Der Beispielcode von MediaPipe Tasks ist eine einfache Implementierung eines Pose Landmarker. für Android. In diesem Beispiel wird die Kamera eines physischen Android-Geräts verwendet, um Posen in einem durchgehenden Videostream erkennen. Die App kann auch Posen in Bilder und Videos aus der Gerätegalerie.

Du kannst die App als Ausgangspunkt für deine eigene Android-App verwenden oder darauf verweisen wenn Sie eine vorhandene App ändern. Der Beispielcode für Pose Landmarker wird auf GitHub

Code herunterladen

In der folgenden Anleitung erfahren Sie, wie Sie eine lokale Kopie des Beispiels erstellen. mit dem Befehlszeilentool git 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. Konfigurieren Sie optional Ihre Git-Instanz für den Sparse-Checkout, damit Sie nur die Dateien für die Beispiel-App Pose Landmarker an:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/pose_landmarker/android
    

Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie das Projekt importieren in Android Studio ein und führen die App aus. Anweisungen hierzu finden Sie im Einrichtungsleitfaden für Android-Geräte

Schlüsselkomponenten

Die folgenden Dateien enthalten den wichtigen Code für dieses Beispiel für die Positionierung der Orientierungspunkte. Anwendung:

  • PoseLandmarkerHelper.kt: Initialisiert den Positions-Landmarker und verwaltet das Modell und die Delegierung. Auswahl.
  • CameraFragment.kt: verwaltet die Gerätekamera und verarbeitet die Bild- und Videoeingabedaten.
  • GalleryFragment.kt: Interagiert mit OverlayView, um das Ausgabebild oder Video anzuzeigen.
  • OverlayView.kt: Implementiert die Anzeige für die erkannten Posen.

Einrichtung

In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten Ihrer Entwicklungsumgebung und Code-Projekte für die Verwendung von Pose Landmarker erstellen. Allgemeine Informationen zu Einrichten Ihrer Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich Anforderungen an die Plattformversion finden Sie im Einrichtungsleitfaden für Android-Geräte

Abhängigkeiten

Bei der Aufgabe „Pose Landmarker“ wird die Bibliothek com.google.mediapipe:tasks-vision verwendet. Hinzufügen diese Abhängigkeit zur build.gradle-Datei deiner Android-App:

dependencies {
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

Modell

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

Wählen Sie das Modell aus, laden Sie es herunter und speichern Sie es in Ihrem Projektverzeichnis:

<dev-project-root>/src/main/assets

Geben Sie den Pfad des Modells innerhalb des Parameters ModelAssetPath an. Im Beispielcode haben, wird das Modell im PoseLandmarkerHelper.kt Datei:

val modelName = "pose_landmarker_lite.task"
baseOptionsBuilder.setModelAssetPath(modelName)

Aufgabe erstellen

Bei der Aufgabe „MediaPipe Pose Landmarker“ wird mit der Funktion createFromOptions() die . Die Funktion createFromOptions() akzeptiert Werte für die Konfiguration Optionen. Weitere Informationen zu Konfigurationsoptionen finden Sie unter Konfiguration Optionen.

Der Pose Landmarker unterstützt die folgenden Eingabedatentypen: Standbilder, Video und Live-Videostreams. Du musst den Laufmodus angeben die dem Eingabedatentyp entsprechen. Tab auswählen für Ihren Eingabedatentyp aus, um zu sehen, wie die Aufgabe erstellt wird.

Bild

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    poseLandmarker.poseLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinPoseDetectionConfidence(minPoseDetectionConfidence)
        .setMinTrackingConfidence(minPoseTrackingConfidence)
        .setMinPosePresenceConfidence(minposePresenceConfidence)
        .setNumPoses(maxNumPoses)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
poseLandmarker = poseLandmarker.createFromOptions(context, options)
    

Video

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    poseLandmarker.poseLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinPoseDetectionConfidence(minPoseDetectionConfidence)
        .setMinTrackingConfidence(minPoseTrackingConfidence)
        .setMinPosePresenceConfidence(minposePresenceConfidence)
        .setNumPoses(maxNumPoses)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
poseLandmarker = poseLandmarker.createFromOptions(context, options)
    

Livestream

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    poseLandmarker.poseLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinPoseDetectionConfidence(minPoseDetectionConfidence)
        .setMinTrackingConfidence(minPoseTrackingConfidence)
        .setMinPosePresenceConfidence(minposePresenceConfidence)
        .setNumPoses(maxNumPoses)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
poseLandmarker = poseLandmarker.createFromOptions(context, options)
    

Mit dem Beispielcode für Pose Landmarker können Nutzer zwischen Verarbeitungsmodi. Dieser Ansatz macht den Code zur Aufgabenerstellung komplizierter und ist möglicherweise für Ihren Anwendungsfall ungeeignet. Sie sehen diesen Code in der setupPoseLandmarker() in der Spalte PoseLandmarkerHelper.kt -Datei.

Konfigurationsoptionen

Diese Aufgabe bietet die folgenden Konfigurationsoptionen für Android-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 mit Eingabe zum Beispiel von einer Kamera. In diesem Modus muss der resultListener wird aufgerufen, um einen Listener für den Empfang von Ergebnissen einzurichten asynchron programmiert.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numposes Die maximale Anzahl der Posen, die vom Pose-Markierung Integer > 0 1
minPoseDetectionConfidence Der minimale Konfidenzwert für die Pose-Erkennung als erfolgreich angesehen wird. Float [0.0,1.0] 0.5
minPosePresenceConfidence Der minimale Konfidenzwert für die Präsenz in Posen bei der Erkennung von Orientierungspunkten für Posen. Float [0.0,1.0] 0.5
minTrackingConfidence Der minimale Konfidenzwert für das Positions-Tracking um als erfolgreich zu gelten. Float [0.0,1.0] 0.5
outputSegmentationMasks Legt fest, ob Pose Landmarker eine Segmentierungsmaske für die erkannte Pose. Boolean False
resultListener Legt fest, dass der Ergebnis-Listener die Landmark-Ergebnisse empfangen soll asynchron, wenn sich Pose Landmarker im Livestreammodus befindet. Kann nur verwendet werden, wenn der Ausführungsmodus auf LIVE_STREAM festgelegt ist ResultListener N/A
errorListener Legt einen optionalen Fehler-Listener fest. ErrorListener N/A

Daten vorbereiten

Pose Landmarker kann mit Bildern, Videodateien und Live-Videostreams verwendet werden. Die Aufgabe übernimmt die Vorverarbeitung der Dateneingabe, einschließlich Größenanpassung, Rotation und Wert. Normalisierung.

Der folgende Code zeigt, wie Daten zur Verarbeitung übergeben werden. Diese Die Beispiele enthalten Details zum Umgang mit Daten aus Bildern, Videodateien und Livestreams Videostreams.

Bild

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(image).build()
    

Video

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

val argb8888Frame =
    if (frame.config == Bitmap.Config.ARGB_8888) frame
    else frame.copy(Bitmap.Config.ARGB_8888, false)

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(argb8888Frame).build()
    

Livestream

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    

Im Beispielcode für Pose Landmark wird die Datenvorbereitung in der PoseLandmarkerHelper.kt -Datei.

Aufgabe ausführen

Je nach Art der Daten, mit denen Sie arbeiten, verwenden Sie poseLandmarker.detect...()-Methode, die für diesen Datentyp spezifisch ist. Verwenden Sie detect() für einzelne Bilder, detectForVideo() für Frames in Videodateien und detectAsync() für Videostreams. Wenn Sie Erkennungen auf einem Video-Stream gesehen haben, führen Sie die Erkennungen in einem separaten Thread aus, um sodass der Nutzer-Thread blockiert wird.

Die folgenden Codebeispiele zeigen einfache Beispiele für die Ausführung von Pose Landmarker. in diesen verschiedenen Datenmodi:

Bild

val result = poseLandmarker.detect(mpImage)
    

Video

val timestampMs = i * inferenceIntervalMs

poseLandmarker.detectForVideo(mpImage, timestampMs)
    .let { detectionResult ->
        resultList.add(detectionResult)
    }
    

Livestream

val mpImage = BitmapImageBuilder(rotatedBitmap).build()
val frameTime = SystemClock.uptimeMillis()

poseLandmarker.detectAsync(mpImage, frameTime)
    

Wichtige Hinweise:

  • Im Video- oder Livestreammodus müssen Sie Zeitstempel des Eingabe-Frames für die Aufgabe „Pose Landmarker“.
  • Im Bild- oder Videomodus blockiert die Aufgabe „Pose Landmarker“ in den aktuellen Thread verschieben, bis die Verarbeitung des Eingabebilds oder -frames abgeschlossen ist. Bis Blockierung des Nutzer-Interface vermeiden, Verarbeitung im Hintergrund ausführen Diskussions-Thread.
  • Im Livestreammodus wird die Aufgabe „Pose Landmarker“ zurückgegeben. sofort und blockiert den aktuellen Thread nicht. Das Ergebnis wird aufgerufen. Listener mit dem Erkennungsergebnis, sobald er die Verarbeitung eines Eingabe-Frame.

Im Beispielcode für Pose Landmarker werden detect, detectForVideo und detectAsync-Funktionen sind in den PoseLandmarkerHelper.kt -Datei.

Ergebnisse verarbeiten und anzeigen

Die Pose-Markierung gibt für jede Erkennung ein poseLandmarkerResult-Objekt zurück. ausführen. Das Ergebnisobjekt enthält Koordinaten für jede Pose-Markierung.

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

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)

Die Ausgabe enthält sowohl normalisierte Koordinaten (Landmarks) als auch Weltkoordinaten Koordinaten (WorldLandmarks) für jede Sehenswürdigkeit.

Die Ausgabe enthält die folgenden normalisierten Koordinaten (Landmarks):

  • x und y: Sehenswürdigkeiten-Koordinaten, normalisiert zwischen 0,0 und 1,0 durch das Bildbreite (x) und -höhe (y).

  • z: die charakteristische Tiefe, wobei die Tiefe in der Mitte der Hüfte Ursprung. Je kleiner der Wert, desto näher liegt die Sehenswürdigkeit an der Kamera. Die Die Größe von z hat ungefähr den gleichen Maßstab wie x.

  • visibility: gibt an, wie wahrscheinlich es ist, dass die Sehenswürdigkeit im Bild zu sehen ist.

Die Ausgabe enthält die folgenden Weltkoordinaten (WorldLandmarks):

  • x, y und z: Reale dreidimensionale Koordinaten in Metern mit dem Attribut der Hüftmitte als Ursprung.

  • visibility: gibt an, wie wahrscheinlich es ist, dass die Sehenswürdigkeit im Bild zu sehen ist.

Die folgende Abbildung zeigt eine Visualisierung der Aufgabenausgabe:

Die optionale Segmentierungsmaske gibt an, wie wahrscheinlich es ist, dass jedes Pixel an eine erkannte Person gesendet. Das folgende Bild zeigt eine Segmentierungsmaske des Aufgabenausgabe:

Der Beispielcode für Pose Landmarker zeigt, wie die zurückgegebenen Ergebnisse angezeigt werden sehen Sie sich die OverlayView .