دليل التعرّف على المعالم في نظام Android يدويًا

تتيح لك مهمة معارِض اليد في MediaPipe اكتشاف معالم الأيدي في الصورة. توضّح لك هذه التعليمات كيفية استخدام "أداة معلم اليد" مع تطبيقات Android. تشير رسالة الأشكال البيانية نموذج التعليمات البرمجية الموضح في هذه التعليمات GitHub.

مزيد من المعلومات حول الإمكانات والنماذج وخيارات الضبط هذه المهمة، راجع نظرة عامة.

مثال على الرمز البرمجي

رمز مثال "مهام MediaPipe" هو تنفيذ بسيط لمُرمز يدوي. تطبيق Android. يستخدم هذا المثال الكاميرا على جهاز Android فعلي اكتشاف معالم اليد باستمرار، ويمكن أيضًا استخدام الصور ومقاطع الفيديو من معرض الجهاز لاكتشاف معالم اليد بشكل ثابت.

يمكنك استخدام التطبيق كنقطة بداية لتطبيق Android الخاص بك، أو الرجوع إليه عند تعديل تطبيق حالي. تتم استضافة مثال الرمز البرمجي لأداة ترميز اليد على GitHub.

تنزيل الرمز

توضّح لك التعليمات التالية كيفية إنشاء نسخة على الجهاز من هذا المثال. باستخدام أداة سطر الأوامر git.

لتنزيل نموذج الرمز:

  1. استنساخ مستودع git باستخدام الأمر التالي:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. يمكنك اختياريًا ضبط مثيل git لاستخدام عملية الدفع المتناثر لذلك ليست لديك سوى الملفات الخاصة بتطبيق مثال "أداة التعرّف على اليد":
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/hand_landmarker/android
    

بعد إنشاء نسخة محلية من نموذج الرمز، يمكنك استيراد المشروع. إلى استوديو Android وتشغيل التطبيق. للحصول على التعليمات، يُرجى الاطّلاع على دليل إعداد Android

المكوّنات الرئيسية

تتضمن الملفات التالية الرمز المهم لهذا المَعلم اليدوي. مثال على تطبيق الاكتشاف:

  • HandLandmarkerHelper.kt - تعمل هذه السياسة على إعداد أداة رصد معالم اليد والتعامل مع النموذج والتفويض. التحديد.
  • MainActivity.kt - لتنفيذ التطبيق، بما في ذلك طلب الرقم HandLandmarkerHelper.

ضبط إعدادات الجهاز

يصف هذا القسم الخطوات الرئيسية لإعداد بيئة التطوير ترميز المشروع خصيصًا لاستخدام "أداة معلم اليد". للحصول على معلومات عامة عن إعداد بيئة التطوير الخاصة بك لاستخدام مهام MediaPipe، بما في ذلك متطلبات إصدار نظام التشغيل، راجع دليل إعداد Android

التبعيات

تستخدم مَهمّة "مَعلمة اليد" com.google.mediapipe:tasks-vision المكتبة. أضِف هذه التبعية إلى ملف build.gradle في تطبيق Android:

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

الطراز

تتطلب مهمة أداة ترميز اليد من MediaPipe حزمة نموذج مدرَّبة ومتوافقة مع هذه المهمة. لمزيد من المعلومات حول النماذج المدرَّبة المتاحة لأداة الترميز اليدوية، راجِع نظرة عامة على المهام في قسم "النماذج".

حدد النموذج ونزّله وخزّنه في دليل المشروع:

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

حدِّد مسار النموذج ضمن مَعلمة ModelAssetPath. في جلسة المعمل، مثال التعليمة البرمجية، يتم تحديد النموذج في HandLandmarkerHelper.kt الملف:

baseOptionBuilder.setModelAssetPath(MP_HAND_LANDMARKER_TASK)

إنشاء المهمة

تستخدم مهمة أداة تمييز اليد من MediaPipe الدالة createFromOptions() لإعداد المهمة. تقبل الدالة createFromOptions() قيم الإعدادات. الخيارات. لمزيد من المعلومات حول خيارات الضبط، يُرجى الاطّلاع على خيارات الإعداد:

