Android camera2 API — отображение обработанного кадра в режиме реального времени

Я пытаюсь создать приложение, которое обрабатывает изображения с камер в режиме реального времени и отображает их на экране. Я использую API Camera2. Я создал собственную библиотеку для обработки изображений с использованием OpenCV.

До сих пор мне удалось настроить ImageReader, который получает изображения в формате YUV_420_888, как это.

        mImageReader = ImageReader.newInstance(
mPreviewSize.getWidth(),
mPreviewSize.getHeight(),
ImageFormat.YUV_420_888,
4);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mImageReaderHandler);

Оттуда я могу получить плоскости изображения (Y, U и V), получить их объекты ByteBuffer и передать их в мою собственную функцию. Это происходит в mOnImageAvailableListener:

        Image image = reader.acquireLatestImage();

Image.Plane[] planes = image.getPlanes();
Image.Plane YPlane = planes[0];
Image.Plane UPlane = planes[1];
Image.Plane VPlane = planes[2];

ByteBuffer YPlaneBuffer = YPlane.getBuffer();
ByteBuffer UPlaneBuffer = UPlane.getBuffer();
ByteBuffer VPlaneBuffer = VPlane.getBuffer();

myNativeMethod(YPlaneBuffer, UPlaneBuffer, VPlaneBuffer, w, h);

image.close();

На родной стороне я могу получить указатели данных из буферов, создать cv::Mat из данных и выполнить обработку изображения.

Теперь следующим шагом будет показать мой обработанный вывод, но я не уверен, как показать мое обработанное изображение. Любая помощь будет принята с благодарностью.

3

Решение

Вообще говоря, вам нужно отправить обработанные данные изображения в представление Android.

Наиболее эффективный вариант — получить объект android.view.Surface для рисования — вы можете получить его из SurfaceView (через SurfaceHolder) или TextureView (через SurfaceTexture). Затем вы можете передать эту поверхность через JNI в ваш собственный код и там использовать методы NDK:

  • ANativeWindow_fromSurface получить ANativeWindow
  • Различные Методы ANativeWindow установить размер и формат выходного буфера, а затем нарисовать обработанные данные в него.

Используйте setBuffersGeometry () для настройки размера вывода, затем lock (), чтобы получить ANativeWindow_Buffer. Запишите данные изображения в ANativeWindow_Buffer.bits, а затем отправьте буфер с помощью unlockAndPost ().

Как правило, вам следует придерживаться RGBA_8888 как наиболее совместимого формата; технически только он и два других варианта RGB официально поддерживаются. Поэтому, если ваше обработанное изображение находится в формате YUV, вам нужно сначала преобразовать его в RGBA.

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

Вы также можете установить формат одного из внутренних форматов Android YUV, но это не гарантированно работать!

4

Другие решения

Я попробовал подход ANativeWindow, но это неудобно, и мне не удалось сделать это правильно. В конце концов, я только что отказался и импортировал библиотеку OpenCV4Android, которая упрощает работу, конвертируя данные камеры в RGBA Mat за кулисами.

0