Use OpenCV to convert a color image into a grayscale image

The purpose of image grayscale is to simplify the matrix and improve the operation speed.

The color of each pixel in a color image is determined by three components of R, G, and B, and the value range of each component is between 0-255, so for a computer, a pixel of a color image will be There are 256*256*256=16777216 color ranges!

The grayscale image is a special color image with the same R, G, and B components. For a computer, the variation range of a pixel is only 256 kinds of 0-255.

Suppose we have a color image now, but we want to get its grayscale image now, what should we do?

Opencv comes with this conversion function,

We can set the second parameter to 0 when reading with the imread() function, and we can directly get the grayscale image of the color image;

Mat src0 = imread("C:\\Users\\32498\\Pictures\\16.png",0);

You can also read in the color image first, and then use the cvtColor function to convert it to get its grayscale image.

Mat src = imread("C:\\Users\\32498\\Pictures\\16.png");
cvtColor(src, cvt_gray_image,COLOR_BGR2GRAY);

You can also use the psychological formula GRAY=0.299*R+0.587*G+0.114*B to write a conversion function yourself, in which the weighting coefficient is a parameter adjusted according to the brightness perception system of the human eye.


void ConvertRGB2GRAY(const Mat& image, Mat& imageGray)
{
	if (!image.data || image.channels() != 3)
	{
		return;
	}
	//创建一张单通道的灰度图像
	imageGray = Mat::zeros(image.size(), CV_8UC1);
	//取出存储图像像素的数组的指针
	uchar* pointImage = image.data;
	uchar* pointImageGray = imageGray.data;
	//取出图像每行所占的字节数
	size_t stepImage = image.step;
	size_t stepImageGray = imageGray.step;

	
	for (int i = 0; i < imageGray.rows; i++)
	{
		for (int j = 0; j < imageGray.cols; j++)
		{
			//opencv的通道顺序是BGR,而不是我们常说的RGB顺序
			pointImageGray[i * stepImageGray + j] =
				(uchar)(0.114 * pointImage[i * stepImage + 3 * j] +
					0.587 * pointImage[i * stepImage + 3 * j + 1] +
					0.299 * pointImage[i * stepImage + 3 * j + 2]);
		}
	}
}

 In multi-channel images, such as RGB images are saved like this

int  widthStep;   /* 排列的图像行大小,以字节为单位 */
int  nChannels;     /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */

The image matrix is ​​a two-dimensional array, whether it is a grayscale image or a color image, it is stored in the form of a one-dimensional array in the computer memory. When using Mat to store an image, if the image is stored continuously in memory (isContinuous == true of the Mat object), the data of the image can be regarded as a one-dimensional array, and its data (uchar*) member is Points to the first byte of the image data, so the image data can be accessed with the data pointer.

If you want to traverse the elements in it, you can use the pointer's traversal method


uchar* data=(uchar *)img->imageData;
int step = img->widthStep/sizeof(uchar);
int channels = img->nChannels;
uchar *b,*g,*r;
for(int i=0;i<img->height;i++)
     for(int j=0;j<img->width;j++){
           *b=data[i*step+j*chanels+0];
           *g=data[i*step+j*chanels+1];
           *r=data[i*step+j*chanels+2];
      }

Let's take a look at the results of grayscale conversion using these methods

#include <opencv2\opencv.hpp>
using namespace cv;
void ConvertRGB2GRAY(const Mat& image, Mat& imageGray);

int main()
{
	Mat src = imread("C:\\Users\\32498\\Pictures\\16.png");
	Mat src0 = imread("C:\\Users\\32498\\Pictures\\16.png",0);
	Mat grayImage;
    Mat cvt_gray_image;

	//读入的彩色图
	namedWindow("origin_image", WINDOW_NORMAL);
	imshow("origin_image", src);

	//opencv使用imread函数读入彩色图,设置第二个参数为0得到的灰度图
	namedWindow("opencv_image", WINDOW_NORMAL);
	imshow("opencv_image", src0);

	//使用公式GRAY=0.299*R+0.587*G+0.114*B
	ConvertRGB2GRAY(src, grayImage);
	namedWindow("my_gray_image", WINDOW_NORMAL);
	imshow("my_gray_image", grayImage);

	//先读入彩色图,然后使用cvtColor函数进行灰度转化
	cvtColor(src, cvt_gray_image,COLOR_BGR2GRAY);
	namedWindow("cvt_gray_image", WINDOW_NORMAL);
	imshow("cvt_gray_image", cvt_gray_image);
	waitKey(0);
	return 0;
}

void ConvertRGB2GRAY(const Mat& image, Mat& imageGray)
{
	if (!image.data || image.channels() != 3)
	{
		return;
	}
	//创建一张单通道的灰度图像
	imageGray = Mat::zeros(image.size(), CV_8UC1);
	//取出存储图像像素的数组的指针
	uchar* pointImage = image.data;
	uchar* pointImageGray = imageGray.data;
	//取出图像每行所占的字节数
	size_t stepImage = image.step;
	size_t stepImageGray = imageGray.step;

	
	for (int i = 0; i < imageGray.rows; i++)
	{
		for (int j = 0; j < imageGray.cols; j++)
		{
			//opencv的通道顺序是BGR,而不是我们常说的RGB顺序
			pointImageGray[i * stepImageGray + j] =
				(uchar)(0.114 * pointImage[i * stepImage + 3 * j] +
					0.587 * pointImage[i * stepImage + 3 * j + 1] +
					0.299 * pointImage[i * stepImage + 3 * j + 2]);
		}
	}
}

Guess you like

Origin blog.csdn.net/yangSHU21/article/details/130237669