Udhëzues për zbulimin e pikës referimi të pozave për Android

Detyra MediaPipe Pose Landmarker ju lejon të zbuloni pika referimi të trupave njerëzorë në një imazh ose video. Ju mund ta përdorni këtë detyrë për të identifikuar vendndodhjet kryesore të trupit, për të analizuar qëndrimin dhe për të kategorizuar lëvizjet. Kjo detyrë përdor modele të mësimit të makinerive (ML) që funksionojnë me imazhe ose video të vetme. Detyra nxjerr pikat referuese të pozës së trupit në koordinatat e imazhit dhe në koordinatat botërore 3-dimensionale.

Shembulli i kodit i përshkruar në këto udhëzime është i disponueshëm në GitHub . Për më shumë informacion rreth aftësive, modeleve dhe opsioneve të konfigurimit të kësaj detyre, shihni Përmbledhjen .

Shembull kodi

Kodi i shembullit të MediaPipe Tasks është një zbatim i thjeshtë i një aplikacioni Pose Landmarker për Android. Shembulli përdor kamerën në një pajisje fizike Android për të zbuluar pozat në një transmetim të vazhdueshëm video. Aplikacioni gjithashtu mund të zbulojë pozat në imazhe dhe video nga galeria e pajisjes.

Mund ta përdorni aplikacionin si pikënisje për aplikacionin tuaj Android ose t'i referoheni kur modifikoni një aplikacion ekzistues. Shembulli i kodit Pose Landmarker është pritur në GitHub .

Shkarkoni kodin

Udhëzimet e mëposhtme ju tregojnë se si të krijoni një kopje lokale të kodit shembull duke përdorur mjetin e linjës së komandës git .

Për të shkarkuar kodin shembull:

  1. Klononi depon e git duke përdorur komandën e mëposhtme:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Opsionale, konfiguroni shembullin tuaj të git për të përdorur arkëtimin e rrallë, në mënyrë që të keni vetëm skedarët për shembullin e aplikacionit Pose Landmarker:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/pose_landmarker/android
    

Pas krijimit të një versioni lokal të kodit shembull, mund ta importoni projektin në Android Studio dhe të ekzekutoni aplikacionin. Për udhëzime, shihni Udhëzuesin e konfigurimit për Android .

Komponentët kryesorë

Skedarët e mëposhtëm përmbajnë kodin vendimtar për këtë aplikacion shembulli të shënjimit të pozës:

  • PoseLandmarkerHelper.kt - Inicializon shënuesin e pozës dhe trajton përzgjedhjen e modelit dhe delegatit.
  • CameraFragment.kt - Trajton kamerën e pajisjes dhe përpunon të dhënat e hyrjes së imazhit dhe videos.
  • GalleryFragment.kt - Ndërvepron me OverlayView për të shfaqur imazhin ose videon dalëse.
  • OverlayView.kt - Zbaton ekranin për pozat e zbuluara.

Konfigurimi

Ky seksion përshkruan hapat kryesorë për konfigurimin e mjedisit tuaj të zhvillimit dhe projekteve të kodit në mënyrë specifike për të përdorur Pose Landmarker. Për informacion të përgjithshëm mbi konfigurimin e mjedisit tuaj të zhvillimit për përdorimin e detyrave të MediaPipe, duke përfshirë kërkesat e versionit të platformës, shihni udhëzuesin e konfigurimit për Android .

varësitë

Detyra Pose Landmarker përdor bibliotekën com.google.mediapipe:tasks-vision . Shtoni këtë varësi në skedarin build.gradle të aplikacionit tuaj Android:

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

Model

Detyra MediaPipe Pose Landmarker kërkon një paketë modeli të trajnuar që është në përputhje me këtë detyrë. Për më shumë informacion mbi modelet e trajnuara të disponueshme për Pose Landmarker, shihni seksionin Modelet e përmbledhjes së detyrave.

Zgjidhni dhe shkarkoni modelin dhe ruajeni në direktorinë e projektit tuaj:

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

Specifikoni shtegun e modelit brenda parametrit ModelAssetPath . Në kodin e shembullit, modeli përcaktohet në skedarin PoseLandmarkerHelper.kt :

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

