1

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

3 回答 3

5

首先,OpenCV 中的所有彩色图像都是 BGR 而不是 RGB,所以问题之一可能是 OpenCV 使转换错误。您应该使用 BGR2GRAY。其次,如果我在 matlab 中记得很清楚,你应该指定图像中的值范围。对于灰度图像,您必须在 0 到 255 之间输入。

我希望这可以帮助你。

于 2012-09-07T03:54:35.063 回答
2

我也遇到了这个问题,在 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矩阵命名的矩阵,并且是一个影响到每个通道的传输的矩阵。通过这个矩阵,我们可以实现如下srcgraymCV_BGR2GRAYCV_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

输出如下 在此处输入图像描述

于 2017-04-17T15:45:36.050 回答
-1

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

于 2015-01-14T05:30:25.433 回答