Задача MediaPipe Image Embedder позволяет преобразовывать данные изображения в числовое представление для выполнения задач обработки изображений, связанных с машинным обучением, таких как сравнение сходства двух изображений. В этих инструкциях показано, как использовать Image Embedder с приложениями Android.
Дополнительные сведения о возможностях, моделях и параметрах конфигурации этой задачи см. в разделе Обзор .
Пример кода
Пример кода задач MediaPipe — это простая реализация приложения Image Embedder для Android. В примере используется камера на физическом устройстве Android для непрерывного внедрения изображений, а также можно запустить средство внедрения для файлов изображений, хранящихся на устройстве.
Вы можете использовать это приложение в качестве отправной точки для своего собственного приложения для Android или обращаться к нему при изменении существующего приложения. Пример кода Image Embedder размещен на GitHub .
Загрузите код
Следующие инструкции показывают, как создать локальную копию кода примера с помощью инструмента командной строки git .
Чтобы загрузить пример кода:
- Клонируйте репозиторий git, используя следующую команду:
git clone https://github.com/google-ai-edge/mediapipe-samples
- При желании настройте свой экземпляр git на использование разреженной проверки, чтобы у вас были только файлы для примера приложения Image Embedder:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_embedder/android
После создания локальной версии кода примера вы можете импортировать проект в Android Studio и запустить приложение. Инструкции см. в Руководстве по установке для Android .
Ключевые компоненты
Следующие файлы содержат ключевой код для этого примера приложения для внедрения изображений:
- ImageEmbedderHelper.kt : инициализирует средство внедрения изображений и обрабатывает выбор модели и делегата.
- MainActivity.kt : реализует приложение и собирает компоненты пользовательского интерфейса.
Настраивать
В этом разделе описаны ключевые шаги по настройке среды разработки и проектов кода для использования Image Embedder. Общие сведения о настройке среды разработки для использования задач MediaPipe, включая требования к версии платформы, см. в руководстве по настройке для Android .
Зависимости
Image Embedder использует библиотеку com.google.mediapipe:tasks-vision
. Добавьте эту зависимость в файл build.gradle
вашего проекта разработки приложения для Android. Импортируйте необходимые зависимости с помощью следующего кода:
dependencies {
...
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Модель
Для задачи MediaPipe Image Embedder требуется обученная модель, совместимая с этой задачей. Дополнительную информацию о доступных обученных моделях для Image Embedder см. в разделе «Модели » обзора задач.
Выберите и загрузите модель, а затем сохраните ее в каталоге вашего проекта:
<dev-project-root>/src/main/assets
Укажите путь к модели в параметре ModelAssetPath
. В примере кода модель определяется в функции setupImageEmbedder()
в файле ImageEmbedderHelper.kt :
Используйте метод BaseOptions.Builder.setModelAssetPath()
чтобы указать путь, используемый моделью. Этот метод упоминается в примере кода в следующем разделе.
Создать задачу
Вы можете использовать функцию createFromOptions
для создания задачи. Функция createFromOptions
принимает параметры конфигурации для установки параметров внедрения. Дополнительные сведения о параметрах конфигурации см. в разделе Обзор конфигурации .
Задача Image Embedder поддерживает три типа входных данных: неподвижные изображения, видеофайлы и прямые видеопотоки. При создании задачи вам необходимо указать режим работы, соответствующий вашему типу входных данных. Выберите вкладку, соответствующую вашему типу входных данных, чтобы узнать, как создать задачу и выполнить вывод.
Изображение
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.IMAGE) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
Видео
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.VIDEO) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
Прямая трансляция
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.LIVE_STREAM) .setResultListener((result, inputImage) -> { // Process the embedding result here. }) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
Пример реализации кода позволяет пользователю переключаться между режимами обработки. Такой подход усложняет код создания задачи и может не подойти для вашего варианта использования. Вы можете увидеть этот код в функции setupImageEmbedder()
в файле ImageEmbedderHelper.kt .
Варианты конфигурации
Эта задача имеет следующие параметры конфигурации для приложений Android:
Название опции | Описание | Диапазон значений | Значение по умолчанию |
---|---|---|---|
runningMode | Устанавливает режим выполнения задачи. Есть три режима: ИЗОБРАЖЕНИЕ: Режим для ввода одного изображения. ВИДЕО: Режим декодированных кадров видео. LIVE_STREAM: режим прямой трансляции входных данных, например с камеры. В этом режиме необходимо вызвать resultListener, чтобы настроить прослушиватель на асинхронное получение результатов. | { IMAGE, VIDEO, LIVE_STREAM } | IMAGE |
l2_normalize | Нормализовать ли возвращенный вектор признаков по норме L2. Используйте эту опцию, только если модель еще не содержит встроенный L2_NORMALIZATION TFLite Op. В большинстве случаев это уже так, и нормализация L2, таким образом, достигается посредством вывода TFLite без необходимости использования этой опции. | Boolean | False |
quantize | Следует ли квантовать возвращенное внедрение в байты посредством скалярного квантования. Неявно предполагается, что вложения имеют единичную норму, и поэтому любое измерение гарантированно имеет значение в [-1.0, 1.0]. Если это не так, используйте опцию l2_normalize. | Boolean | False |
resultListener | Настраивает прослушиватель результатов на асинхронное получение результатов внедрения, когда Image Embedder находится в режиме прямого потока. Может использоваться только в том случае, если для режима работы установлено значение LIVE_STREAM | Н/Д | Не установлено |
errorListener | Устанавливает дополнительный прослушиватель ошибок. | Н/Д | Не установлено |
Подготовьте данные
Image Embedder работает с изображениями, видеофайлами и видео в реальном времени. Задача выполняет предварительную обработку входных данных, включая изменение размера, поворот и нормализацию значений.
Вам необходимо преобразовать входное изображение или кадр в объект com.google.mediapipe.framework.image.MPImage
, прежде чем передавать его в задачу Image Embedder.
Изображение
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 value. You’ll need them // 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() Image mpImage = new MediaImageBuilder(mediaImage).build();
В примере кода подготовка данных осуществляется в файле ImageEmbedderHelper.kt .
Запустить задачу
Вы можете вызвать функцию embed
, соответствующую вашему режиму работы, чтобы инициировать выводы. API Image Embedder возвращает векторы внедрения для входного изображения или кадра.
Изображение
ImageEmbedderResult embedderResult = imageEmbedder.embed(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. ImageEmbedderResult embedderResult = imageEmbedder.embedForVideo(image, frameTimestampMs);
Прямая трансляция
// Run inference on the frame. The embedding results will be available // via the `resultListener` provided in the `ImageEmbedderOptions` when // the image embedder was created. imageEmbedder.embedAsync(image, frameTimestampMs);
Обратите внимание на следующее:
- При работе в режиме видео или режиме прямой трансляции вы также должны предоставить метку времени входного кадра задаче Image Embedder.
- При работе в режиме изображения или видео задача Image Embedder блокирует текущий поток до тех пор, пока он не завершит обработку входного изображения или кадра. Чтобы избежать блокировки текущего потока, выполните обработку в фоновом потоке.
- При работе в режиме прямой трансляции задача Image Embedder не блокирует текущий поток, а немедленно возвращается. Он будет вызывать прослушиватель результатов с результатом обнаружения каждый раз, когда завершает обработку входного кадра. Если функция
embedAsync
вызывается, когда задача Image Embedder занята обработкой другого кадра, задача игнорирует новый входной кадр.
В примере кода функция embed
определена в файле ImageEmbedderHelper.kt .
Обработка и отображение результатов
После выполнения вывода задача Image Embedder возвращает объект ImageEmbedderResult
, который содержит список внедрений (с плавающей запятой или скалярно-квантованных) для входного изображения.
Ниже показан пример выходных данных этой задачи:
ImageEmbedderResult:
Embedding #0 (sole embedding head):
float_embedding: {0.0, 0.0, ..., 0.0, 1.0, 0.0, 0.0, 2.0}
head_index: 0
Этот результат был получен путем встраивания следующего изображения:
Вы можете сравнить сходство двух вложений, используя функцию ImageEmbedder.cosineSimilarity
. См. следующий код для примера.
// Compute cosine similarity.
double similarity = ImageEmbedder.cosineSimilarity(
result.embeddingResult().embeddings().get(0),
otherResult.embeddingResult().embeddings().get(0));