Krijo detyrën

Detyra MediaPipe Pose Landmarker përdor funksionin createFromOptions() për të konfiguruar detyrën. Funksioni createFromOptions() pranon vlerat për opsionet e konfigurimit. Për më shumë informacion mbi opsionet e konfigurimit, shihni Opsionet e konfigurimit .

Pose Landmarker mbështet llojet e mëposhtme të të dhënave hyrëse: imazhe statike, skedarë video dhe transmetime video të drejtpërdrejta. Ju duhet të specifikoni mënyrën e ekzekutimit që korrespondon me llojin tuaj të të dhënave hyrëse kur krijoni detyrën. Zgjidhni skedën për llojin tuaj të të dhënave hyrëse për të parë se si të krijoni detyrën.

Imazhi

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)
    

Transmetim i drejtpërdrejtë

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)
    

Zbatimi i kodit të shembullit të Pose Landmarker lejon përdoruesin të kalojë midis mënyrave të përpunimit. Qasja e bën kodin e krijimit të detyrës më të komplikuar dhe mund të mos jetë i përshtatshëm për rastin tuaj të përdorimit. Ju mund ta shihni këtë kod në funksionin setupPoseLandmarker() në skedarin PoseLandmarkerHelper.kt .

Opsionet e konfigurimit

Kjo detyrë ka opsionet e mëposhtme të konfigurimit për aplikacionet Android:

Emri i opsionit Përshkrimi Gama e vlerave Vlera e paracaktuar
runningMode Vendos modalitetin e ekzekutimit për detyrën. Ekzistojnë tre mënyra:

IMAGE: Modaliteti për hyrjet e një imazhi të vetëm.

VIDEO: Modaliteti për kornizat e dekoduara të një videoje.

LIVE_STREAM: Modaliteti për një transmetim të drejtpërdrejtë të të dhënave hyrëse, si p.sh. nga një aparat fotografik. Në këtë modalitet, resultListener duhet të thirret për të vendosur një dëgjues për të marrë rezultatet në mënyrë asinkrone.
{ IMAGE, VIDEO, LIVE_STREAM } IMAGE
numposes Numri maksimal i pozave që mund të zbulohet nga Shënuesi i Pozës. Integer > 0 1
minPoseDetectionConfidence Rezultati minimal i besimit për zbulimin e pozës që të konsiderohet i suksesshëm. Float [0.0,1.0] 0.5
minPosePresenceConfidence Rezultati minimal i besimit të rezultatit të pranisë së pozës në zbulimin e pikës referuese të pozës. Float [0.0,1.0] 0.5
minTrackingConfidence Rezultati minimal i besimit për ndjekjen e pozës që të konsiderohet i suksesshëm. Float [0.0,1.0] 0.5
outputSegmentationMasks Nëse Pose Landmarker nxjerr një maskë segmentimi për pozën e zbuluar. Boolean False
resultListener Vendos dëgjuesin e rezultateve që të marrë rezultatet e pikë referimit në mënyrë asinkrone kur Pose Landmarker është në modalitetin e transmetimit të drejtpërdrejtë. Mund të përdoret vetëm kur modaliteti i ekzekutimit është caktuar në LIVE_STREAM ResultListener N/A
errorListener Vendos një dëgjues opsional gabimi. ErrorListener N/A

Përgatitni të dhënat

Pose Landmarker punon me imazhe, skedarë video dhe transmetime video të drejtpërdrejta. Detyra trajton parapërpunimin e hyrjes së të dhënave, duke përfshirë ndryshimin e madhësisë, rrotullimin dhe normalizimin e vlerës.

Kodi i mëposhtëm tregon se si të dorëzohen të dhënat për përpunim. Këto mostra përfshijnë detaje se si të trajtohen të dhënat nga imazhet, skedarët video dhe transmetimet video të drejtpërdrejta.

Imazhi

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()
    

Transmetim i drejtpërdrejtë

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()
    

Në kodin e shembullit të Pose Landmarker, përgatitja e të dhënave trajtohet në skedarin PoseLandmarkerHelper.kt .

Drejtoni detyrën

