Обнаружение объектов с помощью Android

В этом руководстве показано, как создать приложение 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. Запустите Android-студию .
  2. В Android Studio выберите «Файл» > «Создать» > «Импортировать проект» .
  3. Перейдите в каталог примера кода, содержащий файл build.gradle ( .../examples/lite/examples/object_detection/android/build.gradle ), и выберите этот каталог.
  4. Если Android Studio запрашивает синхронизацию Gradle, выберите «ОК».
  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. Синхронизируйте проект, выбрав: «Файл» > «Синхронизировать проект с файлами Gradle» .

Чтобы запустить проект:

  1. В Android Studio запустите проект, выбрав «Выполнить» > «Выполнить…» .
  2. Выберите подключенное устройство Android с камерой, чтобы протестировать приложение.

В следующих разделах показаны изменения, которые необходимо внести в существующий проект, чтобы добавить эту функциональность в ваше собственное приложение, используя этот пример приложения в качестве ориентира.

Добавить зависимости проекта

В вашем собственном приложении вы должны добавить определенные зависимости проекта для запуска моделей машинного обучения TensorFlow Lite и получить доступ к служебным функциям, которые преобразуют данные, такие как изображения, в формат тензорных данных, который может обрабатываться используемой вами моделью.

В примере приложения используется библиотека задач TensorFlow Lite для машинного зрения , позволяющая выполнять модель машинного обучения для обнаружения объектов. Следующие инструкции объясняют, как добавить необходимые зависимости библиотеки в ваш собственный проект приложения 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 ) предоставляет инфраструктуру для запуска приложения на графическом процессоре, а Delegate ( tensorflow-lite-gpu ) предоставляет список совместимости.

  2. В Android Studio синхронизируйте зависимости проекта, выбрав « Файл» > «Синхронизировать проект с файлами Gradle» .

Инициализируйте модель машинного обучения

В своем приложении для 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. Используйте настройки этого объекта для создания объекта ObjectDetector TensorFlow Lite, содержащего модель:

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

setupObjectDetector устанавливает следующие параметры модели:

  • Порог обнаружения
  • Максимальное количество результатов обнаружения
  • Количество используемых потоков обработки ( BaseOptions.builder().setNumThreads(numThreads) )
  • Фактическая модель ( modelName )
  • Объект ObjectDetector ( objectDetector )

Настроить аппаратный ускоритель

При инициализации модели TensorFlow Lite в вашем приложении вы можете использовать функции аппаратного ускорения, чтобы ускорить прогнозные расчеты модели.

Делегаты TensorFlow Lite — это программные модули, которые ускоряют выполнение моделей машинного обучения с использованием специализированного оборудования обработки на мобильном устройстве, такого как графические процессоры (GPU), тензорные процессоры (TPU) и процессоры цифровых сигналов (DSP). Использование делегатов для запуска моделей 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, который может обрабатываться вашей моделью. Данные в тензоре, которые вы передаете в модель, должны иметь определенные размеры или форму, соответствующие формату данных, используемых для обучения модели.

Модель EfficientDet-Lite0 , используемая в этом примере кода, принимает тензоры, представляющие изображения размером 320 x 320 с тремя каналами (красным, синим и зеленым) на пиксель. Каждое значение в тензоре представляет собой один байт от 0 до 255. Таким образом, чтобы выполнить прогнозирование новых изображений, ваше приложение должно преобразовать данные этого изображения в объекты данных тензора такого размера и формы. API Vision библиотеки задач 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() для управления выбором камеры, окном предварительного просмотра и обработкой модели машинного обучения. Класс ObjectDetectorHelper.kt обрабатывает передачу данных изображения в модель. Чтобы запустить модель и сгенерировать прогнозы на основе данных изображения:

  • Запустите прогноз, передав данные изображения в функцию прогнозирования:

    val results = objectDetector?.detect(tensorImage)
    

Объект интерпретатора TensorFlow Lite получает эти данные, сравнивает их с моделью и создает список прогнозов. Для непрерывной обработки данных моделью используйте метод runForMultipleInputsOutputs() , чтобы объекты Interpreter не создавались, а затем удалялись системой при каждом прогоне прогнозирования.

Обработка вывода модели

В вашем приложении 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 в виде числа с плавающей запятой, представляющего достоверность прогноза, где 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 .