opencv C++从android NV21图像数据缓冲区创建Mat对象

pre*_*ree 9 c++ android opencv

我已经实现了一个启动摄像头的android应用程序,并使用JNI接口将所有预览缓冲区发送到本机组件.由于预览数据是NV21图像格式,我需要从中创建一个cv :: Mat实例.我搜索了它,发现了以下解决方案:

cv::Mat _yuv(height, width, CV_8UC1, (uchar *) imagebuffer);

where imagebuffer is jbyte*
Run Code Online (Sandbox Code Playgroud)

但是,请勿在输出图像中获得预期的图像.这些都充满了一些随机的线等.有谁知道我究竟能做到这一点?

Fro*_*oyo 18

您需要将YUV图像转换为RGBA图像.

cv::Mat _yuv(height+height/2, width, CV_8UC1, (uchar *)imagebuffer);
cv::cvtColor(_yuv, _yuv, CV_YUV2RGBA_NV21);
Run Code Online (Sandbox Code Playgroud)

通常,YUV图像是1通道图像1.5*height(如果它是RGB或灰度图像).

或者你可以创建一个新的Mat并将jint数组传递给本机函数,并使用该数组来设置位图的像素.

jint *_out = env->GetIntArrayElements(out, 0);     

cv::Mat _yuv(height + height/2, width, CV_8UC1, (uchar*)imagebuffer);
cv::Mat _rgba(height, width, CV_8UC4, (uchar *)_out);

cv::cvtColor(_yuv, _rgba, CV_YUV2RGBA_NV21);

env->ReleaseIntArrayElements(out, _out, 0);
Run Code Online (Sandbox Code Playgroud)

在Java中

bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
pixels = new int[width * height];

native_function(height, width, bytedata, pixels);

bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
Run Code Online (Sandbox Code Playgroud)