راهنمای تشخیص ژست برای اندروید

وظیفه MediaPipe Gesture Recognizer به شما امکان می دهد حرکات دست را در زمان واقعی تشخیص دهید و نتایج تشخیص دست و نشانه های دست را در دست های شناسایی شده ارائه می دهد. این دستورالعمل‌ها به شما نشان می‌دهند که چگونه از Gesture Recognizer با برنامه‌های Android استفاده کنید. نمونه کد شرح داده شده در این دستورالعمل ها در GitHub موجود است.

با مشاهده نسخه نمایشی وب می توانید این کار را در عمل مشاهده کنید. برای اطلاعات بیشتر در مورد قابلیت‌ها، مدل‌ها و گزینه‌های پیکربندی این کار، به نمای کلی مراجعه کنید.

نمونه کد

کد مثال MediaPipe Tasks یک پیاده سازی ساده از یک برنامه Gesture Recognizer برای اندروید است. این مثال از دوربین یک دستگاه فیزیکی اندروید برای تشخیص مداوم حرکات دست استفاده می‌کند و همچنین می‌تواند از تصاویر و ویدیوهای گالری دستگاه برای تشخیص استاتیک حرکات استفاده کند.

می‌توانید از برنامه به‌عنوان نقطه شروع برای برنامه اندرویدی خود استفاده کنید یا هنگام تغییر برنامه موجود به آن مراجعه کنید. کد نمونه Gesture Recognizer در GitHub میزبانی می شود.

کد را دانلود کنید

دستورالعمل های زیر به شما نشان می دهد که چگونه با استفاده از ابزار خط فرمان git یک کپی محلی از کد مثال ایجاد کنید.

برای دانلود کد نمونه:

  1. با استفاده از دستور زیر مخزن git را کلون کنید:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. به صورت اختیاری، نمونه git خود را برای استفاده از تسویه حساب پراکنده پیکربندی کنید، بنابراین فقط فایل‌های برنامه نمونه Gesture Recognizer را داشته باشید:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/gesture_recognizer/android
    

پس از ایجاد یک نسخه محلی از کد نمونه، می توانید پروژه را به اندروید استودیو وارد کرده و برنامه را اجرا کنید. برای دستورالعمل‌ها، به راهنمای راه‌اندازی برای Android مراجعه کنید.

اجزای کلیدی

فایل‌های زیر حاوی کد حیاتی برای این نمونه برنامه تشخیص حرکت دست هستند:

  • GestureRecognizerHelper.kt - شناسایی ژست را راه‌اندازی می‌کند و مدل و انتخاب نماینده را مدیریت می‌کند.
  • MainActivity.kt - برنامه را پیاده سازی می کند، از جمله فراخوانی GestureRecognizerHelper و GestureRecognizerResultsAdapter .
  • GestureRecognizerResultsAdapter.kt - نتایج را کنترل و قالب بندی می کند.

برپایی

این بخش مراحل کلیدی را برای راه اندازی محیط توسعه و پروژه های کد مخصوصاً برای استفاده از Gesture Recognizer توضیح می دهد. برای اطلاعات کلی در مورد تنظیم محیط توسعه خود برای استفاده از وظایف MediaPipe، از جمله الزامات نسخه پلت فرم، به راهنمای راه اندازی برای Android مراجعه کنید.

وابستگی ها

تکلیف Gesture Recognizer از کتابخانه com.google.mediapipe:tasks-vision استفاده می کند. این وابستگی را به فایل build.gradle برنامه اندروید خود اضافه کنید:

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

مدل

وظیفه MediaPipe Gesture Recognizer به یک بسته مدل آموزش دیده نیاز دارد که با این کار سازگار باشد. برای اطلاعات بیشتر در مورد مدل‌های آموزش‌دیده موجود برای Gesture Recognizer، بخش مدل‌های نمای کلی کار را ببینید.

مدل را انتخاب و دانلود کنید و آن را در فهرست پروژه خود ذخیره کنید:

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

مسیر مدل را در پارامتر ModelAssetPath مشخص کنید. در کد مثال، مدل در فایل GestureRecognizerHelper.kt تعریف شده است:

