Udhëzues për njohjen e gjesteve për Android

Detyra MediaPipe Gesture Recognizer ju lejon të dalloni gjestet e duarve në kohë reale dhe ofron rezultatet e njohura të gjesteve të duarve dhe pikat referuese të duarve të zbuluara. Këto udhëzime ju tregojnë se si të përdorni "Njohësin e gjesteve" me aplikacionet Android. Shembulli i kodit i përshkruar në këto udhëzime është i disponueshëm në GitHub .

Ju mund ta shihni këtë detyrë në veprim duke parë demonstrimin në ueb . 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 Gesture Recognizer për Android. Shembulli përdor kamerën në një pajisje fizike Android për të zbuluar vazhdimisht gjestet e duarve dhe gjithashtu mund të përdorë imazhe dhe video nga galeria e pajisjes për të zbuluar në mënyrë statike gjestet.

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 të Njohësit të Gjestit është i 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 pagesën e rrallë, në mënyrë që të keni vetëm skedarët për shembullin e aplikacionit Gesture Recognizer:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/gesture_recognizer/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ë njohjes së gjesteve të dorës:

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 "Njohësin e gjesteve". 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 e Njohjes së Gjesteve 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 Gesture Recognizer 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 Njohjen e Gjesteve, 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 GestureRecognizerHelper.kt :

baseOptionBuilder.setModelAssetPath(MP_RECOGNIZER_TASK)

Krijo detyrën

Detyra MediaPipe Gesture Recognizer 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 .

Njohësi i gjesteve mbështet 3 lloje të dhënash 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 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_RECOGNIZER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

Video

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

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

Transmetim i drejtpërdrejtë

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

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

