使用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图像的,没有负的;

三、图像亮度调整:

#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;
}

在这里插入图片描述
在这里插入图片描述
四、图像对比度调整

#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;
}

在这里插入图片描述
在这里插入图片描述
五、图像亮度与对比度同时调整:

#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;
}

在这里插入图片描述
在这里插入图片描述
参考文献:
https://blog.csdn.net/ivan_9/article/details/113572880

猜你喜欢

转载自blog.csdn.net/qq_27353621/article/details/125864785