Быстрый старт для Android

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

Анимированная демонстрация обнаружения объектов

Настройка и запуск примера

Для первой части этого упражнения загрузите пример кода с GitHub и запустите его с помощью Android Studio . В следующих разделах этого документа рассматриваются соответствующие разделы примера кода, чтобы вы могли применить их к своим собственным приложениям Android. Вам необходимо установить следующие версии этих инструментов:

  • Android Studio 4.2 или выше
  • Android SDK версии 21 или выше

Получить пример кода

Создайте локальную копию кода примера, чтобы его можно было собрать и запустить.

Чтобы клонировать и настроить пример кода:

  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_play_services
    

Импортируйте и запустите проект

Используйте Android Studio, чтобы создать проект на основе загруженного примера кода, собрать проект и запустить его.

Чтобы импортировать и построить проект примера кода:

  1. Запустите Android-студию .
  2. На странице приветствия Android Studio выберите «Импортировать проект» или выберите «Файл» > «Создать» > «Импортировать проект» .
  3. Перейдите в каталог примера кода, содержащий файл build.gradle ( ...examples/lite/examples/object_detection/android_play_services/build.gradle ), и выберите этот каталог.

После того, как вы выберете этот каталог, Android Studio создаст новый проект и соберет его. По завершении сборки Android Studio отображает сообщение BUILD SUCCESSFUL на панели состояния вывода сборки .

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

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

Как работает пример приложения

В примере приложения используется предварительно обученная модель обнаружения объектов, такая как mobilenetv1.tflite , в формате TensorFlow Lite для поиска объектов в прямом видеопотоке с камеры устройства Android. Код этой функции в основном находится в следующих файлах:

  • ObjectDetectorHelper.kt — инициализирует среду выполнения, включает аппаратное ускорение и запускает модель машинного обучения для обнаружения объектов.
  • CameraFragment.kt — создает поток данных изображения камеры, подготавливает данные для модели и отображает результаты обнаружения объектов.

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

Создайте приложение

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

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

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

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

Чтобы добавить зависимости модуля:

  1. В модуле приложения Android, использующем TensorFlow Lite, обновите файл build.gradle модуля, включив в него следующие зависимости. В примере кода этот файл находится здесь: ...examples/lite/examples/object_detection/android_play_services/app/build.gradle

    ...
    dependencies {
    ...
        // Tensorflow Lite dependencies
        implementation 'org.tensorflow:tensorflow-lite-task-vision-play-services:0.4.2'
        implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    ...
    }
    
  2. В Android Studio синхронизируйте зависимости проекта, выбрав « Файл» > «Синхронизировать проект с файлами Gradle» .

Инициализируйте сервисы Google Play

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

Чтобы инициализировать TensorFlow Lite с помощью сервисов Google Play:

  1. Создайте объект TfLiteInitializationOptions и измените его, чтобы включить поддержку графического процессора:

    val options = TfLiteInitializationOptions.builder()
        .setEnableGpuDelegateSupport(true)
        .build()
    
  2. Используйте метод TfLiteVision.initialize() , чтобы включить использование среды выполнения служб Play, и настройте прослушиватель для проверки успешной загрузки:

    TfLiteVision.initialize(context, options).addOnSuccessListener {
        objectDetectorListener.onInitialized()
    }.addOnFailureListener {
        // Called if the GPU Delegate is not supported on the device
        TfLiteVision.initialize(context).addOnSuccessListener {
            objectDetectorListener.onInitialized()
        }.addOnFailureListener{
            objectDetectorListener.onError("TfLiteVision failed to initialize: "
                    + it.message)
        }
    }
    

Инициализируйте интерпретатор модели ML

Инициализируйте интерпретатор модели машинного обучения TensorFlow Lite, загрузив файл модели и задав параметры модели. Модель TensorFlow Lite включает файл .tflite , содержащий код модели. Вам следует хранить свои модели в каталоге src/main/assets вашего проекта разработки, например:

.../src/main/assets/mobilenetv1.tflite`

Чтобы инициализировать модель:

  1. Добавьте файл модели .tflite в каталог src/main/assets вашего проекта разработки, например ssd_mobilenet_v1 .
  2. Задайте переменную modelName , чтобы указать имя файла вашей модели ML:

    val modelName = "mobilenetv1.tflite"
    
  3. Установите параметры модели, такие как порог прогнозирования и размер набора результатов:

    val optionsBuilder =
        ObjectDetector.ObjectDetectorOptions.builder()
            .setScoreThreshold(threshold)
            .setMaxResults(maxResults)
    
  4. Включите ускорение графического процессора с помощью параметров и разрешите корректный сбой кода, если ускорение не поддерживается на устройстве:

    try {
        optionsBuilder.useGpu()
    } catch(e: Exception) {
        objectDetectorListener.onError("GPU is not supported on this device")
    }
    
    
  5. Используйте настройки этого объекта для создания объекта ObjectDetector TensorFlow Lite, содержащего модель:

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

Дополнительные сведения об использовании делегатов аппаратного ускорения с TensorFlow Lite см. в разделе Делегаты TensorFlow Lite .

Подготовьте данные для модели

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

Чтобы подготовить данные для обработки моделью:

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

Запуск прогнозов

После создания объекта TensorImage с данными изображения в правильном формате вы можете запустить модель на основе этих данных, чтобы получить прогноз или вывод . В примере приложения этот код содержится в методе ObjectDetectorHelper.detect() .

Чтобы запустить модель и сгенерировать прогнозы на основе данных изображения:

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

    val results = objectDetector?.detect(tensorImage)
    

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

После того как вы запустите данные изображения для модели обнаружения объектов, она создаст список результатов прогнозирования, которые код вашего приложения должен обработать, выполняя дополнительную бизнес-логику, отображая результаты пользователю или выполняя другие действия. Модель обнаружения объектов в примере приложения создает список прогнозов и ограничивающих рамок для обнаруженных объектов. В примере приложения результаты прогнозирования передаются объекту-прослушивателю для дальнейшей обработки и отображения пользователю.

Чтобы обработать результаты прогнозирования модели:

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

Следующие шаги