【VC++、OpenCV3.4】图像亮度和对比度调整

1、图像变换可以看做像素变换(点操作)和区域上的邻域操作。

调整图像亮度和对比度属于像素变换-点操作。

【VC++、OpenCV3.4】图像亮度和对比度调整其中alpha是增益变量,另外OpenCV是基于RGB的图像操作,0-255,所以a应该是正数。

注意:提高亮度和提高对比度是不一样的。亮度是关注像素值,对比度关注像素差值。

2、重要的API

Mat new_image=Mat::zeros(image..size(),image.type());创建一张和原图大小一致的空白图像,像素值初始化为0。

saturate_cast<uchar>(value)确保值的大小范围在0-255;

Mat.at<Vec3b>(x,y)[index]=value;给每个像素点的通道赋值。

Mat对象默认是Vec3b的数据形式,如果要使用Vec3f等形式需要用函数convertTo(out,CV_32F)来转换。数据类型不对会报错

3、亮度的改变也可以直接用multiply

用法:

CV_EXPORTS_W void multiply(InputArray src1, InputArray src2,
                           OutputArray dst, double scale = 1, int dtype = -1);

代码:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<string>

using namespace cv;
//调整亮度和对比度
int main(int argc, char**argv) {

	Mat src, dst;
	src = imread("C:\\Users\\admin\\Desktop\\demo.jpg", IMREAD_COLOR);
	if (!src.data)
	{
		printf("Could not load the picture...");
		return -1;
	}

	char Input_title[] = "Source pic";
	namedWindow(Input_title, CV_WINDOW_AUTOSIZE);
	imshow(Input_title, src);

	int width = src.cols;
	int height = src.rows;
	double alpha = 1.2;
	double beta = 10.0;
	dst = Mat::zeros(src.size(), src.type());
	
	Mat m1;
	src.convertTo(m1, CV_32F);
	for (int row = 0; row < height; row++)
	{
		for (int col = 0; col < width; col++)
		{
			if (src.channels() == 3) {
				//直接使用Vec3f有报错。在使用之前需要转换
				float b = m1.at<Vec3f>(row, col)[0];
				float g = m1.at<Vec3f>(row, col)[1];
				float r = m1.at<Vec3f>(row, col)[2];
				
				dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);
				dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(b*alpha + beta);
				dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(b*alpha + beta);
			}
			else if(src.channels()==1)
			{
				float v = src.at<uchar>(row, col);
				dst.at<uchar>(row, col) = saturate_cast<uchar>(v*alpha + beta);
			}
		}

	}

	String Out_pic = "Output window";
	namedWindow(Out_pic, CV_WINDOW_AUTOSIZE);
	imshow(Out_pic, dst);
	waitKey(0);
	return 0;
}

效果图:

【VC++、OpenCV3.4】图像亮度和对比度调整