دليل تصنيف الصور إلى شرائح لنظام التشغيل 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/image_segmentation/android
    

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

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

تحتوي الملفات التالية على التعليمات البرمجية الهامة لتطبيق مثال تقسيم الصور هذا:

  • ImageSegmenterHelper.kt - يضبط هذا الإعداد مهمة أداة تقسيم الصور وتعالج النموذج وتفويض الاختيار.
  • CameraFragment.kt - يوفّر واجهة المستخدم ورمز التحكم للكاميرا.
  • GalleryFragment.kt - يوفر واجهة المستخدم ورمز التحكم لاختيار ملفات الصور والفيديو.
  • OverlayView.kt - الأسماء المعرِّفة وتنسيق نتائج التقسيم.

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

يصف هذا القسم الخطوات الرئيسية لإعداد بيئة التطوير ومشاريع التعليمات البرمجية لاستخدام أداة تقسيم الصور. للحصول على معلومات عامة حول إعداد بيئة التطوير لاستخدام مهام 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

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

في مثال على رمز "أداة تقسيم الصور"، يتم تعريف النموذج في الفئة ImageSegmenterHelper.kt في الدالة setupImageSegmenter().

إنشاء المهمة

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

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

صورة

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.IMAGE)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .build();
imagesegmenter = ImageSegmenter.createFromOptions(context, options);
    

حملة فيديو

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.VIDEO)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .build();
imagesegmenter = ImageSegmenter.createFromOptions(context, options);
    

البث المباشر

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .setResultListener((result, inputImage) -> {
         // Process the segmentation result here.
    })
    .setErrorListener((result, inputImage) -> {
         // Process the segmentation errors here.
    })
    .build()
imagesegmenter = ImageSegmenter.createFromOptions(context, options)
    

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

خيارات الضبط

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

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

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

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

البث المباشر: وضع بث مباشر لبيانات الإدخال، مثل الكاميرا. في هذا الوضع، يجب استدعاء resultsListener لإعداد أداة معالجة الصوت لكي تتلقى النتائج بشكل غير متزامن.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
outputCategoryMask في حال ضبط هذه السياسة على True، سيتضمّن الناتج قناع تصنيف على شكل صورة uint8، حيث تشير كل قيمة بكسل إلى قيمة الفئة الفائزة. {True, False} False
outputConfidenceMasks في حال ضبط هذه القيمة على True، تتضمّن النتيجة قناع تصنيف على شكل صورة ذات قيمة عائمة، حيث تمثل كل قيمة عائمة خريطة نتيجة الثقة للفئة. {True, False} True
displayNamesLocale تحدِّد هذه السياسة لغة التصنيفات التي سيتم استخدامها للأسماء المعروضة في البيانات الوصفية لنموذج المهمة، إذا كان ذلك متاحًا. الإعداد التلقائي هو en للغة الإنجليزية. يمكنك إضافة تصنيفات مترجَمة إلى البيانات الوصفية لنموذج مخصّص باستخدام TensorFlow Lite Metadata Scriptr API. رمز اللغة en
resultListener تعمل هذه السياسة على ضبط أداة معالجة النتائج لتلقّي نتائج التقسيم على نحو غير متزامن عندما يكون مقسّم الصور في وضع البث المباشر. لا يمكن استخدام هذا الخيار إلا عند ضبط وضع التشغيل على LIVE_STREAM. لا ينطبق لا ينطبق
errorListener لضبط أداة معالجة الأخطاء الاختيارية. لا ينطبق لم يتم الضبط.

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

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

تحتاج إلى تحويل الصورة أو الإطار الذي يتم إدخاله إلى كائن 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 value. You’ll need them
// 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()
Image mpImage = new MediaImageBuilder(mediaImage).build();
    

في الرمز البرمجي الخاص بنموذج تقسيم الصور، يتم إعداد البيانات في الفئة ImageSegmenterHelper من خلال الدالة segmentLiveStreamFrame().

تنفيذ المهمة

تستدعي دالة segment مختلفة استنادًا إلى وضع التشغيل الذي تستخدمه. تعرض دالة تقسيم الصورة مناطق القطاع المحددة داخل صورة الإدخال أو الإطار.

صورة

ImageSegmenterResult segmenterResult = imagesegmenter.segment(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.
ImageSegmenterResult segmenterResult =
    imagesegmenter.segmentForVideo(image, frameTimestampMs);
    

البث المباشر

// Run inference on the frame. The segmentations results will be available via
// the `resultListener` provided in the `ImageSegmenterOptions` when the image
// segmenter was created.
imagesegmenter.segmentAsync(image, frameTimestampMs);
    

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

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

في رمز مثال أداة تقسيم الصور، يتم تحديد دوال segment في الملف ImageSegmenterHelper.kt.

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

عند تنفيذ الاستنتاج، تعرض مهمة "أداة تقسيم الصور" عنصر ImageSegmenterResult يحتوي على نتائج مهمة التقسيم. ويعتمد محتوى المخرجات على outputType التي تضبطها عند ضبط المهمة.

تعرض الأقسام التالية أمثلة على بيانات المخرجات من هذه المهمة:

ثقة الفئة

تُظهر الصور التالية تصورًا لناتج المهمة لقناع الثقة للفئة. يحتوي ناتج قناع الثقة على قيم عائمة بين [0, 1].

نتيجة قناع الثقة للصورة والفئة الأصلية. الصورة المصدر من مجموعة بيانات Pascal VOC 2012.

قيمة الفئة

تعرض الصور التالية تصورًا لإخراج المهمة لقناع قيمة الفئة. نطاق قناع الفئة هو [0, 255] وتمثل كل قيمة بكسل فهرس الفئة الفائزة في ناتج النموذج. حصل مؤشر الفئة الفائزة على أعلى درجة من بين الفئات التي يمكن للنموذج التعرف عليها.

مخرجات قناع الصورة والفئة الأصلية. الصورة المصدر من مجموعة بيانات Pascal VOC 2012.