2015-01-21 4 views
1

Глядя на следующий кодOpenCV раунд после разделения

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

Mat G = (Green + Blue)/2; 

, где красный зеленый и синий каналы изображения. Если сумма Green и Blue нечетна, иногда она делает раунд, а иногда и «исправление». Например, для зеленого пикселя со значениями 120 и Синего 45 значение G равно 82 (так что он принимает только целую часть 82,5). В то время как в другом случае, когда Зеленый - 106, а Синий - 33, я получаю значение 70 для этого элемента G (так что он делает раунд, потому что (33 + 106)/2 = 69,5).

Какая операция?

ответ

5

OpenCV использует режим округления от половины к четному. Если фракция равна 0,5, она округляется до ближайшего четного целого. Вот почему 82,5 округлены до 82 и от 69,5 до 70.

+0

Спасибо за это. Ссылка на некоторую документацию по этому поводу будет приятной. – rayryeng

0

Если вы хотите, чтобы получить число с плавающей точкой, то вам нужно использовать:

Mat G = (Green + Blue)/2.0; 

Только с помощью:

Mat G = (Green + Blue)/2; 

использует целочисленное деление и так как нет знака после запятой в целое число его усекается.

1

Это различие произошло для реализации cvRound в opencv-источнике. Часть его скопирована с 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) в OpenCV коде, который вызывается INTURN cvRound. Вы можете видеть это в github (link).

Смежные вопросы