كشف الكائنات مع أندرويد

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

عرض توضيحي للكشف عن الكائنات

نظرة عامة على اكتشاف الكائنات

اكتشاف الكائنات هي مهمة التعلم الآلي لتحديد وجود وموقع فئات متعددة من الكائنات داخل الصورة. يتم تدريب نموذج الكشف عن الكائنات على مجموعة بيانات تحتوي على مجموعة من الكائنات المعروفة.

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

النماذج ومجموعة البيانات

يستخدم هذا البرنامج التعليمي النماذج التي تم تدريبها باستخدام مجموعة بيانات COCO . COCO عبارة عن مجموعة بيانات واسعة النطاق للكشف عن الكائنات تحتوي على 330 ألف صورة و1.5 مليون مثيل للكائن و80 فئة للكائنات.

لديك خيار استخدام أحد النماذج المدربة مسبقًا التالية:

  • EfficientDet-Lite0 [مستحسن] - نموذج خفيف الوزن للكشف عن الكائنات مع مستخرج ميزات BiFPN، ومؤشر الصندوق المشترك، وفقدان التركيز. تبلغ نسبة mAP (متوسط ​​الدقة) لمجموعة بيانات التحقق من صحة COCO 2017 25.69%.

  • EfficientDet-Lite1 - نموذج اكتشاف كائن EfficientDet متوسط ​​الحجم. تبلغ نسبة MAP لمجموعة بيانات التحقق من صحة COCO 2017 30.55%.

  • EfficientDet-Lite2 - نموذج أكبر للكشف عن كائن EfficientDet. تبلغ نسبة MAP لمجموعة بيانات التحقق من صحة COCO 2017 33.97%.

  • MobileNetV1-SSD - نموذج خفيف الوزن للغاية تم تحسينه للعمل مع TensorFlow Lite لاكتشاف الكائنات. تبلغ نسبة MAP لمجموعة بيانات التحقق من صحة COCO 2017 21%.

في هذا البرنامج التعليمي، يحقق نموذج EfficientDet-Lite0 توازنًا جيدًا بين الحجم والدقة.

تتم إدارة تنزيل النماذج واستخراجها ووضعها في مجلد الأصول تلقائيًا من خلال ملف download.gradle ، الذي يتم تشغيله في وقت الإنشاء. لا تحتاج إلى تنزيل نماذج TFLite يدويًا في المشروع.

مثال الإعداد والتشغيل

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

متطلبات النظام

  • إصدار Android Studio 2021.1.1 (Bumblebee) أو أعلى.
  • Android SDK الإصدار 31 أو أعلى
  • جهاز Android مزود بإصدار نظام التشغيل الأدنى SDK 24 (Android 7.0 - Nougat) مع تمكين وضع المطور.

احصل على رمز المثال

قم بإنشاء نسخة محلية من رمز المثال. ستستخدم هذا الرمز لإنشاء مشروع في Android Studio وتشغيل نموذج التطبيق.

لاستنساخ رمز المثال وإعداده:

  1. استنساخ مستودع git
    git clone https://github.com/tensorflow/examples.git
    
  2. بشكل اختياري، قم بتكوين مثيل git الخاص بك لاستخدام السحب المتفرق، بحيث يكون لديك فقط الملفات الخاصة بالتطبيق النموذجي لاكتشاف الكائنات:
    cd examples
    git sparse-checkout init --cone
    git sparse-checkout set lite/examples/object_detection/android
    

استيراد وتشغيل المشروع

قم بإنشاء مشروع من رمز المثال الذي تم تنزيله، وقم ببناء المشروع، ثم قم بتشغيله.

