Руководство по обнаружению объектов для Android

Задача «Детектор объектов» позволяет обнаруживать наличие и расположение объектов нескольких классов. Например, детектор объектов может обнаружить на изображении собак. В этих инструкциях показано, как использовать задачу «Детектор объектов» на Android. Пример кода, описанный в этой инструкции, доступен на GitHub . Вы можете увидеть эту задачу в действии, просмотрев эту веб-демо . Дополнительные сведения о возможностях, моделях и параметрах конфигурации этой задачи см. в разделе Обзор .

Пример кода

Пример кода задач MediaPipe — это простая реализация приложения Object Detector для Android. В примере используется камера на физическом устройстве Android для непрерывного обнаружения объектов, а также можно использовать изображения и видео из галереи устройства для статического обнаружения объектов.

Вы можете использовать это приложение в качестве отправной точки для создания собственного приложения для Android или обращаться к нему при изменении существующего приложения. Пример кода Object Detector размещен на GitHub .

Загрузите код

Следующие инструкции показывают, как создать локальную копию кода примера с помощью инструмента командной строки git .

Чтобы загрузить пример кода:

  1. Клонируйте репозиторий git, используя следующую команду:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. При желании настройте свой экземпляр git на использование разреженной проверки, чтобы у вас были только файлы для примера приложения Object Detector:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/object_detection/android
    

После создания локальной версии кода примера вы можете импортировать проект в Android Studio и запустить приложение. Инструкции см. в Руководстве по установке для Android .

Ключевые компоненты

Следующие файлы содержат ключевой код для примера приложения Object Detector:

  • ObjectDetectorHelper.kt — инициализирует детектор объектов и обрабатывает выбор модели и делегата.
  • MainActivity.kt — реализует приложение и собирает компоненты пользовательского интерфейса.
  • OverlayView.kt — обрабатывает и отображает результаты.

Настраивать

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

Зависимости

Детектор объектов использует библиотеку com.google.mediapipe:tasks-vision . Добавьте эту зависимость в файл build.gradle вашего проекта разработки приложения для Android. Импортируйте необходимые зависимости с помощью следующего кода:

dependencies {
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

Модель

Для задачи «Детектор объектов MediaPipe» требуется обученная модель, совместимая с этой задачей. Дополнительную информацию о доступных обученных моделях для Object Detector смотрите в разделе «Модели обзора задач».

Выберите и загрузите модель, а затем сохраните ее в каталоге вашего проекта:

<dev-project-root>/src/main/assets

Используйте метод BaseOptions.Builder.setModelAssetPath() чтобы указать путь, используемый моделью. Пример кода см. в следующем разделе.

Создать задачу

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

Задача «Детектор объектов» поддерживает 3 типа входных данных: неподвижные изображения, видеофайлы и прямые видеопотоки. При создании задачи вам необходимо указать режим работы, соответствующий вашему типу входных данных. Выберите вкладку, соответствующую вашему типу входных данных, чтобы узнать, как создать задачу и выполнить вывод.

Изображение

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.IMAGE)
    .setMaxResults(5)
    .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

видео

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.VIDEO)
    .setMaxResults(5)
    .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

Прямая трансляция

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMaxResults(5)
    .setResultListener((result, inputImage) -> {
      // Process the detection result here.
    })
    .setErrorListener((result, inputImage) -> {
      // Process the classification errors here.
    })
   .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

Реализация примера кода Object Detector позволяет пользователю переключаться между режимами обработки. Такой подход усложняет код создания задачи и может не подойти для вашего варианта использования. Вы можете увидеть этот код в функции setupObjectDetector() класса ObjectDetectorHelper .

Варианты конфигурации

Эта задача имеет следующие параметры конфигурации для приложений Android:

Название опции Описание Диапазон значений Значение по умолчанию
runningMode Устанавливает режим выполнения задачи. Есть три режима:

ИЗОБРАЖЕНИЕ: Режим для ввода одного изображения.

ВИДЕО: Режим декодированных кадров видео.

LIVE_STREAM: режим прямой трансляции входных данных, например, с камеры. В этом режиме необходимо вызвать resultListener, чтобы настроить прослушиватель на асинхронное получение результатов.
{ IMAGE, VIDEO, LIVE_STREAM } IMAGE
displayNamesLocales Задает язык меток, которые будут использоваться для отображаемых имен, представленных в метаданных модели задачи, если они доступны. По умолчанию — en для английского языка. Вы можете добавить локализованные метки к метаданным пользовательской модели с помощью API записи метаданных TensorFlow Lite. Код региона ru
maxResults Устанавливает необязательное максимальное количество возвращаемых результатов обнаружения с наибольшим количеством оценок. Любые положительные числа -1 (возвращаются все результаты)
scoreThreshold Устанавливает порог оценки прогноза, который переопределяет тот, который указан в метаданных модели (если таковые имеются). Результаты ниже этого значения отклоняются. Любой плавающий Не задано
categoryAllowlist Устанавливает необязательный список разрешенных имен категорий. Если поле не пусто, результаты обнаружения, имя категории которых отсутствует в этом наборе, будут отфильтрованы. Повторяющиеся или неизвестные названия категорий игнорируются. Эта опция является взаимоисключающей с categoryDenylist , и использование обеих приводит к ошибке. Любые строки Не задано
categoryDenylist Устанавливает необязательный список имен категорий, которые не разрешены. Если поле не пусто, результаты обнаружения, имя категории которых находится в этом наборе, будут отфильтрованы. Повторяющиеся или неизвестные названия категорий игнорируются. Этот параметр является взаимоисключающим с categoryAllowlist , и использование обоих приводит к ошибке. Любые строки Не задано
resultListener Настраивает прослушиватель результатов на асинхронное получение результатов обнаружения, когда детектор объектов находится в режиме прямого потока. Эту опцию можно использовать только в том случае, если для параметра RunningMode установлено значение LIVE_STREAM. Непригодный Не задано