يتوافق "مؤشر اليد" مع ثلاثة أنواع من بيانات الإدخال: الصور الثابتة وملفات الفيديو بث مباشر. يجب تحديد وضع التشغيل المناسب نوع بيانات الإدخال عند إنشاء المهمة. اختر علامة التبويب المقابلة بيانات الإدخال لمعرفة كيفية إنشاء المهمة وتنفيذ الاستنتاج.

صورة

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)
    

فيديو

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)
    

بث مباشر

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)
    

يتيح تنفيذ رمز نموذج أداة دليل اليد للمستخدم إمكانية التبديل بين أوضاع المعالجة. تجعل هذه الطريقة رمز إنشاء المهمة أكثر تعقيدًا قد لا تكون مناسبة لحالة الاستخدام لديك. يمكنك رؤية هذا الرمز في دالة setupHandLandmarker() في HandLandmarkerHelper.kt الملف.

خيارات الإعداد

تتضمّن هذه المهمة خيارات الضبط التالية لتطبيقات Android:

اسم الخيار الوصف نطاق القيمة القيمة الافتراضية
runningMode لضبط وضع التشغيل للمهمة. هناك ثلاثة وسائل النقل:

IMAGE: وضع إدخالات الصورة الفردية

فيديو: وضع الإطارات التي تم فك ترميزها لفيديو معيّن

LIVE_STREAM: وضع البث المباشر للإدخال البيانات، مثل تلك الواردة من الكاميرا. في هذا الوضع، يجب أن يكون resultListener يتم استدعاءها لإعداد مستمع للحصول على النتائج بشكل غير متزامن.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numHands الحد الأقصى لعدد الأيدي التي رصدتها أداة رصد معالم اليد Any integer > 0 1
minHandDetectionConfidence الحد الأدنى لنتيجة الثقة لرصد اليد تُعد ناجحة في نموذج اكتشاف راحة اليد. 0.0 - 1.0 0.5
minHandPresenceConfidence الحد الأدنى لدرجة الثقة للحصول على نتيجة الحضور باليد نموذج اكتشاف المعالم. في وضع الفيديو ووضع البث المباشر إذا كانت نتيجة الثقة للتواجد على اليد من نموذج المعالم الرئيسية على اليد أقل من هذا الحد، يشغّل "مؤشر اليد" نموذج اكتشاف راحة اليد. بخلاف ذلك، تحدد خوارزمية التتبع الخفيف لليد موقع اليد(الأيدي) لعمليات الكشف اللاحقة للمعالم. 0.0 - 1.0 0.5
minTrackingConfidence يشير ذلك المصطلح إلى الحد الأدنى لدرجة الثقة التي يجب أن يراعيها تتبُّع اليد. وناجح. هذا هو الحد الأدنى لحجم صندوق الإحاطة بين اليدين في الإطار الحالي والإطار الأخير. في وضع الفيديو ووضع البث في معلم اليد، إذا فشل التتبع، يقوم مؤشر اليد باليد الرصد. في الحالات الأخرى، يتخطّى الجهاز ميزة "رصد اليد". 0.0 - 1.0 0.5
resultListener تعيين أداة معالجة النتيجة لتلقي نتائج الرصد بشكل غير متزامن عندما يكون معلم اليد في وضع البث المباشر ينطبق فقط عند ضبط وضع التشغيل على LIVE_STREAM لا ينطبق لا ينطبق
errorListener تضبط هذه السياسة أداة معالجة للأخطاء اختيارية. لا ينطبق لا ينطبق

تجهيز البيانات

تعمل أداة "مَعلمة اليد" مع الصور وملفّات الفيديو وبث الفيديو المباشر. المهمة المعالجة المسبقة لإدخال البيانات، بما في ذلك تغيير الحجم والتدوير والقيمة التسوية.

يوضح الرمز التالي كيفية تسليم البيانات للمعالجة. هذه تتضمن النماذج تفاصيل حول كيفية التعامل مع البيانات من الصور وملفات الفيديو عمليات بث الفيديو.

صورة

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

في جلسة المعمل، مثال على رمز أداة ترميز اليد، يتم التعامل مع إعداد البيانات في HandLandmarkerHelper.kt الملف.

تنفيذ المهمة