لاستيراد وإنشاء مشروع التعليمات البرمجية النموذجي:

  1. ابدأ تشغيل أندرويد ستوديو .
  2. من Android Studio، حدد File > New > Import Project .
  3. انتقل إلى دليل التعليمات البرمجية النموذجي الذي يحتوي على ملف build.gradle ( .../examples/lite/examples/object_detection/android/build.gradle ) وحدد هذا الدليل.
  4. إذا طلب Android Studio إجراء Gradle Sync، فاختر "موافق".
  5. تأكد من أن جهاز Android الخاص بك متصل بجهاز الكمبيوتر الخاص بك وأن وضع المطور ممكّن. انقر فوق سهم Run الأخضر.

إذا قمت بتحديد الدليل الصحيح، فسيقوم Android Studio بإنشاء مشروع جديد وإنشائه. يمكن أن تستغرق هذه العملية بضع دقائق، اعتمادًا على سرعة جهاز الكمبيوتر الخاص بك وما إذا كنت قد استخدمت Android Studio لمشاريع أخرى. عند اكتمال البناء، يعرض Android Studio رسالة BUILD SUCCESSFUL في لوحة حالة إخراج البناء .

اختياري: لإصلاح أخطاء البناء عن طريق تحديث إصدار مكون Android الإضافي:

  1. افتح ملف build.gradle في دليل المشروع.
  2. قم بتغيير إصدار أدوات Android كما يلي:

    // from: classpath
    'com.android.tools.build:gradle:4.2.2'
    // to: classpath
    'com.android.tools.build:gradle:4.1.2'
    
  3. قم بمزامنة المشروع عن طريق تحديد: File > Sync Project with Gradle Files .

لتشغيل المشروع:

  1. من Android Studio، قم بتشغيل المشروع عن طريق تحديد Run > Run… .
  2. حدد جهاز Android متصلاً بكاميرا لاختبار التطبيق.

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

إضافة تبعيات المشروع

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

يستخدم تطبيق المثال مكتبة TensorFlow Lite Task للرؤية لتمكين تنفيذ نموذج التعلم الآلي للكشف عن الكائنات. تشرح الإرشادات التالية كيفية إضافة تبعيات المكتبة المطلوبة إلى مشروع تطبيق Android الخاص بك.

تشرح الإرشادات التالية كيفية إضافة المشروع المطلوب وتبعيات الوحدة النمطية إلى مشروع تطبيق Android الخاص بك.

لإضافة تبعيات الوحدة النمطية:

  1. في الوحدة التي تستخدم TensorFlow Lite، قم بتحديث ملف build.gradle الخاص بالوحدة ليشمل التبعيات التالية. في رمز المثال، يوجد هذا الملف هنا: ...examples/lite/examples/object_detection/android/app/build.gradle ( مرجع الكود )

    dependencies {
      ...
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.4.0'
      // Import the GPU delegate plugin Library for GPU inference
      implementation 'org.tensorflow:tensorflow-lite-gpu-delegate-plugin:0.4.0'
      implementation 'org.tensorflow:tensorflow-lite-gpu:2.9.0'
    }
    

    يجب أن يتضمن المشروع مكتبة مهام Vision ( tensorflow-lite-task-vision ). توفر مكتبة وحدة معالجة الرسومات (GPU) ( tensorflow-lite-gpu-delegate-plugin ) البنية الأساسية لتشغيل التطبيق على GPU، وتوفر مكتبة Delegate ( tensorflow-lite-gpu ) قائمة التوافق.

  2. في Android Studio، قم بمزامنة تبعيات المشروع عن طريق تحديد: File > Sync Project with Gradle Files .

تهيئة نموذج ML

في تطبيق Android الخاص بك، يجب عليك تهيئة نموذج التعلم الآلي TensorFlow Lite باستخدام المعلمات قبل تشغيل التنبؤات مع النموذج. تكون معلمات التهيئة هذه متسقة عبر نماذج اكتشاف الكائنات ويمكن أن تتضمن إعدادات مثل الحد الأدنى لحدود الدقة للتنبؤات.

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

يقوم هذا المثال بتنزيل العديد من النماذج المحددة في download_models.gradle ، وتوفر فئة ObjectDetectorHelper محددًا للنماذج:

