c++ - OpenCV imread如何在16位和8位之间转换

标签 c++ opencv

我目前正在处理从 kinect 传感器检索到的深度图像,这些图像已保存为 16 位灰度 PNG。目前,我只是使用带有 CV_LOAD_IMAGE_GRAYSCALE 标志的 imread() 函数加载这些图像,一切正常。我这样做的原因是因为一些 OpenCV 函数依赖于 8 位的输入。

问题来了:下一步是直接使用传感器捕获的 16 位深度帧。我虽然使用 covertTo(dst, CV_8U, 1.0/256.0) 缩放和转换值就足够了,但出于某种原因,生成的图像看起来与加载为 8 位的图像有很大不同?那么,当加载为 8 位图像时,OpenCV 如何转换图像。

这是 image我用于测试,这里是一些显示问题的代码:

int main(int argc, char *argv[]){

    Mat depth8 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
    Mat depth16 = imread(argv[1], CV_LOAD_IMAGE_ANYDEPTH);

    depth16.convertTo(depth16, CV_8U, 1.0/256.0);

    Mat diff;
    absdiff(depth8, depth16, diff);

    //imshow("depth8", depth8*255.0/16.0);
    //imshow("depth16", depth16*255.0/16.0);
    imshow("diff", diff > 0);
    waitKey(0);

    return 0;
}

可以找到代码的输出here .

我想你想知道为什么测试图像这么暗,这是因为 16 位的最大值比 kinect 产生的值大得多(高达 4000 左右)。

另一件事:加载为 8 位的图像似乎比转换后的图像好得多。如果您在这两行中发表评论,您就会明白我的意思。

再说一次:OpenCV 如何进行转换?

提前致谢。

最佳答案

  1. imread函数最终会调用 imread_(...)highgui/src/loadsave.cpp .

  2. 正确的解码器将在 imread_ 中确定函数和矩阵 mat根据imread()中的第二个参数进行初始化.

  3. mat传递给 readData()解码器的方法。在这种情况下,将调用 png 解码器。

  4. 取决于mat的深度, png_set_strip_16在 png 解码器 ( highgui/src/grfmt_png.cpp ) 中可能会被调用。

  5. png_set_strip_16()使 libpng 调用 png_do_chop()最终。 (它只是丢弃低字节。请参阅 libpng 中的 pngrtran.c)

关于c++ - OpenCV imread如何在16位和8位之间转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26409175/

相关文章:

c++ - 如何使用着色器制作复古/ NEON /发光效果?

python - OpenCV 打开文件错误(Assertion failed)

python-3.x - 我还可以使用哪些方法来提取图像中的有效补丁?

c++ - OpenCV-如何将RGB图像投影到日志(R/G)〜日志(B/G)空间?

c++ - 从指针到成员的映射

c++ - 引用模板的语法(别名?)

c++ - 多态性和默认值 : can co-exist?

c++ - 如何终止DLL中的log4cplus?

c++ - HOG特征检测可以用于关键点匹配吗?

python - 在python中使用用户定义的转换函数将灰度图像转换回rgb图像的问题