Udhëzues dore për zbulimin e pikave referuese për Android

Detyra MediaPipe Hand Landmarker ju lejon të zbuloni pikat referuese të duarve në një imazh. Këto udhëzime ju tregojnë se si të përdorni Handmarker me aplikacionet Android. 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 Hand Landmarker për Android. Shembulli përdor kamerën në një pajisje fizike Android për të zbuluar vazhdimisht pikat referuese të dorës dhe gjithashtu mund të përdorë imazhe dhe video nga galeria e pajisjes për të zbuluar në mënyrë statike pikat referuese të dorës.

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 Hand Landmarker gjendet 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 Hand Landmarker:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/hand_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ë zbulimit të pikës referimi me dorë:

  • HandLandmarkerHelper.kt - Inicializon detektorin e pikës së dorës dhe trajton përzgjedhjen e modelit dhe delegatit.
  • MainActivity.kt - Zbaton aplikacionin, duke përfshirë thirrjen HandLandmarkerHelper .

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 Hand 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 Hand 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 Hand 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 Hand 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 HandLandmarkerHelper.kt :

baseOptionBuilder.setModelAssetPath(MP_HAND_LANDMARKER_TASK)

Krijo detyrën

Detyra MediaPipe Hand 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 .

Shënuesi i dorës mbështet 3 lloje të dhënash hyrëse: imazhe statike, skedarë video dhe transmetim të drejtpërdrejtë. 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 që korrespondon me llojin tuaj të të dhënave hyrëse për të parë se si të krijoni detyrën dhe të ekzekutoni konkluzionet.

Imazhi

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

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

Video

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

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

Transmetim i drejtpërdrejtë

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

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

Implementimi i kodit të shembullit të Hand Landmarker lejon përdoruesin të kalojë ndërmjet 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 setupHandLandmarker() në skedarin HandLandmarkerHelper.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
numHands Numri maksimal i duarve të zbuluara nga detektori i pikës referuese Hand. Any integer > 0 1
minHandDetectionConfidence Rezultati minimal i besimit për zbulimin e dorës për t'u konsideruar i suksesshëm në modelin e zbulimit të pëllëmbës. 0.0 - 1.0 0.5
minHandPresenceConfidence Rezultati minimal i besimit për rezultatin e pranisë së dorës në modelin e zbulimit të pikës referimi me dorë. Në modalitetin "Video" dhe "Transmetimi i drejtpërdrejtë", nëse rezultati i besueshmërisë së pranisë së dorës nga modeli i pikës së dorës është nën këtë prag, "Shënuesi i dorës" aktivizon modelin e zbulimit të pëllëmbës. Përndryshe, një algoritëm i lehtë i gjurmimit të dorës përcakton vendndodhjen e dorës(ave) për zbulimet e mëvonshme të pikës referimi. 0.0 - 1.0 0.5
minTrackingConfidence Rezultati minimal i besimit që gjurmimi i dorës të konsiderohet i suksesshëm. Ky është pragu kufizues IoU i kutisë midis duarve në kuadrin aktual dhe kuadrit të fundit. Në modalitetin "Video" dhe "Transmetim" të "Hand Landmarker", nëse gjurmimi dështon, Hand Landmarker aktivizon zbulimin me dorë. Përndryshe, ai anashkalon zbulimin e dorës. 0.0 - 1.0 0.5
resultListener Vendos dëgjuesin e rezultateve që të marrë rezultatet e zbulimit në mënyrë asinkrone kur pikë referimi është në modalitetin e transmetimit të drejtpërdrejtë. Zbatohet vetëm kur modaliteti i ekzekutimit është caktuar në LIVE_STREAM N/A N/A
errorListener Vendos një dëgjues opsional gabimi. N/A N/A

Përgatitni të dhënat

Hand Landmarker punon me imazhe, skedarë video dhe video me transmetim të drejtpërdrejtë. 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 Hand Landmarker, përgatitja e të dhënave trajtohet në skedarin HandLandmarkerHelper.kt .

Drejtoni detyrën

Në varësi të llojit të të dhënave me të cilat po punoni, përdorni metodën HandLandmarker.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 jeni duke kryer zbulime në një transmetim video, sigurohuni që zbulimet t'i ekzekutoni në një bashkëbisedim të veçantë për të shmangur bllokimin e lidhjes së ndërfaqes së përdoruesit.

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

Imazhi

val result = handLandmarker?.detect(mpImage)
    

Video

val timestampMs = i * inferenceIntervalMs

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

Transmetim i drejtpërdrejtë

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

handLandmarker?.detectAsync(mpImage, frameTime)
    

Vini re sa vijon:

  • Kur ekzekutoni në modalitetin e videos ose në modalitetin e transmetimit të drejtpërdrejtë, duhet të jepni gjithashtu vulën kohore të kornizës së hyrjes në detyrën Hand Landmarker.
  • Kur ekzekutohet në modalitetin e imazhit ose të videos, detyra Hand Landmarker do të bllokojë fillin aktual derisa të përfundojë përpunimin e imazhit ose kornizës hyrëse. Për të shmangur bllokimin e ndërfaqes së përdoruesit, ekzekutoni përpunimin në një fill në sfond.
  • Kur ekzekutohet në modalitetin e transmetimit të drejtpërdrejtë, detyra Hand Landmarker nuk e bllokon lidhjen aktuale, por kthehet menjëherë. Ai do të thërrasë dëgjuesin e tij të rezultateve me rezultatin e zbulimit sa herë që ka përfunduar përpunimin e një kornize hyrëse. Nëse funksioni i zbulimit thirret kur detyra Hand Landmarker është e zënë me përpunimin e një kuadri tjetër, detyra do të injorojë kornizën e re hyrëse.

Në kodin shembull Hand Landmarker, funksionet detect , detectForVideo dhe detectAsync përcaktohen në skedarin HandLandmarkerHelper.kt .

Trajtoni dhe shfaqni rezultatet

Shënuesi i dorës gjeneron një objekt të rezultatit të pikës së dorës për çdo ekzekutim zbulimi. Objekti i rezultatit përmban pika referimi të dorës në koordinatat e imazhit, pikë referimi të dorës në koordinatat botërore dhe dorëzimin (dora e majtë/djathtas) e duarve të zbuluara.

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

Dalja HandLandmarkerResult përmban tre komponentë. Çdo komponent është një grup, ku secili element përmban rezultatet e mëposhtme për një dorë të vetme të zbuluar:

  • Duartësia

    Duartësia përfaqëson nëse duart e zbuluara janë duart e majta apo të djathta.

  • Pikat e referimit

    Ka 21 pika referimi, secila e përbërë nga koordinatat x , y dhe z . Koordinatat x dhe y normalizohen në [0.0, 1.0] nga gjerësia dhe lartësia e imazhit, respektivisht. Koordinata z përfaqëson thellësinë e pikës referuese, me thellësinë në kyçin e dorës që është origjina. 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 .

  • Monumentet e botës

    21 pikat referuese të dorës janë paraqitur gjithashtu në koordinatat botërore. Çdo pikë referimi përbëhet nga x , y dhe z , që përfaqësojnë koordinatat 3D të botës reale në metra me origjinën në qendrën gjeometrike të dorës.

HandLandmarkerResult:
  Handedness:
    Categories #0:
      index        : 0
      score        : 0.98396
      categoryName : Left
  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)

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

Një dorë në një lëvizje gishti lart me strukturën skeletore të dorës të përcaktuar

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