val modelName =
  when (currentModel) {
    MODEL_MOBILENETV1 -> "mobilenetv1.tflite"
    MODEL_EFFICIENTDETV0 -> "efficientdet-lite0.tflite"
    MODEL_EFFICIENTDETV1 -> "efficientdet-lite1.tflite"
    MODEL_EFFICIENTDETV2 -> "efficientdet-lite2.tflite"
    else -> "mobilenetv1.tflite"
  }

لتهيئة النموذج في تطبيقك:

  1. أضف ملف نموذج .tflite إلى دليل src/main/assets لمشروع التطوير الخاص بك، مثل: EfficientDet-Lite0 .
  2. قم بتعيين متغير ثابت لاسم ملف النموذج الخاص بك. في تطبيق المثال، يمكنك تعيين متغير modelName إلى MODEL_EFFICIENTDETV0 لاستخدام نموذج الكشف EfficientDet-Lite0.
  3. قم بتعيين خيارات النموذج، مثل عتبة التنبؤ وحجم مجموعة النتائج واختياريًا، تفويضات تسريع الأجهزة:

    val optionsBuilder =
      ObjectDetector.ObjectDetectorOptions.builder()
        .setScoreThreshold(threshold)
        .setMaxResults(maxResults)
    
  4. استخدم الإعدادات من هذا الكائن لإنشاء كائن TensorFlow Lite ObjectDetector الذي يحتوي على النموذج:

    objectDetector =
      ObjectDetector.createFromFileAndOptions(
        context, modelName, optionsBuilder.build())
    

يقوم setupObjectDetector بإعداد معلمات النموذج التالية:

  • عتبة الكشف
  • الحد الأقصى لعدد نتائج الكشف
  • عدد سلاسل المعالجة المطلوب استخدامها ( BaseOptions.builder().setNumThreads(numThreads) )
  • النموذج الفعلي ( modelName )
  • كائن كاشف الكائنات ( objectDetector )

تكوين مسرع الأجهزة

عند تهيئة نموذج TensorFlow Lite في تطبيقك، يمكنك استخدام ميزات تسريع الأجهزة لتسريع حسابات التنبؤ للنموذج.

مندوبو TensorFlow Lite عبارة عن وحدات برمجية تعمل على تسريع تنفيذ نماذج التعلم الآلي باستخدام أجهزة معالجة متخصصة على جهاز محمول، مثل وحدات معالجة الرسومات (GPUs) ووحدات معالجة Tensor (TPUs) ومعالجات الإشارات الرقمية (DSPs). يوصى باستخدام المفوضين لتشغيل نماذج TensorFlow Lite، ولكنه غير مطلوب.

تتم تهيئة كاشف الكائنات باستخدام الإعدادات الحالية على مؤشر الترابط الذي يستخدمه. يمكنك استخدام مفوضي وحدة المعالجة المركزية (CPU) و NNAPI مع أجهزة الكشف التي تم إنشاؤها على مؤشر الترابط الرئيسي واستخدامها في مؤشر ترابط الخلفية، ولكن يجب أن يستخدم مؤشر الترابط الذي قام بتهيئة الكاشف مفوض GPU.

يتم تعيين المفوضين ضمن الدالة ObjectDetectionHelper.setupObjectDetector() :

when (currentDelegate) {
    DELEGATE_CPU -> {
        // Default
    }
    DELEGATE_GPU -> {
        if (CompatibilityList().isDelegateSupportedOnThisDevice) {
            baseOptionsBuilder.useGpu()
        } else {
            objectDetectorListener?.onError("GPU is not supported on this device")
        }
    }
    DELEGATE_NNAPI -> {
        baseOptionsBuilder.useNnapi()
    }
}

لمزيد من المعلومات حول استخدام مندوبي تسريع الأجهزة مع TensorFlow Lite، راجع مندوبي TensorFlow Lite .

