问题
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