OpenCv round after division

喜夏-厌秋 提交于 2019-12-13 00:34:23

问题


Looking at the following code

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

Mat G = (Green + Blue) / 2;

where Red Green and Blue are the channels of an image. Where the sum of Green and Blue is odd, sometimes it make a round and sometimes a "fix". For example for a Green pixel with value 120 and Blue 45, the G value is 82 (so that it takes just the integer part of 82,5). While in another case where the Green is 106 and the Blue is 33 i get the value 70 for that element of G (so that, it makes a round because (33+106)/2 = 69,5 ).

Which is the operation?


回答1:


OpenCV uses "Round half to even" rounding mode. If fraction is 0.5, it rounds to the nearest even integer. That's why 82.5 is rounded to 82 and 69.5 to 70.




回答2:


That difference happened for an implementation of cvRound in opencv source. A part of it copied from github below with comments added.

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

I wrote a small sample and debugged to see that weighted addition of matrices invoked saturate_cast ( link ) in opencv code which inturn invoked cvRound. You can see that at github ( link ).




回答3:


If you want to get a floating point number then you need to use:

Mat G = (Green + Blue) / 2.0;

Just using:

Mat G = (Green + Blue) / 2;

Uses integer division and since there are no decimal points in an integer it gets truncated.



来源:https://stackoverflow.com/questions/28072053/opencv-round-after-division

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!