Në varësi të llojit të të dhënave me të cilat po punoni, përdorni metodën poseLandmarker.detect...() që është specifike për atë lloj të dhënash. Përdorni detect() për imazhe individuale, detectForVideo() për kornizat në skedarët video dhe detectAsync() për transmetimet video. Kur po kryeni zbulime në një transmetim video, sigurohuni që zbulimet t'i ekzekutoni në një bashkëbisedim të veçantë për të shmangur bllokimin e ndërfaqes së përdoruesit.

Shembujt e mëposhtëm të kodit tregojnë shembuj të thjeshtë se si të ekzekutoni Pose Landmarker në këto mënyra të ndryshme të të dhënave:

Imazhi

val result = poseLandmarker.detect(mpImage)
    

Video

val timestampMs = i * inferenceIntervalMs

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

Transmetim i drejtpërdrejtë

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

poseLandmarker.detectAsync(mpImage, frameTime)
    

Vini re sa vijon:

  • Kur ekzekutoni në modalitetin e videos ose në modalitetin e transmetimit të drejtpërdrejtë, duhet të jepni vulën kohore të kornizës së hyrjes në detyrën Pose Landmarker.
  • Kur ekzekutohet në modalitetin e imazhit ose të videos, detyra Pose Landmarker bllokon fillin aktual derisa të përfundojë përpunimin e imazhit ose kornizës hyrëse. Për të shmangur bllokimin e ndërhyrjes së përdoruesit, ekzekutoni përpunimin në një fill në sfond.
  • Kur ekzekutohet në modalitetin e transmetimit të drejtpërdrejtë, detyra Pose Landmarker kthehet menjëherë dhe nuk bllokon lidhjen aktuale. Ai do të thërrasë dëgjuesin e rezultatit me rezultatin e zbulimit sa herë që përfundon përpunimin e një kornize hyrëse.

Në kodin e shembullit Pose Landmarker, funksionet detect , detectForVideo dhe detectAsync përcaktohen në skedarin PoseLandmarkerHelper.kt .

Trajtoni dhe shfaqni rezultatet

Pose Landmarker kthen një objekt poseLandmarkerResult për çdo ekzekutim zbulimi. Objekti i rezultatit përmban koordinatat për çdo pikë referimi të pozës.

Më poshtë tregon një shembull të të dhënave dalëse nga kjo detyrë:

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)

Dalja përmban të dyja koordinatat e normalizuara ( Landmarks ) dhe koordinatat botërore ( WorldLandmarks ) për çdo pikë referimi.

Dalja përmban koordinatat e mëposhtme të normalizuara ( Landmarks ):

  • x dhe y : Koordinatat e pikës referimi normalizohen midis 0.0 dhe 1.0 nga gjerësia e imazhit ( x ) dhe lartësia ( y ).

  • z : Thellësia pikë referimi, me thellësinë në mes të ijeve si origjinë. Sa më e vogël të jetë vlera, aq më afër kamerës është pikë referimi. Madhësia e z përdor përafërsisht të njëjtën shkallë si x .

  • visibility : Mundësia që pikë referimi të jetë e dukshme brenda imazhit.

Prodhimi përmban koordinatat e mëposhtme botërore ( WorldLandmarks ):

  • x , y dhe z : Koordinatat 3-dimensionale të botës reale në metra, me pikën e mesit të ijeve si origjinë.

  • visibility : Mundësia që pikë referimi të jetë e dukshme brenda imazhit.

Imazhi i mëposhtëm tregon një vizualizim të daljes së detyrës:

Një grua në një pozë meditative. Poza e saj theksohet me një kornizë teli që tregon pozicionimin e gjymtyrëve dhe bustit të saj

Maska opsionale e segmentimit përfaqëson gjasat që çdo piksel t'i përkasë një personi të zbuluar. Imazhi i mëposhtëm është një maskë segmentimi e daljes së detyrës:

Maska e segmentimit të imazhit të mëparshëm që përshkruan formën e gruas

Shembulli i kodit Pose Landmarker tregon se si të shfaqen rezultatet e kthyera nga detyra, shikoni klasën OverlayView për më shumë detaje.