تتيح لك مهمة "إدراج الصور" من MediaPipe تحويل بيانات الصور إلى تمثيل رقمي لإنجاز مهام معالجة الصور ذات الصلة بالذكاء الاصطناعي، مثل مقارنة تشابه صورتَين. توضّح لك هذه التعليمات كيفية استخدام أداة إدراج الصور مع تطبيقات Android.
لمزيد من المعلومات عن الإمكانات والنماذج وخيارات الضبط لهذه المهمة، اطّلِع على نظرة عامة.
مثال على الرمز البرمجي
مثال على رمز 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/image_embedder/android
بعد إنشاء نسخة محلية من رمز المثال، يمكنك استيراد المشروع إلى Android Studio وتشغيل التطبيق. للحصول على التعليمات، اطّلِع على دليل الإعداد لنظام Android.
المكونات الرئيسية
تحتوي الملفات التالية على الرمز البرمجي المهم لهذا المثال على تطبيق "إدراج الصور":
- ImageEmbedderHelper.kt: لإعداد أداة تضمين الصور ومعالجة اختيار النموذج والمندوب
- MainActivity.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
حدِّد مسار النموذج ضمن المَعلمة ModelAssetPath
. في المثال المعروض في التعليمات البرمجية، يتم تعريف النموذج في الدالة setupImageEmbedder()
في ملف
ImageEmbedderHelper.kt:
استخدِم الطريقة BaseOptions.Builder.setModelAssetPath()
لتحديد المسار
الذي يستخدمه النموذج. تتم الإشارة إلى هذه الطريقة في مثال الرمز البرمجي في القسم التالي.
إنشاء المهمة
يمكنك استخدام الدالة createFromOptions
لإنشاء المهمة. تقبل الدالة
createFromOptions
خيارات الضبط لضبط خيارات
المُضمِّن. لمزيد من المعلومات حول خيارات الضبط، يُرجى الاطّلاع على نظرة عامة على الضبط.
تتيح مهمة "إدراج الصور" 3 أنواع من بيانات الإدخال: الصور الثابتة وملفات الفيديو وأحداث البث المباشر للفيديوهات. عليك تحديد وضع التشغيل المقابل لنوع بيانات الإدخال عند إنشاء المهمة. اختَر علامة التبويب التي تتوافق مع نوع بيانات الإدخال للاطّلاع على كيفية إنشاء المهمة وتنفيذ الاستنتاج.
صورة
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.IMAGE) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
فيديو
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.VIDEO) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
بث مباشر
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.LIVE_STREAM) .setResultListener((result, inputImage) -> { // Process the embedding result here. }) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
يسمح مثال تنفيذ الرمز البرمجي للمستخدم بالتبديل بين
أوضاع المعالجة. تجعل هذه الطريقة رمز إنشاء المهام أكثر تعقيدًا وقد لا تكون
مناسبة لحالة الاستخدام. يمكنك الاطّلاع على هذا الرمز في دالة
setupImageEmbedder()
في ملف
ImageEmbedderHelper.kt.
خيارات الضبط
تتضمّن هذه المهمة خيارات الضبط التالية لتطبيقات Android:
اسم الخيار | الوصف | نطاق القيمة | القيمة التلقائية |
---|---|---|---|
runningMode |
لضبط وضع التشغيل للمهمة هناك ثلاثة
أوضاع: IMAGE: وضع الإدخالات باستخدام صورة واحدة. VIDEO: وضع الإطارات التي تم فك ترميزها في الفيديو LIVE_STREAM: وضع البث المباشر لبيانات الإدخال ، مثل بيانات الكاميرا في هذا الوضع، يجب استدعاء resultListener لإعداد مستمع لتلقّي النتائج بشكل غير متزامن. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
l2_normalize |
ما إذا كان يجب تطبيع متجه السمات المعروض باستخدام معيار L2 لا تستخدِم هذا الخيار إلا إذا كان النموذج لا يحتوي على خطوة معالجة برمجية أساسية L2_NORMALIZATION من TFLite. وفي معظم الحالات، يكون هذا هو الحال، وبالتالي يتم تحقيق تسويّة L2 من خلال الاستنتاج باستخدام TFLite بدون الحاجة إلى هذا الخيار. | Boolean |
False |
quantize |
ما إذا كان يجب تجزئة البيانات المضمّنة التي تم إرجاعها إلى وحدات بايت من خلال التجزئة على مستوى المقياس يُفترض ضمنيًا أنّ القيم المضمّنة هي قيم عادية و بالتالي، يُضمن أن تكون قيمة أيّ سمة ضمن النطاق [-1.0, 1.0]. استخدِم الخيار l2_normalize إذا لم يكن الأمر كذلك. | Boolean |
False |
resultListener |
ضبط مستمع النتائج لتلقّي نتائج التضمين
بشكل غير متزامن عندما يكون أداة تضمين الصور في وضع البث المباشر
لا يمكن استخدامها إلا عند ضبط وضع التشغيل على LIVE_STREAM |
لا ينطبق | لم يتم الضبط |
errorListener |
تُستخدَم لضبط مستمع أخطاء اختياري. | لا ينطبق | لم يتم الضبط |
إعداد البيانات
تعمل ميزة "إدراج الصور" مع الصور وملفات الفيديو والفيديوهات المباشرة. تعالج المهمة المعالجة المُسبَقة لإدخال البيانات، بما في ذلك تغيير الحجم والدوران ومعالجة قيم البيانات.
عليك تحويل الصورة أو الإطار المُدخل إلى عنصر
com.google.mediapipe.framework.image.MPImage
قبل تمريره إلى مهمة
Image Embedder (أداة تضمين الصور).
صورة
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();
في مثال الرمز البرمجي، تتم معالجة إعداد البيانات في الملف ImageEmbedderHelper.kt.
تنفيذ المهمة
يمكنك استدعاء الدالة embed
المقابلة لوضع التشغيل لبدء
عمليات الاستنتاج. تعرض واجهة برمجة التطبيقات Image Embedder API متجهات التضمين للملف المدرَج
الصورة أو الإطار.
صورة
ImageEmbedderResult embedderResult = imageEmbedder.embed(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. ImageEmbedderResult embedderResult = imageEmbedder.embedForVideo(image, frameTimestampMs);
بث مباشر
// Run inference on the frame. The embedding results will be available // via the `resultListener` provided in the `ImageEmbedderOptions` when // the image embedder was created. imageEmbedder.embedAsync(image, frameTimestampMs);
يُرجى ملاحظة ما يلي:
- عند التشغيل في وضع الفيديو أو وضع البث المباشر، يجب أيضًا تقديم الطابع الزمني لإطار الإدخال إلى مهمة "أداة تضمين الصور".
- عند التشغيل في وضع الصورة أو الفيديو، ستؤدي مهمة "مُضمِّن الصور" إلى حظر سلسلة المحادثات الحالية إلى أن تنتهي من معالجة الصورة أو الإطار المُدخل. لتجنُّب حظر سلسلة المحادثات الحالية، نفِّذ المعالجة في سلسلت محادثات في الخلفية.
- عند التشغيل في وضع البث المباشر، لا تحظر مهمة "مُضمِّن الصور"
سلسلة المحادثات الحالية، بل تعود على الفور. سيستدعي مستمع النتائج
نتيجة الكشف في كل مرة تنتهي فيها من معالجة ملف
إطار الإدخال. إذا تمّ استدعاء الدالة
embedAsync
عندما تكون مهمة "أداة تضمين الصور" مشغولة في معالجة إطار آخر، تتجاهل المهمة إطار الإدخال الجديد.
في مثال التعليمات البرمجية، تم تعريف الدالة embed
في ملف
ImageEmbedderHelper.kt.
معالجة النتائج وعرضها
عند تنفيذ الاستنتاج، تعرض مهمة "أداة تضمين الصور" عنصرًا من النوع ImageEmbedderResult
يحتوي على قائمة بعمليات التضمين (إما باستخدام النقطة العائمة أو
التضمين الكمي للمتّجه) للصورة المُدخلة.
في ما يلي مثال على بيانات الإخراج من هذه المهمة:
ImageEmbedderResult:
Embedding #0 (sole embedding head):
float_embedding: {0.0, 0.0, ..., 0.0, 1.0, 0.0, 0.0, 2.0}
head_index: 0
تم الحصول على هذه النتيجة من خلال تضمين الصورة التالية:
يمكنك مقارنة تشابه عنصرَي إدراج باستخدام الدالة
ImageEmbedder.cosineSimilarity
. اطّلِع على الرمز البرمجي التالي للحصول على مثال.
// Compute cosine similarity.
double similarity = ImageEmbedder.cosineSimilarity(
result.embeddingResult().embeddings().get(0),
otherResult.embeddingResult().embeddings().get(0));