Norhan Shaker
Norhan Shaker

Reputation: 21

OpenCV and MATLAB gray scale values differ for the same image

In MATLAB, i read a color video , extract a certain frame and convert it to a gray scale image using the rgb2gray function.But when I load the same video with OpenCV2.3.1, extract the same frame and then convert it to gray scale it doesn't give the same gray scale values as MATLAB. Why is that?

This is the C++ code using OpenCV:

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

Upvotes: 1

Views: 1612

Answers (3)

Saeed Masoomi
Saeed Masoomi

Reputation: 1834

I get this problem too , in MATLAB documents i can found rgb2gray implementation and it was so easy as follow

gray_value = 0.2989 * R + 0.5870 * G + 0.1140 * B

So i implement this algorithm in OpenCV as follow

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];        
   }

}

and this code will give same result as matlab, and in OpenCV you can use below code to regenerate it:

cv::cvtColor( rgb_image , gray_image , CV_BGR2GRAY );  //BLUE+GREEN+RED

but if you use below code

cv::cvtColor( rgb_image , gray_image , CV_RGB2GRAY ); //RED+GREEN+BLUE

then this algorithm will be in reverse order as follows:

gray_value = 0.2989 * R->B + 0.5870 * G->G + 0.1140 * B->R

and the output not same as MATLAB output


using cv::transform function

I found a handy and useful function in opencv named cv::transform that implement above things in easiest way . if we have three Mat matrix named src for source image and gray for destination Matrix and m is a matrix that affect a transportation to every channel. by this matrixs we can implement CV_BGR2GRAY and CV_RGB2GRAY as follows

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

output will like as follow image enter image description here

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

and output is like as follow enter image description here

Upvotes: 2

Majid Daryadel
Majid Daryadel

Reputation: 27

The OpenCV Reference Manual, Release 2.4.10.0, Page 283: "Note that the default color format in OpenCV is often referred to as RGB but it is actually BGR (the bytes are reversed). So the first byte in a standard (24-bit) color image will be an 8-bit Blue component, the second byte will be Green, and the third byte will be Red."

Upvotes: -1

RaulPL
RaulPL

Reputation: 241

First, all color images in OpenCV are BGR and not RGB so maybe one of the problems could be that OpenCV is making the transformation wrong. You should use BGR2GRAY. And second, If I remember well in matlab yo should specify which are the ranges of values in your image. You have to put between 0 and 255 for a gray image.

I hope this can help you.

Upvotes: 5

Related Questions