دليل "التعرّف على الوجوه" على أجهزة Android

تتيح لك مهمة MediaPipe اكتشاف الوجوه في صورة أو فيديو. يمكنك استخدام هذه المهمة لتحديد موقع الوجوه وملامح الوجه داخل الإطار. تستخدم هذه المهمة نموذج التعلم الآلي (ML) الذي يعمل مع الصور الفردية أو التدفق المستمر للصور. وتؤدي المهمة إلى إخراج مواقع الوجه، بالإضافة إلى النقاط الرئيسية للوجه التالية: العين اليسرى، والعين اليمنى، وطرف الأنف، والفم، وإراحة العين اليسرى، وجرح العين اليمنى.

يتوفر نموذج التعليمات البرمجية الموضح في هذه التعليمات على 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/face_detector/android
    

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

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

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

  • FaceDetectorHelper.kt - يضبط أداة التعرّف على الوجه وتعالج النموذج وتفويض الاختيار.
  • CameraFragment.kt - يعالج كاميرا الجهاز ويعالج بيانات إدخال الصور والفيديو.
  • GalleryFragment.kt - تتفاعل مع OverlayView لعرض الصورة أو الفيديو الناتجَين.
  • OverlayView.kt - لتطبيق العرض مع مربّعات الإحاطة للوجوه التي تم اكتشافها.

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

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

التبعيات

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

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

الطراز

تتطلّب مهمة MediaPipe Face Detector حزمة نماذج مدرَّبة ومتوافقة مع هذه المَهمّة. للحصول على مزيد من المعلومات حول النماذج المدربة المتاحة لاستخدام ميزة "التعرّف على الوجوه"، راجِع قسم الطُرز الذي يقدّم نظرة عامة على المهمة.

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

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

حدِّد مسار النموذج ضمن المَعلمة ModelAssetPath. في مثال الرمز البرمجي، يتم تحديد النموذج في ملف FaceDetectorHelper.kt:

val modelName = "face_detection_short_range.tflite"
baseOptionsBuilder.setModelAssetPath(modelName)

إنشاء المهمة

تستخدم مهمة MediaPipe Face Detector الدالة createFromOptions() لإعداد المهمة. تقبل الدالة createFromOptions() قيمًا لخيارات الضبط. لمزيد من المعلومات حول خيارات الضبط، يُرجى الاطّلاع على خيارات الضبط.

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

صورة

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

حملة فيديو

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

البث المباشر

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

يتيح مثال تطبيق رمز أداة "التعرّف على الوجه" للمستخدم التبديل بين أوضاع المعالجة. يجعل هذا النهج كود إنشاء المهمة أكثر تعقيدًا وقد لا يكون مناسبًا لحالة استخدامك. يمكنك رؤية هذا الرمز في دالة setupFaceDetector() في ملف FaceDetectorHelper.kt.

خيارات الضبط

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

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

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

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

البث المباشر: وضع بث مباشر لبيانات الإدخال، مثل الكاميرا. في هذا الوضع، يجب استدعاء resultsListener لإعداد أداة معالجة الصوت لكي تتلقى النتائج بشكل غير متزامن.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
minDetectionConfidence الحد الأدنى لدرجة الثقة ليتم اعتبار ميزة "التعرّف على الوجه" ناجحة. Float [0,1] 0.5
minSuppressionThreshold الحد الأدنى غير الأقصى للمنع الذي يتم اعتباره ميزة "التعرّف على الوجه" متداخلاً. Float [0,1] 0.3
resultListener يعمل هذا الإعداد على ضبط أداة معالجة النتائج لتلقّي نتائج الرصد بشكل غير متزامن عندما تكون أداة التعرّف على الوجوه في وضع البث المباشر. لا يمكن استخدام هذا العمود إلّا عند ضبط وضع التشغيل على LIVE_STREAM. N/A Not set
errorListener لضبط أداة معالجة الأخطاء الاختيارية. N/A Not set

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

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

يوضح الرمز البرمجي التالي كيفية تسليم البيانات للمعالجة. وتشمل هذه النماذج تفاصيل حول كيفية التعامل مع البيانات الواردة من الصور وملفات الفيديو وأحداث البث المباشر.

صورة

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

في مثال الرمز البرمجي لأداة التعرّف على الوجوه، تتم معالجة عملية تحضير البيانات في ملف FaceDetectorHelper.kt.

تنفيذ المهمة

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

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

صورة

val result = faceDetector.detect(mpImage)
    

حملة فيديو

val timestampMs = i * inferenceIntervalMs

faceDetector.detectForVideo(mpImage, timestampMs)
    .let { detectionResult ->
        resultList.add(detectionResult)
    }
    

البث المباشر

val mpImage = BitmapImageBuilder(rotatedBitmap).build()
val frameTime = SystemClock.uptimeMillis()

faceDetector.detectAsync(mpImage, frameTime)
    

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

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

في رمز نموذج "أداة التعرّف على الوجوه"، يتم تحديد الدوال detect وdetectForVideo وdetectAsync في ملف FaceDetectorHelper.kt.

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

تعرض "أداة التعرّف على الوجوه" كائن FaceDetectorResult عند كل عملية رصد. يحتوي كائن النتيجة على مربعات حدود للوجوه التي تم اكتشافها ونتيجة ثقة لكل وجه تم اكتشافه.

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

FaceDetectionResult:
  Detections:
    Detection #0:
      BoundingBox:
        origin_x: 126
        origin_y: 100
        width: 463
        height: 463
      Categories:
        Category #0:
          index: 0
          score: 0.9729152917861938
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.18298381567001343
          y: 0.2961040139198303
        NormalizedKeypoint #1:
          x: 0.3302789330482483
          y: 0.29289937019348145
        ... (6 keypoints for each face)
    Detection #1:
      BoundingBox:
        origin_x: 616
        origin_y: 193
        width: 430
        height: 430
      Categories:
        Category #0:
          index: 0
          score: 0.9251380562782288
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.6151331663131714
          y: 0.3713381886482239
        NormalizedKeypoint #1:
          x: 0.7460576295852661
          y: 0.38825345039367676
        ... (6 keypoints for each face)

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

بالنسبة إلى الصورة التي لا تحتوي على مربّعات حدود، يمكنك الاطّلاع على الصورة الأصلية.

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