在MATLAB中,我读取彩色视频,提取某个帧并使用rgb2gray
函数将其转换为灰度图像。但是当我使用OpenCV2.3.1加载相同的视频时,提取相同的帧并且然后将其转换为灰度,它不会提供与MATLAB相同的灰度值。那是为什么?
这是使用OpenCV的C ++代码:
VideoCapture cap(0);
cap.open("Human sperm evaluation_0.avi");
Mat image;
Mat gray(480,640,CV_8U);
for(int i=0;i<513;i++)
{
cap>>image;
cvtColor(image,gray,CV_RGB2GRAY);
}
for(int i=0;i<20;i++)
{
for(int j=0;j<20;j++)
{
cout<<(int)gray.at<uchar>(i,j)<<' ';
}
}
答案 0 :(得分:4)
首先,OpenCV中的所有彩色图像都是BGR而不是RGB,所以可能其中一个问题可能是OpenCV导致转换错误。你应该使用BGR2GRAY。 第二,如果我在matlab中记得很清楚你应该指定图像中值的范围。对于灰色图像,您必须在0到255之间。
我希望这可以帮到你。
答案 1 :(得分:1)
我也遇到了这个问题,在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输出相同,与下面代码相同
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中找到了一个方便实用的函数,它以最简单的方式实现了上述功能。如果我们有三个名为Mat
的{{1}}矩阵用于源图像,src
用于目标矩阵,gray
是一个影响到每个频道的传输的矩阵。通过此矩阵,我们可以实现m
和CV_BGR2GRAY
,如下所示
1-CV_BGR2GRAY
CV_RGB2GRAY
2-CV_RGB2GRAY
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 :(得分:0)
OpenCV参考手册,版本2.4.10.0,页面283: “请注意,OpenCV中的默认颜色格式通常称为RGB,但它实际上是BGR(字节相反)。因此标准(24位)彩色图像中的第一个字节将是8位蓝色组件,第二个字节为绿色,第三个字节为红色。“