除法后的 OpenCv 回合

OpenCv round after division

看下面的代码

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

Mat G = (Green + Blue) / 2;

其中红绿蓝是图像的通道。如果绿色和蓝色的总和是奇数,有时它会变成一个回合,有时会变成 "fix"。例如,对于值为 120 的绿色像素和值为 45 的蓝色像素,G 值为 82(因此它只取 82,5 的整数部分)。而在另一种情况下,绿色为 106,蓝色为 33,我得到 G 的该元素的值 70(因此,它进行了一次循环,因为 (33+106)/2 = 69,5)。

操作是什么?

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

Mat G = (Green + Blue) / 2.0;

正在使用:

Mat G = (Green + Blue) / 2;

使用整数除法,由于整数中没有小数点,它会被截断。

OpenCV 使用 "Round half to even" 舍入模式。如果 fraction 为 0.5,则四舍五入为最接近的偶数。这就是为什么 82.5 舍入为 82,69.5 舍入为 70。

这种差异发生在 opencv 源代码中 cvRound 的实现。其中一部分从下面的 github 复制而来,并添加了注释。

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;
}

我编写了一个小示例并进行了调试,以查看调用的矩阵加权加法 saturate_cast ( link ) in opencv code which inturn invoked cvRound. You can see that at github ( link )。