Быстрый старт для 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 на панели состояния Build Output .

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

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

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

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

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

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

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

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

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

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

В примере приложения используется библиотека задач 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.0.0'
    ...
    }
    
  2. В Android Studio синхронизируйте зависимости проекта, выбрав: File > Sync Project with Gradle Files .

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

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

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