OpenCV和MATLAB灰度值对于同一图像是不同的

时间:2012-09-05 13:20:43

标签: matlab opencv

在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)<<' ';
    }
}

3 个答案:

答案 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 function

我在名为cv::transform的opencv中找到了一个方便实用的函数,它以最简单的方式实现了上述功能。如果我们有三个名为Mat的{​​{1}}矩阵用于源图像,src用于目标矩阵,gray是一个影响到每个频道的传输的矩阵。通过此矩阵,我们可以实现mCV_BGR2GRAY,如下所示

1-CV_BGR2GRAY

CV_RGB2GRAY

输出将如下图所示 enter image description here

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

和输出如下 enter image description here

答案 2 :(得分:0)

OpenCV参考手册,版本2.4.10.0,页面283: “请注意,OpenCV中的默认颜色格式通常称为RGB,但它实际上是BGR(字节相反)。因此标准(24位)彩色图像中的第一个字节将是8位蓝色组件,第二个字节为绿色,第三个字节为红色。“