baseOptionBuilder.setModelAssetPath(MP_RECOGNIZER_TASK)

کار را ایجاد کنید

وظیفه MediaPipe Gesture Recognizer از تابع createFromOptions() برای تنظیم کار استفاده می کند. تابع createFromOptions() مقادیری را برای گزینه های پیکربندی می پذیرد. برای اطلاعات بیشتر در مورد گزینه های پیکربندی، گزینه های پیکربندی را ببینید.

Gesture Recognizer از 3 نوع داده ورودی پشتیبانی می‌کند: تصاویر ثابت، فایل‌های ویدیویی، و جریان‌های ویدیویی زنده. هنگام ایجاد کار، باید حالت اجرای مربوط به نوع داده ورودی خود را مشخص کنید. برای مشاهده نحوه ایجاد کار و اجرای استنتاج، برگه مربوط به نوع داده ورودی خود را انتخاب کنید.

تصویر

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)
    

ویدئو

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)
    

پخش زنده

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)
    

اجرای کد مثال Gesture Recognizer به کاربر اجازه می دهد تا بین حالت های پردازش جابجا شود. این رویکرد کد ایجاد کار را پیچیده‌تر می‌کند و ممکن است برای مورد استفاده شما مناسب نباشد. می توانید این کد را در تابع setupGestureRecognizer() در فایل GestureRecognizerHelper.kt ببینید.

گزینه های پیکربندی

این کار دارای گزینه های پیکربندی زیر برای برنامه های Android است:

نام گزینه شرح محدوده ارزش مقدار پیش فرض
runningMode حالت اجرا را برای کار تنظیم می کند. سه حالت وجود دارد:

IMAGE: حالت برای ورودی های تک تصویر.

VIDEO: حالت برای فریم های رمزگشایی شده یک ویدیو.

