c++中的opencv convertTo和Python中的手动转换结果不同

Posted

技术标签:

【中文标题】c++中的opencv convertTo和Python中的手动转换结果不同【英文标题】:different result between opencv convertTo in c++ and manual conversion in Python 【发布时间】:2018-12-07 17:16:54 【问题描述】:

我正在尝试将代码从 c++ 移植到 python,在某些时候从 .oni 记录 (OpenNI2) 中提取帧,缩放到 8 位并保存为 jpg。 我在 c++ 中使用 OpenCV 函数 convertTo,这在 python 中是不可用的,所以阅读文档我正在尝试手动执行相同的操作,但是出了点问题。

这是c++

cv::Mat depthImage8;

double maxVal = 650.0;
double minVal = 520.0;
depthImage.convertTo(depthImage8, CV_8UC1,  255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal));
cv::imwrite(dst_folder + "/" + std::to_string(DepthFrameIndex) + "_8bit.jpg", depthImage8);

产生:

这是 Python 版本:

depth_scale_factor = 255.0 / (650.0-520.0)
depth_scale_beta_factor = -520.0*255.0/(650.0-520.0)
depth_uint8 = (depth_array*depth_scale_factor+depth_scale_beta_factor).astype('uint8')

产生:

这段代码似乎可以工作,但是生成的图像不同,而原始的(16UC1)是相同的(已经检查并且它们逐像素匹配),所以转换函数应该有问题。

【问题讨论】:

黑色或白色区域的差异是可见的,所以对我来说它看起来像saturate_cast“问题”。 或者说溢出,因为 numpy 不执行饱和(与 OpenCV 不同)。不幸的是,没有合适的minimal reproducible example,所以我无法进一步评论。 【参考方案1】:

感谢 cmets 我想出了解决方案。正如用户 michelson 和 Dan Masek 所说,Opencv 执行 saturate_cast 操作,而 numpy 不执行。所以为了得到同样的结果,Python版本必须是:

    depth_uint8 = depth_array*depth_scale_factor+depth_scale_beta_factor
    depth_uint8[depth_uint8>255] = 255
    depth_uint8[depth_uint8<0] = 0
    depth_uint8 = depth_uint8.astype('uint8')

【讨论】:

以上是关于c++中的opencv convertTo和Python中的手动转换结果不同的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV - Mat::convertTo() 断言错误。

convertTo 在 opencv 中不起作用

opencv convertTo 不工作

convertTo

OpenCV(C++)图像处理基础05:图像的亮度与对比度

opencv c++:将图像矩阵从无符号字符转换为浮点数