#matlab #opencv #rgb #color-conversion
#matlab #opencv #rgb #преобразование цвета
Вопрос:
Я пытаюсь скопировать свой код 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. Какую ОС вы используете?
2. Вы не можете прочитать изображение в RGB в OpenCV с помощью
imread()
. Вы получите BGR и должны использовать в нем соответствующийcvtColor()
with BGR .3. Я использую Ubuntu 18.04
4. Это не то, что говорится в вашем вопросе…
5. @MarkSetchell Я использую макрос COLOR_BGR2YCrCb. Это код для преобразования из RGB в YCbCr в OpenCV. cv::cvtColor(src, dst, COLOR_BGR2YCrCb)
Ответ №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]. Это причина, по которой вы получаете другой результат.
Комментарии:
1. Один предназначен для видео / телевидения (первый, ограниченный диапазон), а второй — для фотографий (полный диапазон).