我正在尝试创建一个实时处理相机图像并将其显示在屏幕上的应用程序.我正在使用camera2 API.我创建了一个本地库来使用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)中获得一个.然后,您可以将该Surface通过JNI传递到您的本机代码,然后在其中使用NDK方法:

> ANativeWindow_fromSurface以获得ANativeWindow

>用各种ANativeWindow methods设置输出缓冲区的大小和格式,然后将处理后的数据绘制到其中.

使用setBuffersGeometry()配置输出大小,然后使用lock()获取ANativeWindow_Buffer.将图像数据写入ANativeWindow_Buffer.bits,然后使用unlockAndPost()发送缓冲区.

通常,您应该坚持使用RGBA_8888作为最兼容的格式.从技术上讲,仅正式支持它和另外两个RGB变体.因此,如果处理后的图像位于YUV中,则需要先将其转换为RGBA.

您还需要确保输出视图的长宽比与您设置的尺寸匹配.默认情况下,Android的View只会将这些内部缓冲区缩放到输出View的大小,可能会在此过程中对其进行拉伸.

您也可以将格式设置为Android内部的YUV格式之一,但这不能保证正常工作!

标签:opencv,native,camera2,c-4,android

来源: https://codeday.me/bug/20191026/1934771.html

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