OpenCv раунд после деления

Глядя на следующий код

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

Mat G = (Green + Blue) / 2;

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

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


person user2614596    schedule 21.01.2015    source источник


Ответы (3)


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

person jet47    schedule 21.01.2015
comment
Спасибо за это. Ссылка на некоторую документацию по этому поводу была бы хорошей. - person rayryeng; 03.02.2017

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

person kiranpradeep    schedule 21.01.2015

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

Mat G = (Green + Blue) / 2.0;

Просто используя:

Mat G = (Green + Blue) / 2;

Использует целочисленное деление, и, поскольку в целом числе нет десятичных точек, оно усекается.

person NathanOliver    schedule 21.01.2015