В этом руководстве показано, как создать приложение 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 и запуска примера приложения.
Чтобы клонировать и настроить пример кода:
- Клонируйте репозиторий git
git clone https://github.com/tensorflow/examples.git
- При желании настройте свой экземпляр git на использование разреженной проверки, чтобы у вас были только файлы для примера приложения для обнаружения объектов:
cd examples git sparse-checkout init --cone git sparse-checkout set lite/examples/object_detection/android
Импортируйте и запустите проект
Создайте проект на основе загруженного примера кода, соберите его и запустите.
Чтобы импортировать и построить проект примера кода:
- Запустите Android-студию .
- В Android Studio выберите «Файл» > «Создать» > «Импортировать проект» .
- Перейдите в каталог примера кода, содержащий файл build.gradle (
.../examples/lite/examples/object_detection/android/build.gradle
), и выберите этот каталог. - Если Android Studio запрашивает синхронизацию Gradle, выберите «ОК».
- Убедитесь, что ваше устройство Android подключено к компьютеру и включен режим разработчика. Нажмите зеленую стрелку
Run
.
Если вы выберете правильный каталог, Android Studio создаст новый проект и соберет его. Этот процесс может занять несколько минут, в зависимости от скорости вашего компьютера и того, использовали ли вы Android Studio для других проектов. По завершении сборки Android Studio отображает сообщение BUILD SUCCESSFUL
на панели состояния вывода сборки .
Необязательно: Чтобы исправить ошибки сборки, обновив версию плагина Android:
- Откройте файл build.gradle в каталоге проекта.
Измените версию инструментов Android следующим образом:
// from: classpath 'com.android.tools.build:gradle:4.2.2' // to: classpath 'com.android.tools.build:gradle:4.1.2'
Синхронизируйте проект, выбрав: «Файл» > «Синхронизировать проект с файлами Gradle» .
Чтобы запустить проект:
- В Android Studio запустите проект, выбрав «Выполнить» > «Выполнить…» .
- Выберите подключенное устройство Android с камерой, чтобы протестировать приложение.
В следующих разделах показаны изменения, которые необходимо внести в существующий проект, чтобы добавить эту функциональность в ваше собственное приложение, используя этот пример приложения в качестве ориентира.
Добавить зависимости проекта
В вашем собственном приложении вы должны добавить определенные зависимости проекта для запуска моделей машинного обучения TensorFlow Lite и получить доступ к служебным функциям, которые преобразуют данные, такие как изображения, в формат тензорных данных, который может обрабатываться используемой вами моделью.
В примере приложения используется библиотека задач TensorFlow Lite для машинного зрения , позволяющая выполнять модель машинного обучения для обнаружения объектов. Следующие инструкции объясняют, как добавить необходимые зависимости библиотеки в ваш собственный проект приложения Android.
Следующие инструкции объясняют, как добавить необходимый проект и зависимости модулей в ваш собственный проект приложения Android.
Чтобы добавить зависимости модуля:
В модуле, использующем 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
) предоставляет список совместимости.В 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"
}
Чтобы инициализировать модель в вашем приложении:
- Добавьте файл модели
.tflite
в каталогsrc/main/assets
вашего проекта разработки, например: EfficientDet-Lite0 . - Установите статическую переменную для имени файла вашей модели. В примере приложения вы устанавливаете для переменной
modelName
значениеMODEL_EFFICIENTDETV0
, чтобы использовать модель обнаружения EfficientDet-Lite0. Установите параметры модели, такие как порог прогнозирования, размер набора результатов и, при необходимости, делегаты аппаратного ускорения:
val optionsBuilder = ObjectDetector.ObjectDetectorOptions.builder() .setScoreThreshold(threshold) .setMaxResults(maxResults)
Используйте настройки этого объекта для создания объекта
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:
Создайте объект
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() ...
Подключите анализатор к подсистеме камеры и создайте растровый буфер для хранения данных, полученных от камеры:
.also { it.setAnalyzer(cameraExecutor) { image -> if (!::bitmapBuffer.isInitialized) { bitmapBuffer = Bitmap.createBitmap( image.width, image.height, Bitmap.Config.ARGB_8888 ) } detectObjects(image) } }
Извлеките конкретные данные изображения, необходимые модели, и передайте информацию о повороте изображения:
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) }
Завершите все окончательные преобразования данных и добавьте данные изображения в объект
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) считаются неубедительными. Однако то, как вы обрабатываете результаты прогнозирования с низким значением, зависит от вас и потребностей вашего приложения.
Чтобы обработать результаты прогнозирования модели:
Используйте шаблон прослушивателя для передачи результатов в код вашего приложения или объекты пользовательского интерфейса. В примере приложения этот шаблон используется для передачи результатов обнаружения из объекта
ObjectDetectorHelper
в объектCameraFragment
:objectDetectorListener.onResults( // instance of CameraFragment results, inferenceTime, tensorImage.height, tensorImage.width)
Действуйте в соответствии с результатами, например отображая прогноз пользователю. В примере рисуется наложение на объект 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 .