LIVE_STREAM: حالت پخش زنده داده های ورودی، مانند دوربین. در این حالت، resultListener باید فراخوانی شود تا شنونده ای را برای دریافت نتایج به صورت ناهمزمان تنظیم کند.
{ IMAGE, VIDEO, LIVE_STREAM } IMAGE
numHands حداکثر تعداد دست ها را می توان توسط GestureRecognizer شناسایی کرد. Any integer > 0 1
minHandDetectionConfidence حداقل امتیاز اطمینان برای تشخیص دست برای موفقیت در مدل تشخیص کف دست. 0.0 - 1.0 0.5
minHandPresenceConfidence حداقل امتیاز اطمینان امتیاز حضور دست در مدل تشخیص نقطه عطف دست. در حالت ویدیو و حالت پخش زنده Gesture Recognizer، اگر امتیاز مطمئن حضور دست از مدل نقطه عطف دست کمتر از این آستانه باشد، مدل تشخیص کف دست را فعال می‌کند. در غیر این صورت، یک الگوریتم ردیابی دست سبک وزن برای تعیین محل دست(ها) برای تشخیص نقطه عطف بعدی استفاده می شود. 0.0 - 1.0 0.5
minTrackingConfidence حداقل امتیاز اطمینان برای ردیابی دست که موفقیت آمیز در نظر گرفته شود. این آستانه جعبه محدود کننده IoU بین دست ها در فریم فعلی و آخرین فریم است. در حالت ویدیو و حالت جریان تشخیص حرکت، اگر ردیابی ناموفق باشد، تشخیص حرکت تشخیص دست را فعال می‌کند. در غیر این صورت، تشخیص دست نادیده گرفته می شود. 0.0 - 1.0 0.5
cannedGesturesClassifierOptions گزینه هایی برای پیکربندی رفتار طبقه بندی کننده حرکات کنسرو شده. حرکات کنسرو شده عبارتند از ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
  • محل نام‌های نمایشی: محلی برای استفاده برای نام‌های نمایشی مشخص شده از طریق فراداده مدل TFLite، در صورت وجود.
  • حداکثر نتایج: حداکثر تعداد نتایج طبقه بندی با امتیاز بالا برای بازگشت. اگر < 0 باشد، تمام نتایج موجود برگردانده خواهند شد.
  • آستانه امتیاز: امتیازی که زیر آن نتایج رد می شود. اگر روی 0 تنظیم شود، همه نتایج موجود برگردانده خواهند شد.
  • فهرست مجاز دسته ها: لیست مجاز نام دسته ها. اگر خالی نباشد، نتایج طبقه‌بندی که دسته آنها در این مجموعه نیست فیلتر می‌شوند. انحصاری متقابل با denylist.
  • Category denylist: فهرست انکار نام دسته ها. در صورت خالی نبودن، نتایج طبقه بندی که دسته آنها در این مجموعه است فیلتر می شود. متقابل منحصر به فرد با لیست مجاز.
    • محل نمایش نام: any string
    • حداکثر نتایج: any integer
    • آستانه امتیاز: 0.0-1.0
    • لیست مجاز دسته: vector of strings
    • Category denylist: vector of strings
    • محل نام های نمایشی: "en"
    • حداکثر نتایج: -1
    • آستانه امتیاز: 0
    • لیست مجاز دسته: خالی
    • فهرست رد رده: خالی
    customGesturesClassifierOptions گزینه هایی برای پیکربندی رفتار طبقه بندی کننده حرکات سفارشی.
  • محل نام‌های نمایشی: محلی برای استفاده برای نام‌های نمایشی مشخص شده از طریق فراداده مدل TFLite، در صورت وجود.
  • حداکثر نتایج: حداکثر تعداد نتایج طبقه بندی با امتیاز بالا برای بازگشت. اگر < 0 باشد، تمام نتایج موجود برگردانده خواهند شد.
  • آستانه امتیاز: امتیازی که زیر آن نتایج رد می شود. اگر روی 0 تنظیم شود، همه نتایج موجود برگردانده خواهند شد.
  • فهرست مجاز دسته ها: لیست مجاز نام دسته ها. اگر خالی نباشد، نتایج طبقه‌بندی که دسته آنها در این مجموعه نیست فیلتر می‌شوند. انحصاری متقابل با denylist.
  • Category denylist: فهرست انکار نام دسته ها. در صورت خالی نبودن، نتایج طبقه بندی که دسته آنها در این مجموعه است فیلتر می شود. متقابل منحصر به فرد با لیست مجاز.
    • محل نمایش نام: any string
    • حداکثر نتایج: any integer
    • آستانه امتیاز: 0.0-1.0
    • لیست مجاز دسته: vector of strings
    • Category denylist: vector of strings
    • محل نام های نمایشی: "en"
    • حداکثر نتایج: -1
    • آستانه امتیاز: 0
    • لیست مجاز دسته: خالی
    • فهرست رد رده: خالی
    resultListener شنونده نتیجه را طوری تنظیم می‌کند که وقتی تشخیص‌دهنده اشاره در حالت پخش زنده است، نتایج طبقه‌بندی را به‌صورت ناهمزمان دریافت کند. فقط زمانی قابل استفاده است که حالت اجرا روی LIVE_STREAM تنظیم شده باشد ResultListener N/A N/A
    errorListener یک شنونده خطای اختیاری را تنظیم می کند. ErrorListener N/A N/A

    داده ها را آماده کنید

    Gesture Recognizer با تصاویر، فایل ویدیویی و ویدیوی پخش زنده کار می کند. این وظیفه، پیش پردازش ورودی داده، از جمله تغییر اندازه، چرخش و نرمال سازی مقدار را انجام می دهد.

    کد زیر نحوه واگذاری داده ها را برای پردازش نشان می دهد. این نمونه‌ها شامل جزئیات نحوه مدیریت داده‌های تصاویر، فایل‌های ویدیویی و جریان‌های ویدیویی زنده است.

    تصویر

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

    ویدئو

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

    پخش زنده

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

    در کد نمونه Gesture Recognizer، آماده سازی داده ها در فایل GestureRecognizerHelper.kt مدیریت می شود.

    وظیفه را اجرا کنید

    Gesture Recognizer از توابع recognize , recognizeForVideo و recognizeAsync برای استنتاج استفاده می کند. برای تشخیص ژست، این شامل پیش پردازش داده‌های ورودی، تشخیص دست‌ها در تصویر، تشخیص نشانه‌های دست، و تشخیص حرکت دست از نشانه‌ها است.

    کد زیر نحوه اجرای پردازش با مدل وظیفه را نشان می دهد. این نمونه‌ها شامل جزئیات نحوه مدیریت داده‌ها از تصاویر، فایل‌های ویدیویی و جریان‌های ویدیویی زنده است.

    تصویر

    val result = gestureRecognizer?.recognize(mpImage)
        

    ویدئو

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

    پخش زنده

    val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    val frameTime = SystemClock.uptimeMillis()
    
    gestureRecognizer?.recognizeAsync(mpImage, frameTime)
        

    به موارد زیر توجه کنید:

    • هنگام اجرا در حالت ویدیو یا حالت پخش زنده، باید مُهر زمانی فریم ورودی را نیز به وظیفه Gesture Recognizer ارائه دهید.
    • هنگامی که در حالت تصویر یا ویدیو اجرا می شود، وظیفه تشخیص حرکت رشته فعلی را مسدود می کند تا زمانی که پردازش تصویر یا فریم ورودی به پایان برسد. برای جلوگیری از مسدود کردن رابط کاربری، پردازش را در یک رشته پس‌زمینه اجرا کنید.
    • وقتی در حالت پخش زنده اجرا می‌شود، وظیفه تشخیص حرکت رشته فعلی را مسدود نمی‌کند اما بلافاصله برمی‌گردد. هر بار که پردازش یک فریم ورودی را تمام کند، شنونده نتیجه خود را با نتیجه تشخیص فراخوانی می کند. اگر زمانی که وظیفه تشخیص حرکت مشغول پردازش فریم دیگری است، تابع تشخیص فراخوانی شود، کار کادر ورودی جدید را نادیده می گیرد.

    در کد مثالی Gesture Recognizer، توابع recognize ، recognizeForVideo ، recognizeAsync در فایل GestureRecognizerHelper.kt تعریف شده اند.

    کنترل و نمایش نتایج

    Gesture Recognizer یک شی نتیجه تشخیص ژست را برای هر اجرا تشخیص ایجاد می کند. شیء نتیجه شامل نشانه‌های دست در مختصات تصویر، نشانه‌های دست در مختصات جهان، دسته‌بندی دست (چپ/راست)، و حرکات دست در دست‌های شناسایی‌شده است.

    شکل زیر نمونه ای از داده های خروجی از این کار را نشان می دهد:

    GestureRecognizerResult به دست آمده شامل چهار مؤلفه است و هر مؤلفه یک آرایه است که در آن هر عنصر حاوی نتیجه شناسایی شده یک دست شناسایی شده است.

    • دست غالب

      دستی نشان می دهد که دست های شناسایی شده چپ یا راست هستند.

    • حرکات

      دسته های ژست های شناسایی شده دست های شناسایی شده.

    • نقاط دیدنی

      21 نشانه دستی وجود دارد که هر کدام از مختصات x ، y و z تشکیل شده‌اند. مختصات x و y به ترتیب با عرض و ارتفاع تصویر به [0.0، 1.0] نرمال می شوند. مختصات z نشان دهنده عمق نقطه عطف است و عمق مچ دست مبدأ است. هرچه این مقدار کوچکتر باشد، نقطه عطف به دوربین نزدیکتر است. قدر z تقریباً از همان مقیاس x استفاده می کند.

    • نقاط دیدنی جهان

      21 نشانه دستی نیز در مختصات جهانی ارائه شده است. هر نقطه عطفی از x ، y و z تشکیل شده است که مختصات سه بعدی دنیای واقعی را بر حسب متر با مبدأ در مرکز هندسی عقربه نشان می دهد.

    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)
    

    تصاویر زیر تصویری از خروجی کار را نشان می دهد:

    در کد نمونه Gesture Recognizer، کلاس GestureRecognizerResultsAdapter در فایل GestureRecognizerResultsAdapter.kt نتایج را کنترل می کند.