如何使用JNI + OpenCV + NDK获取原始的android相机传感器图像数据



我正在为我的应用程序使用camera2 api,它基于Camera2Raw。

mRawImageReader = ImageReader.newInstance(largestRaw.getWidth(), 
       largestRaw.getHeight(),ImageFormat.RAW_SENSOR, /*maxImages*/

我从ImageReader.OnImageAvailableListener image,我没有保存DNG文件,而是将其字节数组传递给我的本机opencv函数来处理:

int w = image.getWidth();
int h = image.getHeight();
ByteBuffer buffer = planes[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
addShot(w, h, data);
image.close();

和C++功能:

JNIEXPORT jboolean JNICALL addShot(JNIEnv* env, jobject obj, jint width, jint height, jbyteArray p_data)
   {
       jbyte* _p_data= env->GetByteArrayElements(p_data, 0);
       Mat srcBGR(height, width, CV_8UC3);
       Mat mdata(height, width, CV_8UC3, (unsigned char *)_p_data);
//        Mat tmp_mat= imdecode(mdata,1);
       cvtColor(mdata, srcBGR, CV_RGB2BGR);
       env->ReleaseByteArrayElements(p_data, _p_data, 0);
   }

首先,为了确保这一点,我正在尝试在 c++ 端另存为 JPEG。但结果有很多绿色。

我认为我的 c++ 代码中缺少部分。

谁能帮忙?

处理拜耳RAW数据并非易事 - 它是传感器像素值的原始读数,您需要大量额外的元数据和处理才能将其转换为可查看的图像。 如果你不知道怎么做,我不建议尝试 - 你可以插入像Adobe的DNG SDK或libraw这样的库。

您确定您不仅想要YUV_420_888已处理但未压缩的数据吗?

捕获RAW图像数据后,使用简单的OpenCV函数从缓冲存储器中读取。

Mat mImageMat;
mImageMat = Imgcodecs.imdecode(new MatOfByte(data), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);

其中,mImageMat是映像容器的垫子类。

然后,处理图像变得简单。

最新更新