تحضير البيانات للنموذج

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

يقبل نموذج EfficientDet-Lite0 المستخدم في مثال التعليمات البرمجية هذا Tensors التي تمثل صورًا بأبعاد 320 × 320، مع ثلاث قنوات (أحمر وأزرق وأخضر) لكل بكسل. كل قيمة في الموتر هي بايت واحد بين 0 و255. لذلك، لتشغيل التنبؤات على الصور الجديدة، يجب أن يقوم تطبيقك بتحويل بيانات الصورة إلى كائنات بيانات Tensor بهذا الحجم والشكل. تتولى واجهة برمجة التطبيقات Vision API الخاصة بمكتبة المهام TensorFlow Lite عملية تحويل البيانات نيابةً عنك.

يستخدم التطبيق كائن ImageAnalysis لسحب الصور من الكاميرا. يستدعي هذا الكائن وظيفة detectObject ذات الصورة النقطية من الكاميرا. يتم تغيير حجم البيانات وتدويرها تلقائيًا بواسطة ImageProcessor بحيث تلبي متطلبات بيانات الصورة الخاصة بالنموذج. ثم تتم ترجمة الصورة إلى كائن TensorImage .

لإعداد البيانات من النظام الفرعي للكاميرا لتتم معالجتها بواسطة نموذج ML:

  1. أنشئ كائن ImageAnalysis لاستخراج الصور بالتنسيق المطلوب:

    imageAnalyzer =
        ImageAnalysis.Builder()
            .setTargetAspectRatio(AspectRatio.RATIO_4_3)
            .setTargetRotation(fragmentCameraBinding.viewFinder.display.rotation)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .setOutputImageFormat(OUTPUT_IMAGE_FORMAT_RGBA_8888)
            .build()
            ...
    
  2. قم بتوصيل المحلل بالنظام الفرعي للكاميرا وإنشاء مخزن مؤقت للصورة النقطية لاحتواء البيانات الواردة من الكاميرا:

    .also {
      it.setAnalyzer(cameraExecutor) {
        image -> if (!::bitmapBuffer.isInitialized)
        { bitmapBuffer = Bitmap.createBitmap( image.width, image.height,
        Bitmap.Config.ARGB_8888 ) } detectObjects(image)
        }
      }
    
  3. قم باستخراج بيانات الصورة المحددة التي يحتاجها النموذج، وقم بتمرير معلومات تدوير الصورة:

    private fun detectObjects(image: ImageProxy) {
      //Copy out RGB bits to the shared bitmap buffer
      image.use {bitmapBuffer.copyPixelsFromBuffer(image.planes[0].buffer) }
        val imageRotation = image.imageInfo.rotationDegrees
        objectDetectorHelper.detect(bitmapBuffer, imageRotation)
      }
    
  4. أكمل أي تحويلات نهائية للبيانات وأضف بيانات الصورة إلى كائن TensorImage ، كما هو موضح في طريقة ObjectDetectorHelper.detect() للتطبيق المثال:

    val imageProcessor = ImageProcessor.Builder().add(Rot90Op(-imageRotation / 90)).build()
    // Preprocess the image and convert it into a TensorImage for detection.
    val tensorImage = imageProcessor.process(TensorImage.fromBitmap(image))
    

تشغيل التوقعات

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

في فئة fragments/CameraFragment.kt من التطبيق المثال، يقوم كائن imageAnalyzer داخل وظيفة bindCameraUseCases بتمرير البيانات تلقائيًا إلى النموذج للتنبؤات عندما يكون التطبيق متصلاً بالكاميرا.

يستخدم التطبيق طريقة cameraProvider.bindToLifecycle() للتعامل مع محدد الكاميرا ونافذة المعاينة ومعالجة نموذج ML. تقوم فئة ObjectDetectorHelper.kt بمعالجة تمرير بيانات الصورة إلى النموذج. لتشغيل النموذج وإنشاء تنبؤات من بيانات الصورة:

  • قم بتشغيل التنبؤ عن طريق تمرير بيانات الصورة إلى وظيفة التنبؤ الخاصة بك:

    val results = objectDetector?.detect(tensorImage)
    

