我也遇到了这个问题,在 MATLAB 文档中我可以找到 rgb2gray 实现,它很简单,如下所示
gray_value = 0.2989 * R + 0.5870 * G + 0.1140 * B
所以我在OpenCV中实现这个算法如下
cv::Mat rgb_image = imread("/what/ever/directory/that/was/optional.jpg" );
int nrows = rgb_image.rows; // number of columns
int ncols = rgb_image.cols; // number of rows
cv::Mat gray_image( nrows , ncols , CV_8UC1 ); // define one channel Mat with same size as rgb_image
for(int row = 0; row < rgb_image.rows ; row++)
{
for(int col = 0 ; col < pic.cols ; col++)
{
//matlab algorithm for rgb2gray
gray.at<unsigned char>( row , col ) =
0.2989 * rgb_image.at<Vec3b>( row , col )[0]+
0.5870 * rgb_image.at<Vec3b>( row , col )[1]+
0.1140 * rgb_image.at<Vec3b>( row , col )[2];
}
}
并且此代码将给出与 matlab 相同的结果,在 OpenCV 中,您可以使用以下代码重新生成它:
cv::cvtColor( rgb_image , gray_image , CV_BGR2GRAY ); //BLUE+GREEN+RED
但是如果你使用下面的代码
cv::cvtColor( rgb_image , gray_image , CV_RGB2GRAY ); //RED+GREEN+BLUE
那么这个算法将按照相反的顺序如下:
gray_value = 0.2989 * R->B + 0.5870 * G->G + 0.1140 * B->R
并且输出与 MATLAB 输出不同
使用 cv::transform 函数
我在 opencv 中找到了一个方便且有用的函数,cv::transform
它以最简单的方式实现上述功能。如果我们有三个以源图像和目标Mat
矩阵命名的矩阵,并且是一个影响到每个通道的传输的矩阵。通过这个矩阵,我们可以实现如下src
gray
m
CV_BGR2GRAY
CV_RGB2GRAY
1-CV_BGR2GRAY
Mat src, gray, m ;
src=imread(" ");
m=(Mat_<float>(1,3)<<0.1140,0.5870,0.2989);
cv::transform(src, //src
gray, //dst
m ); //mtx
输出如下图
2-CV_RGB2GRAY
Mat src, gray, m ;
src=imread(" ");
m=(Mat_<float>(1,3)<<0.2989,0.5870,0.1140);
cv::transform(src, //src
gray, //dst
m ); //mtx
输出如下