دليل رصد العناصر في نظام التشغيل Android

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

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

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

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

تنزيل الرمز

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

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

  1. استنسِخ مستودع git باستخدام الأمر التالي:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. يمكنك اختياريًا ضبط مثيل git لاستخدام عملية الدفع المتفرقة، بحيث يكون لديك ملفات نموذج تطبيق Object Detector فقط:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/object_detection/android
    

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

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

تحتوي الملفات التالية على التعليمات البرمجية الهامة لتطبيق مثال Object Detector:

  • ObjectDetectorHelper.kt - يضبط أداة رصد الكائنات وتعالج النموذج وتفويض التحديد
  • MainActivity.kt - تنفّذ التطبيق وتجمع مكوّنات واجهة المستخدم.
  • OverlayView.kt - معالجة وعرض النتائج

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

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

التبعيات

تستخدم أداة رصد الكائنات مكتبة com.google.mediapipe:tasks-vision. أضف هذه التبعية إلى ملف build.gradle لمشروع تطوير تطبيق Android لديك. قم باستيراد التبعيات المطلوبة باستخدام التعليمة البرمجية التالية:

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

الطراز

تتطلّب مهمة MediaPipe Object Detector نموذجًا مدرَّبًا متوافقًا مع هذه المهمة. للحصول على مزيد من المعلومات حول النماذج المدربة المتاحة لأداة رصد الكائنات، راجع قسم النماذج الذي يقدم نظرة عامة على المهمة.

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

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

استخدِم طريقة BaseOptions.Builder.setModelAssetPath() لتحديد المسار الذي يستخدمه النموذج للاطّلاع على مثال على الرمز البرمجي، راجِع القسم التالي.

إنشاء المهمة

يمكنك استخدام الدالة createFromOptions لإنشاء المهمة. تقبل الدالة createFromOptions خيارات الضبط، بما في ذلك وضع التشغيل ولغة الأسماء المعروضة والحد الأقصى لعدد النتائج والحدّ الأدنى للثقة والقائمة المسموح بها للفئات وقائمة الحظر. وإذا لم يتم تحديد خيار الضبط، سيتم استخدام القيمة التلقائية. لمزيد من المعلومات حول خيارات الضبط، يمكنك الاطّلاع على نظرة عامة على الإعدادات.

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

صورة

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.IMAGE)
    .setMaxResults(5)
    .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

حملة فيديو

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.VIDEO)
    .setMaxResults(5)
    .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

البث المباشر

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMaxResults(5)
    .setResultListener((result, inputImage) -> {
      // Process the detection result here.
    })
    .setErrorListener((result, inputImage) -> {
      // Process the classification errors here.
    })
   .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

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

خيارات الضبط

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

اسم الخيار الوصف نطاق القيمة القيمة التلقائية
runningMode تحدِّد هذه السياسة وضع التشغيل للمهمة. هناك ثلاثة أوضاع:

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

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

البث المباشر: وضع بث مباشر لبيانات الإدخال، مثل الكاميرا. في هذا الوضع، يجب استدعاء resultsListener لإعداد أداة معالجة الصوت لكي تتلقى النتائج بشكل غير متزامن.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
displayNamesLocales تحدِّد هذه السياسة لغة التصنيفات التي سيتم استخدامها للأسماء المعروضة في البيانات الوصفية لنموذج المهمة، إذا كان ذلك متاحًا. الإعداد التلقائي هو en للغة الإنجليزية. يمكنك إضافة تصنيفات مترجَمة إلى البيانات الوصفية لنموذج مخصّص باستخدام TensorFlow Lite Metadata Scriptr API. رمز اللغة en
maxResults لضبط الحد الأقصى الاختياري لعدد نتائج الرصد الأعلى تقييمًا التي تريد عرضها. أي أرقام موجبة -1 (يتم عرض جميع النتائج)
scoreThreshold لتعيين الحد الأدنى لدرجة التنبؤ الذي يتجاوز الحد المقدم في البيانات الوصفية للنموذج (إن يتوفر). يتم رفض النتائج التي تقلّ عن هذه القيمة. أي عائم لم يتم الضبط.
categoryAllowlist تُحدِّد القائمة الاختيارية لأسماء الفئات المسموح بها. وإذا لم تكن هذه المجموعة فارغة، فسيتم استبعاد نتائج الاكتشاف التي لا يكون اسم الفئة فيها ضمن هذه المجموعة. ويتم تجاهل أسماء الفئات المكررة أو غير المعروفة. لا يمكن استخدام هذا الخيار مع categoryDenylist، ويؤدي استخدام كلاهما إلى حدوث خطأ. أي سلاسل لم يتم الضبط.
categoryDenylist تُحدِّد القائمة الاختيارية لأسماء الفئات غير المسموح بها. وإذا لم تكن هذه البيانات فارغة، فستتم فلترة نتائج الاكتشاف التي يقع اسم فئتها في هذه المجموعة. ويتم تجاهل أسماء الفئات المكررة أو غير المعروفة. لا يمكن استخدام هذا الخيار إلّا مع categoryAllowlist، ويؤدي استخدام كلا الخيارين إلى حدوث خطأ. أي سلاسل لم يتم الضبط.
resultListener يعمل هذا الإعداد على ضبط أداة معالجة النتائج لتلقّي نتائج الرصد بشكل غير متزامن عندما تكون أداة رصد العناصر في وضع البث المباشر. لا يمكنك استخدام هذا الخيار إلا عند ضبط runMode على LIVE_Stream. غير منطبق لم يتم الضبط.

