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 OpenC
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."
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.
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
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
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