Почему преобразование OpenCV RGB в YCbCr не дает такого же результата, как преобразование в matlab с использованием функции ycbcr2rgb?
Я пытаюсь скопировать мой код Matlab в C с OpenCV. Здесь у меня есть шаг, где мне нужно преобразовать изображение из rgb в ycbcr и выполнить выравнивание гистограммы. Но результаты как в Matlab, так и в C очень разные.
Я использую Matlab R2016b и OpenCV 4.0.0
Какой правильный способ сделать и почему я вижу эту разницу?
Шаги, которые я выполняю в MATLAB и C, изложены ниже:
C шаги:
Прочитать кадр изображения в RGB с помощью imread()
Преобразовал изображение RGB в YCBCr с помощью cv::cvtColor()
Проверил значения канала Y
cv::Mat image, ycbcr; vector splitted; image = imread("image_name.jpg"); cv::cvtColor(image, ycbcr, COLOR_BGR2YCrCb); cv::split(ycbcr, splitted) cv::equalizeHist(splitted[0],splitted[0]); cv::merge(dst_host,ycbcr); cv::cvtColor(ycbcr, image, COLOR_YCrCb2BGR); imshow("Equalized", image);
Шаги MATLAB:
Прочитать кадр изображения в RGB с помощью imread()
Преобразовал изображение RGB в YCBCr с помощью rgb2ycbcr()
Проверил значения канала Y
im = imread('image_name.jpg'); ycbcr_im = rgb2ycbcr(im); ycbcr_im(:,:,1) = histeq(ycbcr_im(:,:,1)); im = ycbcr2rgb(ycbcr_im); imshow(im);
Итак, я проверил результаты после преобразования из rgb в ycbcr в OpenCV и MATLAB, и результат отличается в самом преобразовании.
1 ответ
Глядя на документацию по преобразованию цветов OpenCV и Matlab. Я нашел следующее. По моим наблюдениям, есть существенная разница в алгоритме и реализации.
В Matlab функция rgb2ycbcr() преобразует цвет в цифровую формулу, которая
Y = 16+ (65.481 * R + 128.553 * G + 24.966 * B)
Cb = 128+ (-37.797 * R - 74.203 * G + 112.0 * B)
Cr = 128+ (112.0 * R - 93.786 * G - 18.214 * B)
Если вводом является uint8, то YCBCR - это uint8, где Y находится в диапазоне [16 235], а Cb и Cr находятся в диапазоне [16 240].
Но в OpenCV преобразование выполняется по аналоговой формуле:
Y = 0.299 * R+ 0.587 * G+ 0.114 * B
Cb = -0.168736 * R - 0.331264 * G + 0.5 * B
Cr = 0.5 * R - 0.418688 * G - 0.081312 * B
Если вводом является uint8, то YCBCR - это uint8, где Y и Cb и Cr находятся в диапазоне [0 255]. Это причина, почему вы получаете другой результат.