دليل تضمين الصور لنظام التشغيل Android

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

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

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

رمز مثال "مهام 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_embedder/android
    

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

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

تحتوي الملفات التالية على الرمز المهم لمثال أداة تضمين الصور هذا. app:

  • 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: وضع إدخالات الصورة الفردية

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

LIVE_STREAM: وضع البث المباشر للإدخال البيانات، مثل تلك الواردة من الكاميرا. في هذا الوضع، يجب أن يكون resultListener يتم استدعاءها لإعداد مستمع للحصول على النتائج بشكل غير متزامن.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
l2_normalize ما إذا كان ستتم تسوية متجه الميزة المرتجعة بمعيار L2. لا تستخدم هذا الخيار إلا إذا كان النموذج لا يحتوي على رموز أصلية L2_NORMALIZATION TFLite Op. في معظم الحالات، يكون هذا هو الحال بالفعل يتم تحقيق تسوية المستوى 2 من خلال استنتاج TFLite بدون الحاجة إلى لهذا الخيار. Boolean False
quantize ما إذا كان يجب قياس التضمين الذي يتم عرضه بوحدات البايت عبر الكمية الكمّية. يتم الافتراض ضمنيًا أن التضمينات تستند إلى معيار وحدة وبالتالي، يمكن ضمان توفُّر قيمة لأي سمة في [ -1.0، 1.0]. استخدام الخيار l2_normalize إذا لم يكن الأمر كذلك. Boolean False
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 users device as a Bitmap object using BitmapFactory.

// Convert an Androids Bitmap object to a MediaPipes 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 videos metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. Youll need them
// to calculate the timestamp of each frame later.

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

// Convert the Androids Bitmap object to a MediaPipes Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

بث مباشر

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

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

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

في مثال التعليمة البرمجية، يتم التعامل مع إعداد البيانات في ImageEmbedderHelper.kt الملف.

تنفيذ المهمة

يمكنك استدعاء الدالة embed المرتبطة بوضع الجري لبدء التشغيل والاستنتاجات. تعرض واجهة برمجة تطبيقات تضمين الصورة متجهات التضمين للإدخال الصورة أو الإطار.

صورة

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