Вариант использования анализа изображений предоставляет вашему приложению доступное для ЦП изображение, на котором вы можете выполнять обработку изображений, компьютерное зрение или выводы машинного обучения. Приложение реализует метод analyze()
, который запускается для каждого кадра.
Чтобы узнать, как интегрировать Google ML Kit с вашим приложением CameraX, см. ML Kit Analyzer .
Режимы работы
Если конвейер анализа приложения не может удовлетворить требования CameraX к частоте кадров, CameraX можно настроить на отбрасывание кадров одним из следующих способов:
неблокирующий (по умолчанию): в этом режиме исполнитель всегда кэширует последнее изображение в буфер изображения (аналогично очереди с глубиной, равной единице), пока приложение анализирует предыдущее изображение. Если CameraX получает новое изображение до того, как приложение завершит обработку, новое изображение сохраняется в том же буфере, перезаписывая предыдущее изображение. Обратите внимание, что
ImageAnalysis.Builder.setImageQueueDepth()
в этом сценарии не имеет никакого эффекта, и содержимое буфера всегда перезаписывается. Вы можете включить этот неблокирующий режим, вызвавsetBackpressureStrategy()
сSTRATEGY_KEEP_ONLY_LATEST
. Дополнительные сведения о последствиях для исполнителя см. в справочной документацииSTRATEGY_KEEP_ONLY_LATEST
.блокировка : в этом режиме внутренний исполнитель может добавлять несколько изображений во внутреннюю очередь изображений и начинает отбрасывать кадры только тогда, когда очередь заполнена. Блокировка происходит по всей области действия устройства камеры: если устройство камеры имеет несколько связанных вариантов использования, все эти варианты использования будут заблокированы, пока CameraX обрабатывает эти изображения. Например, если и предварительный просмотр, и анализ изображения привязаны к устройству камеры, предварительный просмотр также будет заблокирован, пока CameraX обрабатывает изображения. Вы можете включить режим блокировки, передав
STRATEGY_BLOCK_PRODUCER
вsetBackpressureStrategy()
. Вы также можете настроить глубину очереди изображений с помощью ImageAnalysis.Builder.setImageQueueDepth() .
Благодаря низкой задержке и высокопроизводительному анализатору, где общее время анализа изображения меньше продолжительности кадра CameraX (например, 16 мс для 60 кадров в секунду), любой режим работы обеспечивает плавное общее впечатление. Режим блокировки по-прежнему может быть полезен в некоторых сценариях, например, при очень кратковременных дрожаниях системы.
При высокой задержке и высокой производительности анализатора для компенсации задержки необходим режим блокировки с более длинной очередью. Однако обратите внимание, что приложение по-прежнему может обрабатывать все кадры.
При высокой задержке и трудоемкости анализатора (анализатор не может обработать все кадры) неблокирующий режим может быть более подходящим выбором, поскольку для пути анализа кадры необходимо отбрасывать, но другие параллельные сценарии использования по-прежнему можно увидеть. все кадры.
Выполнение
Чтобы использовать анализ изображений в своем приложении, выполните следующие действия:
- Создайте вариант использования
ImageAnalysis
. - Создайте
ImageAnalysis.Analyzer
. - Установите свой анализатор на
ImageAnalysis
. - Привяжите владельца жизненного цикла, средство выбора камеры и вариант использования
ImageAnalysis
к жизненному циклу.
Сразу после привязки CameraX отправляет изображения на зарегистрированный анализатор. После завершения анализа вызовите ImageAnalysis.clearAnalyzer()
или отмените привязку варианта использования ImageAnalysis
, чтобы остановить анализ.
Создание варианта использования ImageAnaанализа
ImageAnalysis
подключает ваш анализатор (потребитель изображений) к CameraX, который является производителем изображений. Приложения могут использовать ImageAnalysis.Builder
для создания объекта ImageAnalysis
. С помощью ImageAnalysis.Builder
приложение может настроить следующее:
- Параметры вывода изображения:
- Формат: CameraX поддерживает
YUV_420_888
иRGBA_8888
черезsetOutputImageFormat(int)
. Формат по умолчанию —YUV_420_888
. - Разрешение и соотношение сторон : вы можете установить любой из этих параметров, но учтите, что вы не можете установить оба значения одновременно.
- Вращение .
- Целевое имя : используйте этот параметр в целях отладки.
- Формат: CameraX поддерживает
- Элементы управления потоком изображений:
Приложения могут устанавливать либо разрешение, либо соотношение сторон, но не то и другое. Точное выходное разрешение зависит от запрошенного размера приложения (или соотношения сторон) и возможностей оборудования и может отличаться от запрошенного размера или соотношения сторон. Информацию об алгоритме сопоставления разрешения см. в документации для setTargetResolution()
Приложение может настроить пиксели выходного изображения в цветовом пространстве YUV (по умолчанию) или RGBA. При настройке выходного формата RGBA CameraX внутренне преобразует изображения из цветового пространства YUV в RGBA и упаковывает биты изображения в ByteBuffer
первой плоскости ImageProxy (две другие плоскости не используются) со следующей последовательностью:
ImageProxy.getPlanes()[0].buffer[0]: alpha
ImageProxy.getPlanes()[0].buffer[1]: red
ImageProxy.getPlanes()[0].buffer[2]: green
ImageProxy.getPlanes()[0].buffer[3]: blue
...
При выполнении сложного анализа изображений, когда устройство не может поддерживать частоту кадров, вы можете настроить CameraX на отбрасывание кадров с помощью стратегий, описанных в разделе «Режимы работы» этой темы.
Создайте свой анализатор
Приложения могут создавать анализаторы, реализуя интерфейс ImageAnalysis.Analyzer
и переопределяя analyze(ImageProxy image)
. В каждом анализаторе приложения получают ImageProxy
, который является оберткой для Media.Image . Формат изображения можно запросить с помощью ImageProxy.getFormat()
. Формат — это одно из следующих значений, которые приложение предоставляет с помощью ImageAnalysis.Builder
:
-
ImageFormat.RGBA_8888
, если приложение запросилоOUTPUT_IMAGE_FORMAT_RGBA_8888
. -
ImageFormat.YUV_420_888
, если приложение запросилоOUTPUT_IMAGE_FORMAT_YUV_420_888
.
См. вариант использования Build ImageAnaлиз для получения информации о конфигурациях цветового пространства и о том, где можно получить пиксельные байты.
Внутри анализатора приложение должно делать следующее:
- Анализируйте данный кадр как можно быстрее, желательно в пределах заданного временного ограничения частоты кадров (например, менее 32 мс для случая 30 кадров в секунду). Если приложение не может проанализировать кадр достаточно быстро, рассмотрите один из поддерживаемых механизмов отбрасывания кадров .
- Выпустите
ImageProxy
для CameraX, вызвавImageProxy.close()
. Обратите внимание, что вам не следует вызывать функцию закрытия обернутого Media.Image (Media.Image.close()
).
Приложения могут напрямую использовать завернутый Media.Image
внутри ImageProxy. Только не вызывайте Media.Image.close()
для завернутого изображения, так как это нарушит механизм обмена изображениями внутри CameraX; вместо этого используйте ImageProxy.close()
, чтобы передать базовый Media.Image
в CameraX.
Настройте свой анализатор для ImageAnaанализа
После создания анализатора используйте ImageAnalysis.setAnalyzer()
чтобы зарегистрировать его и начать анализ. Завершив анализ, используйте ImageAnalysis.clearAnalyzer()
чтобы удалить зарегистрированный анализатор.
Для анализа изображений можно настроить только один активный анализатор. Вызов ImageAnalysis.setAnalyzer()
заменяет зарегистрированный анализатор, если он уже существует. Приложения могут установить новый анализатор в любое время, до или после привязки варианта использования.
Привязка ImageAnaанализа к жизненному циклу
Настоятельно рекомендуется привязать ваш ImageAnalysis
к существующему жизненному циклу AndroidX с помощью функции ProcessCameraProvider.bindToLifecycle()
. Обратите внимание, что функцияbindToLifecycle bindToLifecycle()
возвращает выбранное устройство Camera
, которое можно использовать для точной настройки дополнительных параметров, таких как экспозиция и другие. См. это руководство для получения дополнительной информации об управлении выходом камеры.
Следующий пример объединяет все из предыдущих шагов, привязывая варианты использования CameraX ImageAnalysis
и Preview
к владельцу lifeCycle
:
Котлин
val imageAnalysis = ImageAnalysis.Builder() // enable the following line if RGBA output is needed. // .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888) .setTargetResolution(Size(1280, 720)) .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .build() imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer { imageProxy -> val rotationDegrees = imageProxy.imageInfo.rotationDegrees // insert your code here. ... // after done, release the ImageProxy object imageProxy.close() }) cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageAnalysis, preview)
Ява
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder() // enable the following line if RGBA output is needed. //.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888) .setTargetResolution(new Size(1280, 720)) .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .build(); imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() { @Override public void analyze(@NonNull ImageProxy imageProxy) { int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees(); // insert your code here. ... // after done, release the ImageProxy object imageProxy.close(); } }); cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, imageAnalysis, preview);
Дополнительные ресурсы
Чтобы узнать больше о CameraX, см. следующие дополнительные ресурсы.