【问题标题】:How to get raw android camera sensor image data using JNI+OpenCV+NDK?如何使用 JNI+OpenCV+NDK 获取原始 android 相机传感器图像数据?
【发布时间】:2017-02-13 10:08:26
【问题描述】:

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

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

我有来自ImageReader.OnImageAvailableListenerimage,我没有保存 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++ 代码中缺少部分。

有人可以帮忙吗?

【问题讨论】:

  • Docs: "一般原始相机传感器图像格式,通常表示单通道拜耳马赛克图像。每个像素颜色样本以 16 位精度存储。" ——你的情况不是这样吗?因为您似乎将其视为具有 8 位精度的 3 通道 RGB 图像。这似乎很奇怪。
  • 是的,没错。我认为我的 c++ 代码可能适用于另一种情况,例如 YUV 格式。我发布的代码是我的试用版,图像处理不是我的领域:(所以我正在寻求帮助。如果有人指导我,我将不胜感激
  • android-24 添加了 NdkCamera,你也许可以直接从那里获取相机图像。头文件在 NDK 的平台下 include/camera, include/media (for AImagerReader)。

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


【解决方案1】:

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

您确定不只想要 YUV_420_888 数据,这些数据已处理但未压缩?

【讨论】:

  • 感谢您的回答。您发送的库是用于 PC 的吗?我正在尝试仅在移动应用程序中进行处理。我曾经使用YUV_420_888 数据。当我保存 DNG 文件并使用 RawDroid Demo app 转换为 JPEG 时。结果太棒了。所以我正在尝试做一些 rawdroid 做的事情
  • 同样使用 YUV_420_888,在 Google Pixel XL 中不起作用
  • YUV_420_888 在 Pixel XL 上应该可以正常工作 - 您使用的是实际为 YUV_420_888 列出的尺寸,还是尝试重复使用 RAW 尺寸?它们没有完全相同的尺寸,因为对 YUV 的处理通常会使图像更小(以匹配常见的纵横比等)。据我所知,Adobe DNG SDK 现在可以在 Android 上运行(它甚至在 Android Nougat 的 Android AOSP 源代码树中)。不知道libraw有没有。如果您想编写自己的 RAW 处理管道,那里有很多东西要学,而且这超出了简单的 StackOverflow 答案的范围。
  • 请参阅维基百科关于 RAW 的文章,了解从 RAW 文件制作 JPEG 所需的全部操作:en.wikipedia.org/wiki/Raw_image_format
  • 我最终使用了三星相机 SDK developer.samsung.com/galaxy/camera
【解决方案2】:

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

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

其中,mImageMat 是 Image Container 的 Mat 类。

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

【讨论】:

  • 哦,谢谢!如何在 JNI 中完成这项工作?我在本机 cpp 部分中使用 opencv,而不是在 java 中
  • Mat 类可以使用.getNativeObjAddr()传递给JNI
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多