在我成功地在MATLAB中实现了jpeg算法之后,我正在尝试用openCV复制jpeg算法。我注意到MATLAB和OpenCV对于颜色空间从RGB到YCbCr的转换给出了不同的结果。
从OpenCV的文档来看,似乎唯一要使用的函数是cv::cvtColor,但是打印Y、Cb和Cr的第一个8x8子矩阵,它们是不一样的。
这是我为MATLAB和C++编写的代码( OpenCV 4.0.1)。
Matlab:
% Read rgb image
imgrgb = imread('lena512color.bmp');
% Convert to ycbcr
imgycbcr = rgb2ycbcr(imgrgb);
% Extract the 3 components
luma = imgycbcr (:,:,1);
cb = imgycbcr (:,:,2);
cr = imgycbcr (:,:,3);
C++:
// Load img
cv::Mat bgrImg = imread( "lena512color.bmp", cv::IMREAD_COLOR );
assert( bgrImg.data && "No image data");
// Declare an empty Mat for dst image
cv::Mat ycrcbImg;
// Convert to ycrcb
cv::cvtColor(bgrImg, ycrcbImg, cv::COLOR_BGR2YCrCb);
// Split bgr into 3 channels
cv::Mat bgrChan[3];
cv::split(bgrImg, bgrChan);
// Split ycrcb into 3 channels
cv::Mat ycrcbChan[3];
cv::split(ycrcbImg, ycrcbChan);
// Print first block for each channel
PRINT_MAT(ycrcbChan[0](cv::Rect(0, 0, 8, 8)), "LUMA (first 8x8 block)")
PRINT_MAT(ycrcbChan[1](cv::Rect(0, 0, 8, 8)), "Cr (first 8x8 block)")
PRINT_MAT(ycrcbChan[2](cv::Rect(0, 0, 8, 8)), "Cb (first 8x8 block)")
PRINT_MAT(bgrChan[0](cv::Rect(0, 0, 8, 8)), "Blue (first 8x8 block)")
PRINT_MAT(bgrChan[1](cv::Rect(0, 0, 8, 8)), "Green (first 8x8 block)")
PRINT_MAT(bgrChan[2](cv::Rect(0, 0, 8, 8)), "Red (first 8x8 block)")
其中PRINT_MAT
是以下宏:
#define PRINT_MAT(mat, msg) std::cout<< std::endl <<msg <<":" <<std::endl <<mat <<std::endl;
打印出RGB通道,对于Matlab和OpenCV,我获得相同的值(对于前8x8块),而对于Y、Cb和Cr,则得到不同的值。例如,对于Luma组件:
Matlab:
155 155 155 154 155 150 156 154
155 155 155 154 155 150 156 154
155 155 155 154 155 150 156 154
155 155 155 154 155 150 156 154
155 155 155 154 155 150 156 154
157 157 151 149 154 153 152 153
154 154 156 152 154 155 153 150
152 152 149 150 152 152 150 151
OpenCV:
162 162 162 161 162 157 163 161
162 162 162 161 162 157 163 161
162 162 162 161 162 157 163 161
162 162 162 161 162 157 163 161
162 162 162 161 162 157 163 161
164 164 158 155 161 159 159 160
160 160 163 158 160 162 159 156
159 159 155 157 158 159 156 157
什么是正确的转换?为什么结果是不同的?
发布于 2019-02-10 13:50:24
事实证明两者都是“正确的”。而OpenCV为Y采用了整个范围,而MATLAB则为16,235。这个推理可以在另一个问题/回答中看到。
您可以在MATLAB 文档中阅读
图像在YCbCr颜色空间中,返回为m-by n-by-3数组.
在OpenCV 文档中
..。
Y,Cr和Cb覆盖整个值范围。
https://stackoverflow.com/questions/54615539
复制相似问题