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

时间:2017-02-13 10:08:27

标签: android c++ opencv android-ndk java-native-interface

我正在使用基于Camera2Raw的应用的camera2 api。

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

image来自ImageReader.OnImageAvailableListener,而不是保存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 ++代码中缺少部分内容。

有人可以为此提供帮助吗?

2 个答案:

答案 0 :(得分:1)

处理拜耳RAW数据并非易事 - 它是传感器上像素值的原始读数,您需要大量额外的元数据和处理才能将其转换为可视图像。如果您不知道如何操作,我建议您不要尝试 - 您只需插入Adobe's DNG SDKlibraw等库。

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

答案 1 :(得分:1)

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

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

其中,mImageMat是Image Container的Mat类。

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