تتيح لك مهمة MediaPipe Gesture Recognizer (معرّف إيماءات MediaPipe) التعرّف على إيماءات اليد في الوقت الفعلي، و توفّر نتائج إيماءات اليد التي تم التعرّف عليها ومَعلمات اليد للأيدي التي تم رصدها. توضِّح لك هذه التعليمات كيفية استخدام ميزة "التعرّف على الإيماءات" مع تطبيقات Android. يتوفّر نموذج الرمز البرمجي الموضّح في هذه التعليمات على GitHub.
يمكنك الاطّلاع على هذه المهمة وهي قيد التنفيذ من خلال الاطّلاع على الإصدار التجريبي على الويب. لمزيد من المعلومات عن الإمكانات والنماذج وخيارات الضبط لهذه المهمة، اطّلِع على نظرة عامة.
مثال على الرمز البرمجي
مثال رمز MediaPipe Tasks هو تطبيق بسيط لنظام التشغيل Android يُستخدَم لرصد الإيماءات. يستخدم المثال الكاميرا على جهاز Android مادي لرصد إيماءات اليد باستمرار، ويمكنه أيضًا استخدام الصور والفيديوهات من معرض الصور على الجهاز لرصد الإيماءات بشكل ثابت.
يمكنك استخدام التطبيق كنقطة بداية لتطبيق Android الخاص بك، أو الرجوع إليه عند تعديل تطبيق حالي. يتم استضافة مثال رمز معرّف الإيماءات على GitHub.
تنزيل الرمز
توضِّح لك التعليمات التالية كيفية إنشاء نسخة محلية من مثال الرمز البرمجي باستخدام أداة سطر الأوامر git.
لتنزيل نموذج الرمز البرمجي:
- استنسِخ مستودع git باستخدام الأمر التالي:
git clone https://github.com/google-ai-edge/mediapipe-samples
- يمكنك اختياريًا ضبط مثيل git لاستخدام ميزة "الفحص الخفيف"،
لكي لا تتوفّر لديك سوى ملفات مثال تطبيق "معرّف الإيماءات":
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/gesture_recognizer/android
بعد إنشاء نسخة محلية من رمز المثال، يمكنك استيراد المشروع إلى "استوديو Android" وتشغيل التطبيق. للحصول على التعليمات، اطّلِع على دليل الإعداد لنظام التشغيل Android.
المكونات الرئيسية
تحتوي الملفات التالية على الرمز البرمجي المهم لهذا المثال على تطبيق معالجة إيماءات اليد:
- GestureRecognizerHelper.kt: تُستخدَم هذه الفئة لبدء أداة التعرّف على الإيماءات ومعالجة النموذج وتحديد المفوَّض.
- MainActivity.kt:
ينفِّذ التطبيق، بما في ذلك استدعاء
GestureRecognizerHelper
وGestureRecognizerResultsAdapter
. - GestureRecognizerResultsAdapter.kt: تُستخدَم هذه الفئة لمعالجة النتائج وتنسيقها.
ضبط إعدادات الجهاز
يوضّح هذا القسم الخطوات الرئيسية لإعداد بيئة التطوير و مشاريع الرموز البرمجية لاستخدام ميزة "التعرّف على الإيماءات" على وجه التحديد. للحصول على معلومات عامة عن إعداد بيئة التطوير لاستخدام مهام MediaPipe، بما في ذلك متطلبات إصدار النظام الأساسي، يُرجى الاطّلاع على دليل الإعداد لنظام التشغيل Android.
التبعيات
تستخدِم مهمة "أداة التعرّف على الإيماءات" مكتبة com.google.mediapipe:tasks-vision
. أضِف هذه التبعية إلى ملف build.gradle
لتطبيق Android:
dependencies {
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
الطراز
تتطلّب مهمة MediaPipe Gesture Recognizer حِزمة نموذج مدرَّب متوافقة مع هذه المهمة. لمزيد من المعلومات عن النماذج المدربة المتاحة لميزة "التعرّف على الإيماءات"، اطّلِع على النظرة العامة على المهمة في قسم "النماذج".
اختَر النموذج ونزِّله واحفظه في دليل مشروعك:
<dev-project-root>/src/main/assets
حدِّد مسار النموذج ضمن المَعلمة ModelAssetPath
. في المثال التالي على الرمز،
يتم تحديد التصميم في ملف GestureRecognizerHelper.kt
:
baseOptionBuilder.setModelAssetPath(MP_RECOGNIZER_TASK)
إنشاء المهمة
تستخدِم مهمة MediaPipe Gesture Recognizer الدالة createFromOptions()
لإعداد المَهمّة. تقبل الدالة createFromOptions()
قيمًا
لخيارات الضبط. لمزيد من المعلومات حول خيارات الضبط،
يُرجى الاطّلاع على خيارات الضبط.
يتيح "معرّف الإيماءات" 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)
يسمح مثال تنفيذ رمز معرّف الإيماءات للمستخدم بالتبديل بين
أوضاع المعالجة. تؤدي هذه الطريقة إلى جعل رمز إنشاء المهام أكثر تعقيدًا، وقد لا يكون مناسبًا لحالة الاستخدام. يمكنك الاطّلاع على هذا الرمز في دالة
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 |
الحد الأدنى لنتيجة الثقة في نتيجة توفّر اليد في نموذج رصد معالم اليد في وضع "الفيديو" ووضع "البث المباشر" من ميزة "التعرّف على الإيماءات"، إذا كانت نتيجة الثقة في توفّر اليد من نموذج معالم اليد أقل من هذا الحدّ الأدنى، يتم تفعيل نموذج رصد راحة اليد. بخلاف ذلك، يتم استخدام خوارزمية تتبُّع اليد خفيفة الوزن لتحديد موقع اليدين من أجل رصد المعالم اللاحقة. | 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"] |
|
|
|
customGesturesClassifierOptions |
خيارات ضبط سلوك مصنّف الإيماءات المخصّصة |
|
|
|
resultListener |
ضبط مستمع النتائج لتلقّي نتائج التصنيف
بشكل غير متزامن عندما يكون معرّف الإيماءات في وضع البث المباشر
لا يمكن استخدامها إلا عند ضبط وضع التشغيل على LIVE_STREAM |
ResultListener |
لا ينطبق | لا ينطبق |
errorListener |
تُستخدَم لضبط مستمع أخطاء اختياري. | 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()
في مثال رمز برمجي لخدمة التعرّف على الإيماءات، يتمّ التعامل مع إعداد البيانات في ملف GestureRecognizerHelper.kt
.
تنفيذ المهمة
يستخدم معرّف الإيماءات الدوالّ 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)
يُرجى ملاحظة ما يلي:
- عند التشغيل في وضع الفيديو أو وضع البث المباشر، يجب أيضًا تقديم الطابع الزمني لإطار الإدخال إلى مهمة "معرّف الإيماءات".
- عند التشغيل في وضع الصورة أو الفيديو، ستؤدي مهمة "التعرّف على الإيماءات" إلى حظر سلسلة المهام الحالية إلى أن تنتهي من معالجة الصورة أو الإطار المُدخل. لتجنّب حظر واجهة المستخدم، نفِّذ المعالجة في سلسلسة مهام في الخلفية.
- عند التشغيل في وضع البث المباشر، لا تحظر مهمة "التعرّف على الإيماءات" سلسلة المحادثات الحالية، بل تعود على الفور. سيستدعي معالج النتائج المستمع بنتيجة التعرّف في كل مرة تنتهي فيها من معالجة لقطة إدخال. إذا تمّ استدعاء وظيفة التعرّف عندما تكون مهمة "مُعرّف الإيماءات" مشغولة في معالجة إطار آخر، ستتجاهل المهمة إطار الإدخال الجديد.
في مثال رمز برمجي "أداة التعرّف على الإيماءات"، تم تعريف الدوال recognize
وrecognizeForVideo
و
recognizeAsync
في ملف
GestureRecognizerHelper.kt
.
معالجة النتائج وعرضها
ينشئ معرّف الإيماءات عنصر نتيجة رصد الإيماءة لكل عملية رصد. يحتوي عنصر النتيجة على معالِم اليد في إحداثيات الصورة، ومعالم اليد في إحداثيات العالم، واستخدام اليد(اليد اليسرى/اليمنى)، وفئات إيماءات اليد للأيدي التي تم رصدها.
في ما يلي مثال على بيانات الإخراج من هذه المهمة:
يحتوي 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)
تعرض الصور التالية عرضًا مرئيًا لمخرجات المهمة:
في مثال رمز برمجي لخدمة "التعرّف على الإيماءات"، تعالج فئة GestureRecognizerResultsAdapter
في ملف
GestureRecognizerResultsAdapter.kt
النتائج.