Я пытаюсь создать приложение, которое обрабатывает изображения с камер в режиме реального времени и отображает их на экране. Я использую 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
из данных и выполнить обработку изображения.
Теперь следующим шагом будет показать мой обработанный вывод, но я не уверен, как показать мое обработанное изображение. Любая помощь будет принята с благодарностью.
Вообще говоря, вам нужно отправить обработанные данные изображения в представление Android.
Наиболее эффективный вариант — получить объект android.view.Surface для рисования — вы можете получить его из SurfaceView (через SurfaceHolder) или TextureView (через SurfaceTexture). Затем вы можете передать эту поверхность через JNI в ваш собственный код и там использовать методы NDK:
Используйте setBuffersGeometry () для настройки размера вывода, затем lock (), чтобы получить ANativeWindow_Buffer. Запишите данные изображения в ANativeWindow_Buffer.bits, а затем отправьте буфер с помощью unlockAndPost ().
Как правило, вам следует придерживаться RGBA_8888 как наиболее совместимого формата; технически только он и два других варианта RGB официально поддерживаются. Поэтому, если ваше обработанное изображение находится в формате YUV, вам нужно сначала преобразовать его в RGBA.
Вам также необходимо убедиться, что соотношение сторон вашего выходного представления совпадает с заданным размером измерений; по умолчанию представления Android просто масштабируют эти внутренние буферы до размера выходного представления, возможно, растягивая его в процессе.
Вы также можете установить формат одного из внутренних форматов Android YUV, но это не гарантированно работать!
Я попробовал подход ANativeWindow, но это неудобно, и мне не удалось сделать это правильно. В конце концов, я только что отказался и импортировал библиотеку OpenCV4Android, которая упрощает работу, конвертируя данные камеры в RGBA Mat за кулисами.