تشخیص اشیاء در تصاویر با یک مدل آموزش دیده با AutoML در Android

پس از اینکه مدل خود را با استفاده از AutoML Vision Edge آموزش دادید ، می‌توانید از آن در برنامه خود برای تشخیص اشیاء در تصاویر استفاده کنید.

دو راه برای ادغام مدل‌های آموزش‌دیده از AutoML Vision Edge وجود دارد: می‌توانید مدل را با قرار دادن آن در پوشه asset برنامه خود، به صورت دسته‌ای (bundle) درآورید، یا می‌توانید آن را به صورت پویا از Firebase دانلود کنید.

گزینه‌های بسته‌بندی مدل
در برنامه شما گنجانده شده است
  • مدل بخشی از APK برنامه شما است
  • این مدل بلافاصله در دسترس است، حتی زمانی که دستگاه اندروید آفلاین باشد
  • نیازی به پروژه Firebase نیست
میزبانی شده با فایربیس
  • با آپلود مدل در Firebase Machine Learning، آن را میزبانی کنید.
  • حجم APK را کاهش می‌دهد
  • مدل بر اساس تقاضا دانلود می‌شود
  • به‌روزرسانی‌های مدل را بدون انتشار مجدد برنامه خود، ارسال کنید
  • تست A/B آسان با پیکربندی از راه دور Firebase
  • نیاز به یک پروژه Firebase دارد

قبل از اینکه شروع کنی

  1. اگر می‌خواهید یک مدل را دانلود کنید ، اگر قبلاً Firebase را به پروژه اندروید خود اضافه نکرده‌اید، حتماً آن را اضافه کنید. این کار هنگام بسته‌بندی مدل لازم نیست.

  2. وابستگی‌های کتابخانه TensorFlow Lite Task را به فایل gradle سطح app ماژول خود که معمولاً 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. مدل را از آرشیو زیپی که از کنسول Google Cloud دانلود کرده‌اید، استخراج کنید.
  2. مدل خود را در بسته برنامه خود قرار دهید:
    1. اگر پوشه assets را در پروژه خود ندارید، با کلیک راست روی app/ folder و سپس کلیک روی New > Folder > Assets Folder، یکی ایجاد کنید.
    2. فایل مدل tflite خود را به همراه متادیتای تعبیه‌شده در آن، در پوشه assets کپی کنید.
  3. برای اطمینان از اینکه Gradle هنگام ساخت برنامه، فایل مدل را فشرده نمی‌کند، موارد زیر را به فایل build.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() در model manager بررسی کنید.

اگرچه شما فقط باید قبل از اجرای آشکارساز شیء این موضوع را تأیید کنید، اما اگر هم یک مدل میزبانی از راه دور و هم یک مدل بسته‌بندی شده محلی دارید، انجام این بررسی هنگام نمونه‌سازی آشکارساز شیء منطقی است: اگر مدل از راه دور دانلود شده است، یک آشکارساز شیء از آن و در غیر این صورت از مدل محلی ایجاد کنید.

جاوا

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

کاتلین

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

        }

اگر فقط یک مدل میزبانی‌شده از راه دور دارید، باید قابلیت‌های مرتبط با مدل را غیرفعال کنید - برای مثال، بخشی از رابط کاربری خود را خاکستری کنید یا پنهان کنید - تا زمانی که تأیید کنید مدل دانلود شده است. می‌توانید این کار را با اتصال یک شنونده به متد download() در model manager انجام دهید.

وقتی مطمئن شدید مدل شما دانلود شده است، یک آشکارساز شیء از فایل مدل ایجاد کنید:

جاوا

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

۲. تصویر ورودی را آماده کنید

سپس، برای هر تصویری که می‌خواهید برچسب‌گذاری کنید، یک شیء TensorImage از تصویر خود ایجاد کنید. می‌توانید با استفاده از متد fromBitmap ، یک شیء TensorImage از یک Bitmap ایجاد کنید:

جاوا

TensorImage image = TensorImage.fromBitmap(bitmap);

کاتلین

val image = TensorImage.fromBitmap(bitmap)

اگر داده‌های تصویر شما به صورت Bitmap نیست، می‌توانید یک آرایه پیکسلی را همانطور که در مستندات TensorFlow Lite نشان داده شده است، بارگذاری کنید.

۳. آشکارساز شیء را اجرا کنید

برای تشخیص اشیاء در یک تصویر، شیء TensorImage را به متد detect() در ObjectDetector ارسال کنید.

جاوا

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

کاتلین

val results = objectDetector.detect(image)

۴. اطلاعات مربوط به اشیاء برچسب‌گذاری شده را دریافت کنید

اگر عملیات تشخیص شیء با موفقیت انجام شود، فهرستی از اشیاء 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()
}

نکاتی برای بهبود عملکرد در زمان واقعی

اگر می‌خواهید تصاویر را در یک برنامه‌ی بلادرنگ برچسب‌گذاری کنید، برای دستیابی به بهترین نرخ فریم، این دستورالعمل‌ها را دنبال کنید:

  • فراخوانی Throttle به برچسب‌گذار تصویر. اگر در حین اجرای برچسب‌گذار تصویر، فریم ویدیویی جدیدی در دسترس قرار گرفت، فریم را حذف کنید. برای مثال به کلاس VisionProcessorBase در برنامه نمونه شروع سریع مراجعه کنید.
  • اگر از خروجی برچسب‌گذار تصویر برای همپوشانی گرافیک‌ها روی تصویر ورودی استفاده می‌کنید، ابتدا نتیجه را دریافت کنید، سپس تصویر و همپوشانی را در یک مرحله رندر کنید. با انجام این کار، برای هر فریم ورودی فقط یک بار روی سطح نمایشگر رندر می‌کنید. برای مثال به کلاس‌های CameraSourcePreview و GraphicOverlay در برنامه نمونه شروع سریع مراجعه کنید.
  • اگر از API دوربین ۲ استفاده می‌کنید، تصاویر را با فرمت ImageFormat.YUV_420_888 ثبت کنید.

    اگر از API دوربین قدیمی‌تر استفاده می‌کنید، تصاویر را با فرمت ImageFormat.NV21 ضبط کنید.