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

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

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

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

قبل از شروع

  1. اگر می خواهید مدلی را دانلود کنید ، مطمئن شوید که Firebase را به پروژه اندروید خود اضافه کرده اید، اگر قبلاً این کار را انجام نداده اید. هنگامی که مدل را بسته بندی می کنید، این مورد نیاز نیست.

  2. وابستگی‌های کتابخانه TensorFlow Lite Task را به فایل 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. مدل را از بایگانی zip که از کنسول Google Cloud دانلود کرده اید استخراج کنید.
  2. مدل خود را در بسته برنامه خود قرار دهید:
    1. اگر در پروژه خود پوشه دارایی ندارید، با کلیک راست روی app/ برنامه، سپس روی New > Folder > Assets Folder کلیک کنید.
    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 بگیرید.

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