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
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( row , col ) =
0.2989 * rgb_image.at( row , col )[0]+
0.5870 * rgb_image.at( row , col )[1]+
0.1140 * rgb_image.at( 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_(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_(1,3)<<0.2989,0.5870,0.1140);
cv::transform(src, //src
gray, //dst
m ); //mtx
and output is like as follow