اعتمادًا على نوع البيانات التي تتعامل معها، استخدم HandLandmarker.detect...() الخاصة بنوع البيانات هذا تحديدًا. استخدام detect() للصور الفردية detectForVideo() للإطارات في ملفات الفيديو detectAsync() للفيديوهات المضمَّنة. عند إجراء عمليات اكتشاف على فيديو مضمّن، تأكَّد من تنفيذ عمليات الرصد في سلسلة محادثات منفصلة لتجنُّب حظر مؤشر ترابط واجهة المستخدم.

تعرض نماذج التعليمات البرمجية التالية أمثلة بسيطة حول كيفية تشغيل "مَعلمة يدوية". في أوضاع البيانات المختلفة هذه:

صورة

val result = handLandmarker?.detect(mpImage)
    

فيديو

val timestampMs = i * inferenceIntervalMs

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

بث مباشر

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

handLandmarker?.detectAsync(mpImage, frameTime)
    

يُرجى ملاحظة ما يلي:

  • عند تشغيل الفيديو في وضع الفيديو أو في وضع البث المباشر، يجب: توفير الطابع الزمني لإطار الإدخال لمهمة "أداة معلم اليد".
  • عند التشغيل في وضع الصورة أو الفيديو، ستتغير مهمة "مؤشر اليد" حظر سلسلة التعليمات الحالية إلى أن تنتهي من معالجة صورة الإدخال أو الإطار. لتجنّب حظر واجهة المستخدم، يجب تنفيذ المعالجة في سلسلة محادثات في الخلفية.
  • عند تفعيل "وضع البث المباشر"، لا تحظر مَهمّة "مَعلمة اليد". سلسلة التعليمات الحالية ولكنها تعود فورًا. سوف يستدعي نتيجته أداة استماع تظهر فيها نتيجة الرصد في كل مرة ينتهي فيها من معالجة إطار الإدخال. إذا تم استدعاء وظيفة الاكتشاف عند وجود مهمة معلم اليد مشغولاً بمعالجة إطار آخر، فستتجاهل المهمة إطار الإدخال الجديد.

في جلسة المعمل، مثال على رمز أداة ترميز يدوية، detect وdetectForVideo يتم تحديد دوال detectAsync في HandLandmarkerHelper.kt الملف.

التعامل مع العملاء وعرض النتائج

أداة معلم اليد تنشئ كائن نتيجة معلم يد لكل عملية اكتشاف الجري. يحتوي عنصر النتيجة على معالم يد في إحداثيات الصورة، يد المعالِم في إحداثيات العالم ومدى استخدام اليد(اليد اليسرى أو اليمنى) للشخص الذي تم رصده يَدَان

في ما يلي مثال على بيانات الإخراج من هذه المهمة:

تحتوي إخراج HandLandmarkerResult على ثلاثة مكونات. يكون كل عنصر عبارة عن مصفوفة يحتوي فيها كل عنصر على النتائج التالية ليد واحدة تم رصدها:

  • استخدام إحدى اليدين

    ويشير مقياس "استخدام اليدين" إلى ما إذا كانت الأيدي اليسرى أو اليمنى.

  • المعالم

    هناك 21 مَعلمًا لليد، ويتألف كلّ منها من إحداثيات x وy وz. تشير رسالة الأشكال البيانية تتم تسوية إحداثيات x وy إلى [0.0، 1.0] حسب عرض الصورة الارتفاع، على التوالي. ويمثل الإحداثي z عمق المَعلم، مع العمق في المعصم هو المنشأ. كلما كانت القيمة أصغر، اقتربت هو أمام الكاميرا. يستخدم المقدار z تقريبًا نفس المقياس مثل x

  • معالم عالمية

    يتم أيضًا عرض المعالم البالغ عددها 21 يدًا في الإحداثيات العالمية. كل مَعلم تتكون من x وy وz، وتمثل الإحداثيات الثلاثية الأبعاد في العالم الحقيقي في متر مع نقطة الأصل في مركز اليد الهندسي.

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)

تُظهر الصورة التالية تصورًا لنتج المهمة:

يوضح رمز مثال أداة معلم اليد طريقة عرض التي تم إرجاعها من المهمة، يمكنك الاطلاع على OverlayView لمزيد من التفاصيل.