Wednesday, 2 December 2015

How to convert a color image into grayscale image without using CV_LOAD_IMAGE_GRAYSCALE

GrayScale(greyscale) image as the name suggests have  various shades of grey (ranging from black to white)present in the image.
Each pixel in grayscale image is stored as a byte i.e. 8 bits.
Thus the pixel value can range from 0 to 255.
Where 0 represents black and 255 represents white.

All the intermediate values have a shade of grey with increasing black color component as the pixel value approaches 0.
Thus the pixel values only carries the intensity information where black refers weakest intensity to that of white the strongest intensity.
Hence greyscale images are said to have only 1 channel.

The basic parameter is
                                 X=(a*R+b*G+c*B)
Depending upon the values of a,b,c we have two main methods of converting an RGB image into GreyScale.
1. Weighted average method:
Here a=b=c=1/3
         X=( R + G + B )/3
   i.e. X=(0.33*R+0.33*G+0.33*B)
Thus here have taken 33% of contribution of red,green and blue colors each.
But in reality ,based on human visual system we do not see each color as 1/3rd of its intensity.
Our eye is more sensitive to green compared to that of red and blue.
Thus there came the second method called as luminosity method.
The code and output by weighted sum method is as shown below:
// OpenCV Grayscale Image Tutorial 
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
 const float pi=3.14;
 Mat src1,src2;
 src1 = imread("C:\\Users\\arjun\\Desktop\\abcd.png",CV_LOAD_IMAGE_COLOR);
 src2 = Mat::zeros(src1.rows,src1.cols, CV_8UC1);

 if( !src1.data ) { printf("Error loading src1 \n"); return -1;}

for (int i=0; i<src1.cols ; i++){
for (int j=0 ; j<src1.rows ; j++)
 { 
Vec3b color1 = src1.at<Vec3b>(Point(i,j));
Scalar color2 = src2.at<uchar>(Point(i,j));
      color2 = (color1.val[0]+color1.val[1]+color1.val[2])/3;

   src2.at<uchar>(Point(i,j)) = color2.val[0];
  }
 }

//imwrite("C:\\Users\\arjun\\Desktop\\greyscale.jpg",src2);

namedWindow("GRAYSCALE_IMAGE",CV_WINDOW_AUTOSIZE); 
imshow("GRAYSCALE_IMAGE", src2); 

namedWindow("Original Image",CV_WINDOW_AUTOSIZE); 
imshow("Original Image", src1);

 waitKey(0);
 return 0;
}

Input Image:

Output Image:


2. Luminosity method:
X=0.3*R+0.59*G+0.11*B
Note: In OpenCV the default color ordering is BGR rather than RGB.
Refer the code below:
// OpenCV GrayScale Image  Tutorial 
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
 const float pi=3.14;
 Mat src1,src2;
 src1 = imread("C:\\Users\\arjun\\Desktop\\abcd.png",CV_LOAD_IMAGE_COLOR);
 src2 = Mat::zeros(src1.rows,src1.cols, CV_8UC1);

 if( !src1.data ) { printf("Error loading src1 \n"); return -1;}

for (int i=0; i<src1.cols ; i++){
for (int j=0 ; j<src1.rows ; j++)
 { 
Vec3b color1 = src1.at<Vec3b>(Point(i,j));
Scalar color2 = src2.at<uchar>(Point(i,j));
      color2 = (0.11*color1.val[0]+0.59*color1.val[1]+0.3*color1.val[2]);

   src2.at<uchar>(Point(i,j)) = color2.val[0];
  }
 }

//imwrite("C:\\Users\\arjun\\Desktop\\greyscale.jpg",src2);

namedWindow("GRAYSCALE_IMAGE",CV_WINDOW_AUTOSIZE); 
imshow("GRAYSCALE_IMAGE", src2); 

namedWindow("Original Image",CV_WINDOW_AUTOSIZE); 
imshow("Original Image", src1);

 waitKey(0);
 return 0;
}

Input Image:
opencv CV_LOAD_IMAGE_COLOR


Output Image:
OPENCV CV_LOAD_IMAGE_GRAYSCALE

Note: Compare the two greyscale Images and note the difference between the output of the two images.
The green component of an image in luminosity method is much lighter compared to that of the other two color components since the green channel is multiplied by 0.59 which is much much greater than that of the other two constants which are used for other two channels.

Also as we increase this factor more the more the higher intensity that particular channel would get, thus if would have multiplied it by 1 that particular channel would have appeared white in greyscale image.

Significance:
It tells us  about the luminosity (intensity component) of each image.
The size of the greyscale image is comparatively less than that of its corresponding color part(if they use the same encoding and compression factor), since it uses only a single channel to represent the information.

No comments:

Post a Comment