Opencv图像的亮度和对比度调整

前言

图像的亮度和对比度调整

一、图像亮度和对比度的基本概念:

1、图像亮度:

图像亮度就是画面的明亮程度(灰度图像,则跟灰度值有关,灰度值越高则图像越亮),单位是堪德拉每平米(cd/m2)或称nits。
图象亮度是从白色表面到黑色表面的感觉连续体,由反射系数决定,亮度侧重物体,重在“反射”。

例如:灰度图像是单通道的,灰度值在【0,255】之间,越接近‘0’,亮度越暗,越接近‘255’,亮度越亮。

2、图像对比度:

图像对比度就是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,即指一幅图像灰度反差的大小

解析:差异范围越大代表对比越大,差异范围越小代表对比越小,好的对比率120:1就可容易地显示生动、丰富的色彩,当对比率高达300:1时,便可支持各阶的颜色。

二、RGB三通道色彩空间的图像变换:

1、线性变换公式如下:

在这里插入图片描述
公式解析:
       系数α用来调整点的对比度;系数β用来调整点的亮度;

       1)当α=1,β=0时,图像无任何改变;

       2)当α<1,β=0时,图像对比度下降,图像变暗;

       3)当α>1,β=0时,图像对比度上升,图像变生动、丰富;

       4)β上下浮动,图像亮度发生改变,不改变图像对比度;

       5)α的值>0,因为opencv是针对BGR图像的,没有负的;
在这里插入图片描述

2、操作简介:

领域操作简介:通过当前位置的邻域像素计算新的像素值。当邻域包含图像的上几行和下几行时,就需要同时扫描图像的若干行。

点操作简介:对图像的每一个像素点进行操作。

3、图像亮度调整:

代码块:

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

using namespace std;
using namespace cv;
int main() {
    
    
	Mat src, dst;
	src = imread("D:\\Myfile\\素材照片\\opencv素材照片\\8.jpg");
	if (!src.data) {
    
    
		cout << "could not load image..." << endl;
		return 0;
	}
	char input_win[] = "input_image";
	//用来命名显示窗口的名称
	namedWindow(input_win, WINDOW_AUTOSIZE);
	imshow(input_win, src);

	//用at函数对像素点进行操作,改变亮度
	int height = src.rows;
	int width = src.cols;
	float beta = 30;
	dst = Mat::zeros(src.size(), src.type());
	for (int row = 0; row < height; row++) {
    
    
		for (int col = 0; col < width; col++) {
    
    
			if (src.channels() == 3) {
    
    
				float b = src.at<Vec3b>(row, col)[0];
				float g = src.at<Vec3b>(row, col)[1];
				float r = src.at<Vec3b>(row, col)[2];

				dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b + beta);
				dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g + beta);
				dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r + beta);
			}
			else if (src.channels() == 1) {
    
    
				float v_gray = src.at<uchar>(row, col);
				dst.at<uchar>(row, col) = saturate_cast<uchar>(v_gray + beta);
			}
		}
	}

	namedWindow(input_win, WINDOW_AUTOSIZE);
	imshow("output_image", dst);


	waitKey(0);
	return 0;
}

运行结果:
在这里插入图片描述

4、图像对比度调整:

代码块:

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

using namespace std;
using namespace cv;
int main() {
    
    
	Mat src, dst;
	src = imread("D:\\Myfile\\素材照片\\opencv素材照片\\8.jpg");
	if (!src.data) {
    
    
		cout << "could not load image..." << endl;
		return 0;
	}
	char input_win[] = "input_image";
	//用来命名显示窗口的名称
	namedWindow(input_win, WINDOW_AUTOSIZE);
	imshow(input_win, src);

	//用at函数对像素点进行操作,改变对比度
	int height = src.rows;
	int width = src.cols;
	float alpha = 1.5;
	dst = Mat::zeros(src.size(), src.type());
	for (int row = 0; row < height; row++) {
    
    
		for (int col = 0; col < width; col++) {
    
    
			if (src.channels() == 3) {
    
    
				float b = src.at<Vec3b>(row, col)[0];
				float g = src.at<Vec3b>(row, col)[1];
				float r = src.at<Vec3b>(row, col)[2];

				dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha);
				dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha);
				dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha);
			}
			else if (src.channels() == 1) {
    
    
				float v_gray = src.at<uchar>(row, col);
				dst.at<uchar>(row, col) = saturate_cast<uchar>(v_gray * alpha);
			}
		}
	}

	namedWindow(input_win, WINDOW_AUTOSIZE);
	imshow("output_image", dst);


	waitKey(0);
	return 0;
}

运行结果:

在这里插入图片描述

5、三通道图像转换为单通道图像的方法:

1)通过imread方法,在后面添加参数 IMREAD_GRAYSCALE

src = imread("D:\\Myfile\\素材照片\\opencv素材照片\\8.jpg", IMREAD_GRAYSCALE);

2)通过cvtColor方法,直接转换色彩空间为灰度图像,类似于创建新的图像

