分裂后的OpenCv轮次

Posted

技术标签:

【中文标题】分裂后的OpenCv轮次【英文标题】:OpenCv round after division 【发布时间】:2015-01-21 16:24:01 【问题描述】:

看下面的代码

Blue = channel[0];
Green = channel[1];
Red = channel[2];

Mat G = (Green + Blue) / 2;

其中红绿和蓝是图像的通道。在绿色和蓝色的总和为奇数的情况下,有时会进行一轮,有时会进行“修复”。例如,对于值为 120 和蓝色 45 的绿色像素,G 值为 82(因此它只需要 82,5 的整数部分)。而在另一种情况下,绿色为 106,蓝色为 33,我得到 G 的那个元素的值 70(因此,它进行了一轮,因为 (33+106)/2 = 69,5 )。

操作是什么?

【问题讨论】:

【参考方案1】:

OpenCV 使用“四舍五入”舍入模式。如果 fraction 为 0.5,则舍入到最接近的偶数。这就是为什么 82.5 舍入为 82 和 69.5 舍入为 70。

【讨论】:

谢谢。一个链接到一些关于这个的文档会很好。【参考方案2】:

这种差异发生在 opencv 源代码中 cvRound 的实现上。它的一部分是从下面的github 复制的,并添加了 cmets。

int cvRound( float value )

    double intpart, fractpart;
    fractpart = modf(value, &intpart);

    //for +ve numbers, when fraction is 0.5, odd numbers are rounded up 
    //and even numbers are rounded down 
    //and vice versa for -ve numbers

    if ((fabs(fractpart) != 0.5) || ((((int)intpart) % 2) != 0))
        return (int)(value + (value >= 0 ? 0.5 : -0.5));
    else
        return (int)intpart;

我编写了一个小示例并进行了调试,以查看在 opencv 代码中调用saturate_cast (link) 的矩阵加权加法,该代码又调用了cvRound。你可以在 github (link) 上看到。

【讨论】:

【参考方案3】:

如果你想得到一个浮点数那么你需要使用:

Mat G = (Green + Blue) / 2.0;

只是使用:

Mat G = (Green + Blue) / 2;

使用整数除法,因为整数中没有小数点,所以会被截断。

【讨论】:

以上是关于分裂后的OpenCv轮次的主要内容,如果未能解决你的问题,请参考以下文章

youcans 的 OpenCV 例程200篇169.图像分割之区域分离

尝试在 OpenCv 中使用来自 Mat 对象的转换后的 IplImage 对象时出错

Webbots 显示处理后的 numpy 图像(OpenCV Python)

Python使用opencv基于坐标范围批量剪裁(图像)并将剪裁后的图像保存到指定的新文件夹中

opencv图像旋转,该怎么解决

opencv 图片旋转截断问题解决方法