اكتشف الكائنات في الصور باستخدام نموذج مدرب على AutoML على Android

بعد تدريب النموذج الخاص بك باستخدام AutoML Vision Edge ، يمكنك استخدامه في تطبيقك لاكتشاف الكائنات في الصور.

هناك طريقتان لدمج النماذج التي تم تدريبها من AutoML Vision Edge: يمكنك تجميع النموذج عن طريق وضعه داخل مجلد أصول التطبيق الخاص بك، أو يمكنك تنزيله ديناميكيًا من Firebase.

خيارات تجميع النماذج
المجمعة في التطبيق الخاص بك
  • يعد النموذج جزءًا من ملف APK لتطبيقك
  • النموذج متاح على الفور، حتى عندما يكون جهاز Android غير متصل بالإنترنت
  • ليست هناك حاجة لمشروع Firebase
مستضاف مع Firebase
  • قم باستضافة النموذج عن طريق تحميله إلى Firebase Machine Learning
  • يقلل حجم APK
  • يتم تنزيل النموذج عند الطلب
  • دفع تحديثات النموذج دون إعادة نشر تطبيقك
  • اختبار A/B سهل باستخدام Firebase Remote Config
  • يتطلب مشروع Firebase

قبل ان تبدأ

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

  2. أضف تبعيات مكتبة المهام TensorFlow Lite إلى ملف gradle على مستوى التطبيق الخاص بوحدتك، والذي عادةً ما يكون app/build.gradle :

    لتجميع نموذج مع تطبيقك:

    dependencies {
      // ...
      // Object detection with a bundled Auto ML model
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly-SNAPSHOT'
    }
    

    لتنزيل نموذج ديناميكيًا من Firebase، أضف أيضًا تبعية Firebase ML:

    dependencies {
      // ...
      // Object detection with an Auto ML model deployed to Firebase
      implementation platform('com.google.firebase:firebase-bom:26.1.1')
      implementation 'com.google.firebase:firebase-ml-model-interpreter'
    
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly'
    }
    

1. قم بتحميل النموذج

تكوين مصدر نموذج محلي

لتجميع النموذج مع تطبيقك:

  1. قم باستخراج النموذج من الأرشيف المضغوط الذي قمت بتنزيله من وحدة تحكم Google Cloud.
  2. قم بتضمين النموذج الخاص بك في حزمة التطبيق الخاص بك:
    1. إذا لم يكن لديك مجلد أصول في مشروعك، فقم بإنشاء واحد عن طريق النقر بزر الماوس الأيمن فوق app/ المجلد، ثم النقر فوق جديد > مجلد > مجلد الأصول .
    2. انسخ ملف نموذج tflite الخاص بك مع البيانات التعريفية المضمنة إلى مجلد الأصول.
  3. أضف ما يلي إلى ملف build.gradle الخاص بالتطبيق الخاص بك للتأكد من أن Gradle لا يقوم بضغط ملف النموذج عند إنشاء التطبيق:

    android {
        // ...
        aaptOptions {
            noCompress "tflite"
        }
    }
    

    سيتم تضمين ملف النموذج في حزمة التطبيق وسيكون متاحًا كأصل أولي.

قم بتكوين مصدر نموذج مستضاف على Firebase

لاستخدام النموذج المستضاف عن بعد، قم بإنشاء كائن RemoteModel ، مع تحديد الاسم الذي قمت بتعيينه للنموذج عند نشره:

جافا

// Specify the name you assigned when you deployed the model.
FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();

كوتلين

// Specify the name you assigned when you deployed the model.
val remoteModel =
    FirebaseCustomRemoteModel.Builder("your_model_name").build()

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

جافا

DownloadConditions downloadConditions = new DownloadConditions.Builder()
        .requireWifi()
        .build();
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(@NonNull Task<Void> task) {
                // Success.
            }
        });

كوتلين

val downloadConditions = DownloadConditions.Builder()
    .requireWifi()
    .build()
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
    .addOnSuccessListener {
        // Success.
    }

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

قم بإنشاء كاشف كائن من النموذج الخاص بك

