Firebase is back at Google I/O on May 10! Register now

Обнаружение объектов на изображениях с помощью модели, обученной 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. Извлеките модель из zip-архива, загруженного из Google Cloud Console.
  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 .

    Если вы используете старый API камеры, захватывайте изображения в формате ImageFormat.NV21 .