Подготовьте данные

Вам необходимо преобразовать входное изображение или кадр в объект com.google.mediapipe.framework.image.MPImage перед передачей его в детектор объектов.

Следующие примеры объясняют и показывают, как подготовить данные к обработке для каждого из доступных типов данных:

Изображение

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load an image on the user’s device as a Bitmap object using BitmapFactory.

// Convert an Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(bitmap).build();
    

видео

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load a video file on the user's device using MediaMetadataRetriever

// From the video’s metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT values. Use these values
// to calculate the timestamp of each frame later.

// Loop through the video and load each frame as a Bitmap object.

// Convert the Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

Прямая трансляция

import com.google.mediapipe.framework.image.MediaImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Create a CameraX’s ImageAnalysis to continuously receive frames
// from the device’s camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

// For each Android’s ImageProxy object received from the ImageAnalysis,
// extract the encapsulated Android’s Image object and convert it to
// a MediaPipe’s Image object.
android.media.Image mediaImage = imageProxy.getImage()
MPImage mpImage = new MediaImageBuilder(mediaImage).build();
    

В примере кода «Детектора объектов» подготовка данных осуществляется в классе ObjectDetectorHelper в функциях detectImage() , detectVideoFile() , detectLivestreamFrame() .

Запустить задачу

В зависимости от типа данных, с которыми вы работаете, используйте метод ObjectDetector.detect...() , специфичный для этого типа данных. Используйте detect() для отдельных изображений, detectForVideo() для кадров в видеофайлах и detectAsync() для видеопотоков. Когда вы выполняете обнаружения в видеопотоке, убедитесь, что вы запускаете обнаружения в отдельном потоке, чтобы избежать блокировки потока пользовательского интерфейса.

В следующих примерах кода показаны простые примеры запуска Object Detector в различных режимах данных:

Изображение

ObjectDetectorResult detectionResult = objectDetector.detect(image);
    

видео

// Calculate the timestamp in milliseconds of the current frame.
long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count;

// Run inference on the frame.
ObjectDetectorResult detectionResult =
    objectDetector.detectForVideo(image, frameTimestampMs);
    

Прямая трансляция

// Run inference on the frame. The detection results will be available
// via the `resultListener` provided in the `ObjectDetectorOptions` when
// the object detector was created.
objectDetector.detectAsync(image, frameTimestampMs);
    

В примере кода Object Detector более detectAsync() detect() реализации каждого detectVideoFile() этих режимов. Пример кода позволяет пользователю переключаться между режимами обработки, которые могут не потребоваться для вашего варианта использования.

Обратите внимание на следующее:

  • При работе в режиме видео или режиме прямой трансляции вы также должны предоставить метку времени входного кадра задаче «Детектор объектов».
  • При работе в режиме изображения или видео задача «Детектор объектов» блокирует текущий поток до тех пор, пока он не завершит обработку входного изображения или кадра. Чтобы избежать блокировки текущего потока, выполните обработку в фоновом потоке.
  • При работе в режиме прямого потока задача «Детектор объектов» не блокирует текущий поток, а немедленно возвращается. Он будет вызывать прослушиватель результатов с результатом обнаружения каждый раз, когда завершает обработку входного кадра. Если функция обнаружения вызывается, когда задача «Детектор объектов» занята обработкой другого кадра, новый входной кадр будет игнорироваться.

Обработка и отображение результатов

После выполнения вывода задача «Детектор объектов» возвращает объект ObjectDetectorResult , который описывает объекты, обнаруженные во входном изображении.

Ниже показан пример выходных данных этой задачи:

ObjectDetectorResult:
 Detection #0:
  Box: (x: 355, y: 133, w: 190, h: 206)
  Categories:
   index       : 17
   score       : 0.73828
   class name  : dog
 Detection #1:
  Box: (x: 103, y: 15, w: 138, h: 369)
  Categories:
   index       : 17
   score       : 0.73047
   class name  : dog

На следующем изображении показана визуализация результатов задачи:

Пример кода детектора объектов демонстрирует, как отображать результаты обнаружения, возвращенные задачей. Дополнительные сведения см. в классе OverlayView .