بعد تكوين مصادر النموذج الخاص بك، قم بإنشاء كائن ObjectDetector من أحد هذه المصادر.

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

جافا

// Initialization
ObjectDetectorOptions options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build();
ObjectDetector objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options);

كوتلين

// Initialization
val options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build()
val objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options)

إذا كان لديك نموذج مستضاف عن بعد، فسيتعين عليك التحقق من تنزيله قبل تشغيله. يمكنك التحقق من حالة مهمة تنزيل النموذج باستخدام طريقة isModelDownloaded() الخاصة بمدير النموذج.

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

جافا

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean isDownloaded) {
            }
        });

كوتلين

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener { success ->

        }

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

بمجرد معرفة أنه تم تنزيل النموذج الخاص بك، قم بإنشاء كاشف كائن من ملف النموذج:

جافا

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnCompleteListener(new OnCompleteListener<File>() {
            @Override
            public void onComplete(@NonNull Task<File> task) {
                File modelFile = task.getResult();
                if (modelFile != null) {
                    ObjectDetectorOptions options = ObjectDetectorOptions.builder()
                            .setScoreThreshold(0)
                            .build();
                    objectDetector = ObjectDetector.createFromFileAndOptions(
                            getApplicationContext(), modelFile.getPath(), options);
                }
            }
        });

كوتلين

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnSuccessListener { modelFile ->
            val options = ObjectDetectorOptions.builder()
                    .setScoreThreshold(0f)
                    .build()
            objectDetector = ObjectDetector.createFromFileAndOptions(
                    applicationContext, modelFile.path, options)
        }

2. قم بإعداد صورة الإدخال

بعد ذلك، لكل صورة تريد تصنيفها، قم بإنشاء كائن TensorImage من صورتك. يمكنك إنشاء كائن TensorImage من Bitmap باستخدام طريقة fromBitmap :

جافا

TensorImage image = TensorImage.fromBitmap(bitmap);

كوتلين

val image = TensorImage.fromBitmap(bitmap)

إذا لم تكن بيانات صورتك موجودة في Bitmap ، فيمكنك تحميل مصفوفة بكسل كما هو موضح في مستندات TensorFlow Lite .

3. قم بتشغيل كاشف الأشياء

للكشف عن كائنات في صورة ما، قم بتمرير كائن TensorImage إلى طريقة detect() الخاصة بـ ObjectDetector .

جافا

List<Detection> results = objectDetector.detect(image);

كوتلين

val results = objectDetector.detect(image)

4. احصل على معلومات حول الكائنات ذات العلامات

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

على سبيل المثال:

جافا

for (Detection result : results) {
    RectF bounds = result.getBoundingBox();
    List<Category> labels = result.getCategories();
}

كوتلين

for (result in results) {
    val bounds = result.getBoundingBox()
    val labels = result.getCategories()
}

نصائح لتحسين الأداء في الوقت الحقيقي

إذا كنت تريد تصنيف الصور في تطبيق في الوقت الفعلي، فاتبع هذه الإرشادات لتحقيق أفضل معدلات الإطارات:

  • خنق المكالمات إلى ملصق الصورة. إذا أصبح إطار فيديو جديد متاحًا أثناء تشغيل أداة تسمية الصورة، فقم بإسقاط الإطار. راجع فئة VisionProcessorBase في نموذج تطبيق التشغيل السريع للحصول على مثال.
  • إذا كنت تستخدم مخرجات أداة تسمية الصور لتراكب الرسومات على الصورة المدخلة، فاحصل أولاً على النتيجة، ثم قم بعرض الصورة والتراكب في خطوة واحدة. من خلال القيام بذلك، يمكنك العرض على سطح العرض مرة واحدة فقط لكل إطار إدخال. راجع فئتي CameraSourcePreview و GraphicOverlay في نموذج التطبيق السريع للحصول على مثال.
  • إذا كنت تستخدم Camera2 API، فالتقط الصور بتنسيق ImageFormat.YUV_420_888 .

    إذا كنت تستخدم واجهة برمجة تطبيقات الكاميرا الأقدم، فالتقط الصور بتنسيق ImageFormat.NV21 .