يتلقى كائن TensorFlow Lite Interpreter هذه البيانات، ويقوم بتشغيلها على النموذج، وينتج قائمة من التنبؤات. للمعالجة المستمرة للبيانات بواسطة النموذج، استخدم طريقة runForMultipleInputsOutputs() بحيث لا يتم إنشاء كائنات المترجم الفوري ثم إزالتها بواسطة النظام لكل تشغيل تنبؤ.

التعامل مع إخراج النموذج

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

يختلف مخرج أي نموذج TensorFlow Lite من حيث عدد التنبؤات التي ينتجها (واحد أو أكثر)، والمعلومات الوصفية لكل تنبؤ. في حالة نموذج اكتشاف الكائن، تتضمن التنبؤات عادةً بيانات للمربع المحيط الذي يشير إلى مكان اكتشاف الكائن في الصورة. في كود المثال، يتم تمرير النتائج إلى وظيفة onResults في CameraFragment.kt ، والتي تعمل بمثابة DetectorListener في عملية اكتشاف الكائنات.

interface DetectorListener {
  fun onError(error: String)
  fun onResults(
    results: MutableList<Detection>?,
    inferenceTime: Long,
    imageHeight: Int,
    imageWidth: Int
  )
}

بالنسبة للنموذج المستخدم في هذا المثال، يتضمن كل تنبؤ موقع المربع المحيط للكائن، وتسمية للكائن، ودرجة تنبؤ بين 0 و1 باعتبارها Float تمثل ثقة التنبؤ، حيث يمثل 1 أعلى تصنيف للثقة . بشكل عام، تعتبر التنبؤات التي تقل نتيجتها عن 50% (0.5) غير حاسمة. ومع ذلك، فإن كيفية التعامل مع نتائج التنبؤ ذات القيمة المنخفضة أمر متروك لك ولاحتياجات تطبيقك.

للتعامل مع نتائج التنبؤ بالنموذج:

  1. استخدم نمط المستمع لتمرير النتائج إلى رمز التطبيق الخاص بك أو كائنات واجهة المستخدم. يستخدم تطبيق المثال هذا النمط لتمرير نتائج الكشف من كائن ObjectDetectorHelper إلى كائن CameraFragment :

    objectDetectorListener.onResults(
    // instance of CameraFragment
        results,
        inferenceTime,
        tensorImage.height,
        tensorImage.width)
    
  2. التصرف بناءً على النتائج، مثل عرض التنبؤ للمستخدم. يرسم المثال تراكبًا على كائن CameraPreview لإظهار النتيجة:

    override fun onResults(
      results: MutableList<Detection>?,
      inferenceTime: Long,
      imageHeight: Int,
      imageWidth: Int
    ) {
        activity?.runOnUiThread {
            fragmentCameraBinding.bottomSheetLayout.inferenceTimeVal.text =
                String.format("%d ms", inferenceTime)
    
            // Pass necessary information to OverlayView for drawing on the canvas
            fragmentCameraBinding.overlay.setResults(
                results ?: LinkedList<Detection>(),
                imageHeight,
                imageWidth
            )
    
            // Force a redraw
            fragmentCameraBinding.overlay.invalidate()
        }
    }
    

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

الخطوات التالية

  • استكشف الاستخدامات المختلفة لـ TensorFlow Lite في الأمثلة .
  • تعرف على المزيد حول استخدام نماذج التعلم الآلي مع TensorFlow Lite في قسم النماذج .
  • تعرف على المزيد حول تنفيذ التعلم الآلي في تطبيق الهاتف المحمول الخاص بك في دليل مطور TensorFlow Lite .