cvtColor(src, src, COLOR_BGR2GRAY);

6、图像亮度与对比度同时调整:

代码块(三通道和单通道的测试代码如下):

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

using namespace std;
using namespace cv;
int main() {
    
    
	Mat src, dst;
	src = imread("D:\\Myfile\\素材照片\\opencv素材照片\\8.jpg");
	//src = imread("D:\\Myfile\\素材照片\\opencv素材照片\\8.jpg", IMREAD_GRAYSCALE);
	//通过imread的读取方式,直接读取单通道的图像
	if (!src.data) {
    
    
		cout << "could not load image..." << endl;
		return 0;
	}
	//调整为灰度图像进行测试
	//cvtColor(src, src, COLOR_BGR2GRAY);

	char input_win[] = "input_image";
	//用来命名显示窗口的名称
	namedWindow(input_win, WINDOW_AUTOSIZE);
	imshow(input_win, src);

	//用at函数对像素点进行操作,改变对比度和亮度
	int height = src.rows;
	int width = src.cols;
	float alpha = 1.3;
	float beta = 30;
	dst = Mat::zeros(src.size(), src.type());
	for (int row = 0; row < height; row++) {
    
    
		for (int col = 0; col < width; col++) {
    
    
			if (src.channels() == 3) {
    
    
				float b = src.at<Vec3b>(row, col)[0];
				float g = src.at<Vec3b>(row, col)[1];
				float r = src.at<Vec3b>(row, col)[2];

				dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta);
				dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + beta);
				dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
			}
			else if (src.channels() == 1) {
    
    
				float v_gray = src.at<uchar>(row, col);
				dst.at<uchar>(row, col) = saturate_cast<uchar>(v_gray * alpha + beta);
			}
		}
	}
	//转化为32f的,让调整的精度更高!!!!!!!!!!!!!!!!!!!
	//int height = src.rows;
	//int width = src.cols;
	//float alpha = 1.3;
	//float beta = 30;
	//Mat src_converto_32f; //转化32f
	//src.convertTo(src_converto_32f, CV_32F);
	//dst = Mat::zeros(src.size(), src.type());
	//for (int row = 0; row < height; row++) {
    
    
	//	for (int col = 0; col < width; col++) {
    
    
	//		if (src.channels() == 3) {
    
    
	//			float b = src_converto_32f.at<Vec3f>(row, col)[0];
	//			float g = src_converto_32f.at<Vec3f>(row, col)[1];
	//			float r = src_converto_32f.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>(g * alpha + beta);
	//			dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
	//		}
	//		else if (src.channels() == 1) {
    
    
	//			float v_gray = src.at<uchar>(row, col);
	//			dst.at<uchar>(row, col) = saturate_cast<uchar>(v_gray * alpha + beta);
	//		}
	//	}
	//}

	namedWindow(input_win, WINDOW_AUTOSIZE);
	imshow("output_image", dst);


	waitKey(0);
	return 0;
}

运行结果:
在这里插入图片描述

在这里插入图片描述

三、获取图片亮度值

三通道亮度计算公式:
       亮度=R*0.299+G*0.587+B*0.114

代码块:

//计算图像亮度
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;
int main() {
    
    
	Mat src;
	src = imread("D:\\Myfile\\素材照片\\opencv素材照片\\8.jpg", IMREAD_GRAYSCALE);
	//src
	if (!src.data) {
    
    
		cout << "could not load image..." << endl;
		return 0;
	}
	namedWindow("input_image", WINDOW_AUTOSIZE);
	imshow("input_image", src);
	
	int height = src.rows;
	int channel = src.channels();
	int width = src.cols;
	if (channel == 3) {
    
    
		int length = height * width * channel;
		int sumb = 0, sumg = 0, sumr = 0;
		for (int row = 0; row < height ; row++) {
    
    
			for (int col = 0; col < width; col++) {
    
    
				int b = src.at<Vec3b>(row, col)[0];
				int g = src.at<Vec3b>(row, col)[1];
				int r = src.at<Vec3b>(row, col)[2];
				sumb += b;
				sumg += g;
				sumr += r;
			}
		}
		//三通道计算公式:Y = 0.299 * R + 0.587 * G + 0.114 * B
		cout << "三通道图像的平均亮度是:" << sumr * 0.299 + 0.587 * sumg + 0.114 * sumb << endl;
	}
	else {
    
    
		int length = height * width;
		int sum = 0;
		for (int row = 0; row < height; row++) {
    
    
			for (int col = 0; col < width; col++) {
    
    
				int v_gray = src.at<uchar>(row, col);
				sum += v_gray;
			}
		}
		cout << "单通道图像的平均亮度是:" << sum * 0.1 / length << endl;
	}


	waitKey(0);
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

总结

图像的亮度和对比度调整,图像亮度和对比度并不是独立的个体,是相互影响,相互依赖的

如有错误,敬请指正!

猜你喜欢

转载自blog.csdn.net/ivan_9/article/details/113572880