Zbatimi i kodit të shembullit të "Njohësit të gjestit" i lejon përdoruesit 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 setupGestureRecognizer() në skedarin GestureRecognizerHelper.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 mund të zbulohet nga GestureRecognizer . 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 të rezultatit të pranisë së dorës në modelin e zbulimit të pikës referimi me dorë. Në modalitetin "Video" dhe "Transmetimi i drejtpërdrejtë" i "Njohjes së gjesteve", nëse rezultati i sigurt i pranisë së dorës nga modeli i pikës së dorës është nën këtë prag, ai aktivizon modelin e zbulimit të pëllëmbës. Përndryshe, një algoritëm i lehtë i gjurmimit të dorës përdoret për të përcaktuar vendndodhjen e dorës(ave) për zbulimin e mëvonshëm 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ë "Njohësit të gjesteve", nëse gjurmimi dështon, "Njohja e gjesteve" aktivizon zbulimin me dorë. Përndryshe, zbulimi i dorës anashkalohet. 0.0 - 1.0 0.5
cannedGesturesClassifierOptions Opsionet për konfigurimin e sjelljes së klasifikuesit të gjesteve të konservuara. Gjestet e konservuara janë ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
  • Vendndodhja e emrave të shfaqur: vendndodhja për t'u përdorur për emrat e shfaqur të specifikuar përmes Metadatës së Modelit TFLite, nëse ka.
  • Rezultatet maksimale: numri maksimal i rezultateve të klasifikimit me pikët më të larta për t'u kthyer. Nëse < 0, të gjitha rezultatet e disponueshme do të kthehen.
  • Pragu i rezultatit: rezultati nën të cilin rezultatet refuzohen. Nëse vendoset në 0, të gjitha rezultatet e disponueshme do të kthehen.
  • Lista e lejeve të kategorive: lista e lejeve të emrave të kategorive. Nëse nuk janë bosh, rezultatet e klasifikimit kategoria e të cilave nuk është në këtë grup do të filtrohen. Reciprokisht ekskluzive me denylist.
  • Refuzimi i kategorive: lista mohuese e emrave të kategorive. Nëse nuk janë bosh, rezultatet e klasifikimit kategoria e të cilave është në këtë grup do të filtrohen. Reciprokisht ekskluzive me listën e lejeve.
    • Vendndodhja e emrave të shfaqur: any string
    • Rezultatet maksimale: any integer
    • Pragu i rezultatit: 0.0-1.0
    • Lista e lejeve të kategorisë: vector of strings
    • Mohues i kategorisë: vector of strings
    • Vendndodhja e emrave të shfaqur: "en"
    • Rezultatet maksimale: -1
    • Pragu i rezultatit: 0
    • Lista e lejeve të kategorisë: bosh
    • Refuzues i kategorisë: bosh
    customGesturesClassifierOptions Opsionet për konfigurimin e sjelljes së klasifikuesit të gjesteve të personalizuara.
  • Vendndodhja e emrave të shfaqur: vendndodhja për t'u përdorur për emrat e shfaqur të specifikuar përmes Metadatës së Modelit TFLite, nëse ka.
  • Rezultatet maksimale: numri maksimal i rezultateve të klasifikimit me pikët më të larta për t'u kthyer. Nëse < 0, të gjitha rezultatet e disponueshme do të kthehen.
  • Pragu i rezultatit: rezultati nën të cilin rezultatet refuzohen. Nëse vendoset në 0, të gjitha rezultatet e disponueshme do të kthehen.
  • Lista e lejeve të kategorive: lista e lejeve të emrave të kategorive. Nëse nuk janë bosh, rezultatet e klasifikimit kategoria e të cilave nuk është në këtë grup do të filtrohen. Reciprokisht ekskluzive me denylist.
  • Refuzimi i kategorive: lista mohuese e emrave të kategorive. Nëse nuk janë bosh, rezultatet e klasifikimit kategoria e të cilave është në këtë grup do të filtrohen. Reciprokisht ekskluzive me listën e lejeve.
    • Vendndodhja e emrave të shfaqur: any string
    • Rezultatet maksimale: any integer
    • Pragu i rezultatit: 0.0-1.0
    • Lista e lejeve të kategorisë: vector of strings
    • Kategoria mohuese: vector of strings
    • Vendndodhja e emrave të shfaqur: "en"
    • Rezultatet maksimale: -1
    • Pragu i rezultatit: 0
    • Lista e lejeve të kategorisë: bosh
    • Refuzues i kategorisë: bosh
    resultListener Vendos dëgjuesin e rezultateve që të marrë rezultatet e klasifikimit në mënyrë asinkrone kur njohësi i gjesteve ë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 N/A
    errorListener Vendos një dëgjues opsional gabimi. ErrorListener N/A N/A

    Përgatitni të dhënat

    Njohja e gjesteve funksionon 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 të Njohësit të Gjesteve, përgatitja e të dhënave trajtohet në skedarin GestureRecognizerHelper.kt .

    Drejtoni detyrën

    Njohësi i gjesteve përdor funksionet e recognize , recognizeForVideo dhe recognizeAsync për të nxjerrë përfundime. Për njohjen e gjesteve, kjo përfshin përpunimin paraprak të të dhënave hyrëse, zbulimin e duarve në imazh, zbulimin e shenjave të dorës dhe njohjen e gjestit të dorës nga pikat referuese.

    Kodi i mëposhtëm tregon se si të ekzekutohet përpunimi me modelin e detyrës. 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

    val result = gestureRecognizer?.recognize(mpImage)
        

    Video

    val timestampMs = i * inferenceIntervalMs
    
    gestureRecognizer?.recognizeForVideo(mpImage, timestampMs)
        ?.let { recognizerResult ->
            resultList.add(recognizerResult)
        }
        

    Transmetim i drejtpërdrejtë

    val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    val frameTime = SystemClock.uptimeMillis()
    
    gestureRecognizer?.recognizeAsync(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 "Njohësi i gjesteve".
    • Kur ekzekutohet në modalitetin e imazhit ose të videos, detyra e Njohjes së Gjesteve 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 e "Njohjes së gjesteve" nuk e bllokon lidhjen aktuale, por kthehet menjëherë. Ai do të thërrasë dëgjuesin e tij të rezultateve me rezultatin e njohjes sa herë që ka përfunduar përpunimin e një kornize hyrëse. Nëse funksioni i njohjes thirret kur detyra e Njohjes së Gjesteve është e zënë me përpunimin e një kuadri tjetër, detyra do të injorojë kornizën e re të hyrjes.

    Në kodin e shembullit të "Njohjes së gjesteve", funksionet e recognize , recognizeForVideo dhe recognizeAsync përcaktohen në skedarin GestureRecognizerHelper.kt .

    Trajtoni dhe shfaqni rezultatet

    Njohësi i gjesteve gjeneron një objekt rezultati të zbulimit të gjesteve për çdo ekzekutim të njohjes. Objekti i rezultatit përmban pika referimi të dorës në koordinatat e imazhit, pika referimi të dorës në koordinatat e botës, aftësia e dorës (dora e majtë/djathtas) dhe kategoritë e gjesteve të duarve të duarve të zbuluara.

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

    Rezultati i GestureRecognizerResult përmban katër komponentë, dhe secili komponent është një grup, ku secili element përmban rezultatin e zbuluar të një dore të vetme të zbuluar.

    • Duartësia

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

    • Gjestet

      Kategoritë e njohura të gjesteve të duarve të zbuluara.

    • 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.

    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)
    

    Imazhet e mëposhtme tregojnë një vizualizim të daljes së detyrës:

    Një dorë në një lëvizje gishti lart me strukturën skeletore të dorës të shënuar

    Në kodin e shembullit të Gesture Recognizer, klasa GestureRecognizerResultsAdapter në skedarin GestureRecognizerResultsAdapter.kt trajton rezultatet.