为什么 OpenCV RGB 到 YCbCr 的转换与使用 ycbcr2rgb 函数在 matlab 中转换的结果不同?
Why OpenCV RGB to YCbCr conversion doesn't give the same result as conversion in matlab using ycbcr2rgb function?
我正在尝试使用 OpenCV 将我的 matlab 代码复制到 C 中。在这里,我有一个步骤需要将图像从 rgb 转换为 ycbcr 并进行直方图均衡。但是在matlab和C中的结果是非常不同的。
我正在使用 Matlab R2016b 和 OpenCV 4.0.0
哪一个是正确的做法,为什么我会看到这种差异?
我在 MATLAB 和 C 中遵循的步骤如下:
C 步骤:
使用 imread()
读取 RGB 格式的图像帧
使用 cv::cvtColor()
将 RGB 图像转换为 YCBCr
检查了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 步骤:
使用 imread()
读取 RGB 格式的图像帧
使用 rgb2ycbcr()
将 RGB 图像转换为 YCBCr
检查了Y通道的值
im = imread('image_name.jpg');
ycbcr_im = rgb2ycbcr(im);
ycbcr_im(:,:,1) = histeq(ycbcr_im(:,:,1));
im = ycbcr2rgb(ycbcr_im);
imshow(im);
所以我检查了在 OpenCV 和 MATLAB 中从 rgb 转换为 ycbcr 后的结果,结果在转换本身中是不同的。
通过查看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 在 [0255] 范围内。这就是您得到不同结果的原因。
我正在尝试使用 OpenCV 将我的 matlab 代码复制到 C 中。在这里,我有一个步骤需要将图像从 rgb 转换为 ycbcr 并进行直方图均衡。但是在matlab和C中的结果是非常不同的。
我正在使用 Matlab R2016b 和 OpenCV 4.0.0
哪一个是正确的做法,为什么我会看到这种差异?
我在 MATLAB 和 C 中遵循的步骤如下:
C 步骤:
使用 imread()
读取 RGB 格式的图像帧
使用 cv::cvtColor()
将 RGB 图像转换为 YCBCr
检查了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 步骤:
使用 imread()
读取 RGB 格式的图像帧
使用 rgb2ycbcr()
将 RGB 图像转换为 YCBCr
检查了Y通道的值
im = imread('image_name.jpg'); ycbcr_im = rgb2ycbcr(im); ycbcr_im(:,:,1) = histeq(ycbcr_im(:,:,1)); im = ycbcr2rgb(ycbcr_im); imshow(im);
所以我检查了在 OpenCV 和 MATLAB 中从 rgb 转换为 ycbcr 后的结果,结果在转换本身中是不同的。
通过查看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 在 [0255] 范围内。这就是您得到不同结果的原因。