إعداد البيانات

تحتاج إلى تحويل الصورة أو الإطار الذي يتم إدخاله إلى كائن com.google.mediapipe.framework.image.MPImage قبل تمريره إلى "أداة رصد العناصر".

توضح الأمثلة التالية وتوضح كيفية تحضير البيانات للمعالجة لكل نوع من أنواع البيانات المتاحة:

صورة

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load an image on the user’s device as a Bitmap object using BitmapFactory.

// Convert an Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(bitmap).build();
    

حملة فيديو

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load a video file on the user's device using MediaMetadataRetriever

// From the video’s metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT values. Use these values
// to calculate the timestamp of each frame later.

// Loop through the video and load each frame as a Bitmap object.

// Convert the Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

البث المباشر

import com.google.mediapipe.framework.image.MediaImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Create a CameraX’s ImageAnalysis to continuously receive frames
// from the device’s camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

// For each Android’s ImageProxy object received from the ImageAnalysis,
// extract the encapsulated Android’s Image object and convert it to
// a MediaPipe’s Image object.
android.media.Image mediaImage = imageProxy.getImage()
MPImage mpImage = new MediaImageBuilder(mediaImage).build();
    

في مثال الرمز البرمجي لأداة رصد الكائنات، تتم معالجة إعداد البيانات في الفئة ObjectDetectorHelper ضمن الدوال detectImage() وdetectVideoFile() وdetectLivestreamFrame().

تنفيذ المهمة

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

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

صورة

ObjectDetectorResult detectionResult = objectDetector.detect(image);
    

حملة فيديو

// Calculate the timestamp in milliseconds of the current frame.
long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count;

// Run inference on the frame.
ObjectDetectorResult detectionResult =
    objectDetector.detectForVideo(image, frameTimestampMs);
    

البث المباشر

// Run inference on the frame. The detection results will be available
// via the `resultListener` provided in the `ObjectDetectorOptions` when
// the object detector was created.
objectDetector.detectAsync(image, frameTimestampMs);
    

يوضّح مثال رمز أداة رصد العناصر عمليات تنفيذ كل من هذه الأوضاع بمزيد من التفصيل detect() وdetectVideoFile() وdetectAsync(). ويسمح رمز المثال للمستخدم بالتبديل بين أوضاع المعالجة التي قد لا تكون مطلوبة لحالة الاستخدام.

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

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

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

عند تنفيذ الاستنتاج، تعرض مهمة "أداة رصد الكائنات" كائن ObjectDetectorResult يصف الكائنات التي تم العثور عليها في صورة الإدخال.

ويوضح ما يلي مثالاً على بيانات المخرجات من هذه المهمة:

ObjectDetectorResult:
 Detection #0:
  Box: (x: 355, y: 133, w: 190, h: 206)
  Categories:
   index       : 17
   score       : 0.73828
   class name  : dog
 Detection #1:
  Box: (x: 103, y: 15, w: 138, h: 369)
  Categories:
   index       : 17
   score       : 0.73047
   class name  : dog

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

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