【opencv4.3.0教程】13之调整图像的亮度与对比度

2023-12-11 20:33

本文主要是介绍【opencv4.3.0教程】13之调整图像的亮度与对比度,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

前言

一、亮度与对比度

1、什么是亮度和对比度

2、亮度和对比度调整原理

3、亮度和对比度调整代码实现

4、API-convertScaleAbs

二、伽马校正

1、伽马校正引入

2、伽马校正原理

3、伽马校正代码实现


前言

我们在拍照的时候,经常需要通过调整图像的亮度及对比度来调整图像的美感,让我们拍出的照片更有意境。特别是女孩子,喜欢拍一些美美哒皂片!

但如果你的男朋友掌握不好角度,亮度和对比度,那可能就是大型拍照翻车现场了。

你眼中的自己和男友眼中的你

 好吧,说回正题,如果我们不考虑拍的丑不丑,我们只想让图片亮度对比度调整一下,还是可以做到滴!接下来让我们走进今天的内容吧!

一、亮度与对比度

1、什么是亮度和对比度

亮度与对比度其实是图像处理中的概念。我们在调整台式电脑的显示界面,就可以调整亮度与对比度。

亮度是指画面的明亮程度;

对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,即指一幅图像灰度反差的大小。差异范围越大代表对比越大,差异范围越小代表对比越小,好的对比率120:1就可容易地显示生动、丰富的色彩,当对比率高达300:1时,便可支持各阶的颜色。

上面是百科的定义,我们怎么去理解呢?

亮度比较容易理解,阳光下的图片一般都亮,夜晚的图片一般都暗。我们也经常调整手机屏幕和电脑屏幕的亮度。

对比度我们常常听到,从对比二字来看,我们可以理解为两个像素差距大不大,对比起来差距明显不明显。对比度越高,那两个像素的差距越大。其实就是色彩空间中能够表示的范围,范围越广,对比越强烈,对比度越大,同样的,展现出的图像的效果也就越好。如果我们拍景色,在一个伸手不见五指的黑夜去拍,还不开闪光灯,拍出一个近乎纯黑的景色,但如果是白天,晴空万里,阳光明媚,我们再去拍摄,景物分明,而且非常迷人。这就是对比度小和对比度大的区别。

2、亮度和对比度调整原理

那如果我们想要调整亮度和对比度,我们其实就是调整像素值。

亮度其实调整的就是每个像素的大小,像素值越大,越接近白色,就越亮,像素值越小,越接近黑色图像就越黑。所以调整亮度其实就是给像素值增加一个变量值,变量值为正,就是调亮,变量值为负,就是调暗。公式表示如下:

对比度调整的是像素区别,一般来说,图像中相邻位置的像素差别较小,我们想增强对比度,那就需要将差别按倍数扩大,要降低对比度,就要按比例缩小。所以调整对比度就是给像素值添加一个倍数,倍数大于1,就是增强对比度,倍数小于1,就是减少对比度。公式表示如下:

我们使用一个统一的公式来表示,就可以同时调整亮度和对比度,公式如下:

3、亮度和对比度调整代码实现

了解了原理,我们就使用代码实现一下吧!上面公式中的f(x)表示原始像素,g(x)表示调整后的像素。所以我们还需要用到我们之前讲的图像像素指针,来修改像素值,我们要考虑,我们修改的是三通道彩色图像,还是灰度图像。

如果是灰度图像,我们修改方式如下:

	float f = src.at<uchar>(row, col);dst.at<uchar>(row, col) = saturate_cast<uchar>(f*alpha + beta);

如果是彩色图像,我们就需要修改每一个通道的值:

float b = m1.at<Vec3f>(row, col)[0];// bluefloat g = m1.at<Vec3f>(row, col)[1]; // greenfloat r = m1.at<Vec3f>(row, col)[2]; // reddst.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);

而对于一幅图像,我们需要根据其类型来选择不同的方式,所以我们需要判断一下图像的通道数:

if (src.channels() == 3) {float b = m1.at<Vec3f>(row, col)[0];// bluefloat g = m1.at<Vec3f>(row, col)[1]; // greenfloat r = m1.at<Vec3f>(row, col)[2]; // reddst.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 f = src.at<uchar>(row, col);dst.at<uchar>(row, col) = saturate_cast<uchar>(f*alpha + beta);
}

有了这些实现的核心代码,我们就可以遍历所有的像素点,来调整图像了。全部代码如下:

	Mat YT = imread("./image/YiTian1.jpg");if (!YT.data){cout << "ERROR : could not load image.\n";return -1;}imshow("倚天屠龙记", YT);Mat new_YT = YT.clone();float alpha = 1.0; // 调整对比度float beta = -50;   // 调整亮度YT.convertTo(YT, CV_32F);for (int row = 0; row < YT.rows; row++) {for (int col = 0; col < YT.cols; col++) {if (YT.channels() == 3) {float b = YT.at<Vec3f>(row, col)[0];// bluefloat g = YT.at<Vec3f>(row, col)[1]; // greenfloat r = YT.at<Vec3f>(row, col)[2]; // rednew_YT.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);new_YT.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha + beta);new_YT.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta);}else if (YT.channels() == 1) {float f = YT.at<uchar>(row, col);new_YT.at<uchar>(row, col) = saturate_cast<uchar>(f*alpha + beta);}}}imshow("倚天-调整亮度", new_YT);

执行结果如下:

调整对比度:alpha = 1.2,beta = 0
调整对比度:alpha = 0.8,beta = 0
调整亮度:alpha = 1.0,beta = 50
调整亮度:alpha = 1.0,beta = -50

4、API-convertScaleAbs

OpenCV中提供了API-convertScaleAbs,可以实现类似的功能,这个API的功能是:

缩放、计算绝对值并将结果转换为8位。

API如下:

void convertScaleAbs(InputArray src, OutputArray dst,                                  double alpha = 1, double beta = 0
);

参数含义如下:

(1)InputArray类型的src,输入图像。

(2)OutputArray类型的dst,输出图像。

(3)double类型的alpha,可选比例因子。。

(4)double类型的beta,添加到缩放值的可选增量。

举个栗子:

	Mat YT = imread("./image/YiTian1.jpg");if (!YT.data){cout << "ERROR : could not load image.\n";return -1;}imshow("倚天屠龙记", YT);Mat YT_convertScaleAbs;convertScaleAbs(YT, YT_convertScaleAbs,1.9,-50);imshow("倚天屠龙记-convertScaleAbs", YT_convertScaleAbs);

调整后的图像

二、伽马校正

1、伽马校正引入

我们前面通过线性的方式调整图像的亮度和对比度,调整之后,效果可能不是那么理想,毕竟“直男”太直了!

所以我们需要考虑非线性调整方式,看看如果是非线性,会有什么样的效果呢?

这就是我们接下来要讲的伽马校正。

2、伽马校正原理

伽马校正数学公式很简单:

I表示的是输入图像,O表示输出图像,γ是参数,我们可以通过调整不同的γ得到不同的结果:

不同伽马值的绘图

3、伽马校正代码实现

理解了公式,我们实现也很简单:

if (YT.channels() == 3) {float b = YT.at<Vec3f>(row, col)[0];// bluefloat g = YT.at<Vec3f>(row, col)[1]; // greenfloat r = YT.at<Vec3f>(row, col)[2]; // rednew_YT.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(pow(b / 255.0, gamma) * 255.0);new_YT.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(pow(g / 255.0, gamma) * 255.0);new_YT.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(pow(r / 255.0, gamma) * 255.0);
}
else if (YT.channels() == 1) {float f = YT.at<uchar>(row, col);new_YT.at<uchar>(row, col) = saturate_cast<uchar>(pow(f / 255.0, gamma) * 255.0);
}

有了这些实现的核心代码,我们就可以遍历所有的像素点,来调整图像了。全部代码如下:

	Mat YT = imread("./image/YiTian1.jpg");if (!YT.data){cout << "ERROR : could not load image.\n";return -1;}imshow("倚天屠龙记", YT);	Mat new_YT = YT.clone();YT.convertTo(YT, CV_32F);float gamma = 1.6;for (int row = 0; row < YT.rows; row++) {for (int col = 0; col < YT.cols; col++) {if (YT.channels() == 3) {float b = YT.at<Vec3f>(row, col)[0];// bluefloat g = YT.at<Vec3f>(row, col)[1]; // greenfloat r = YT.at<Vec3f>(row, col)[2]; // rednew_YT.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(pow(b / 255.0, gamma) * 255.0);new_YT.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(pow(g / 255.0, gamma) * 255.0);new_YT.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(pow(r / 255.0, gamma) * 255.0);}else if (YT.channels() == 1) {float f = YT.at<uchar>(row, col);new_YT.at<uchar>(row, col) = saturate_cast<uchar>(pow(f / 255.0, gamma) * 255.0);}}}imshow("倚天-伽马校正", new_YT);

执行结果如下:

今天我们讲的就到这里啦,大家要多做练习才能掌握更深哦!

这篇关于【opencv4.3.0教程】13之调整图像的亮度与对比度的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/482027

相关文章

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

如何为Yarn配置国内源的详细教程

《如何为Yarn配置国内源的详细教程》在使用Yarn进行项目开发时,由于网络原因,直接使用官方源可能会导致下载速度慢或连接失败,配置国内源可以显著提高包的下载速度和稳定性,本文将详细介绍如何为Yarn... 目录一、查询当前使用的镜像源二、设置国内源1. 设置为淘宝镜像源2. 设置为其他国内源三、还原为官方

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

Maven的使用和配置国内源的保姆级教程

《Maven的使用和配置国内源的保姆级教程》Maven是⼀个项目管理工具,基于POM(ProjectObjectModel,项目对象模型)的概念,Maven可以通过一小段描述信息来管理项目的构建,报告... 目录1. 什么是Maven?2.创建⼀个Maven项目3.Maven 核心功能4.使用Maven H

IDEA自动生成注释模板的配置教程

《IDEA自动生成注释模板的配置教程》本文介绍了如何在IntelliJIDEA中配置类和方法的注释模板,包括自动生成项目名称、包名、日期和时间等内容,以及如何定制参数和返回值的注释格式,需要的朋友可以... 目录项目场景配置方法类注释模板定义类开头的注释步骤类注释效果方法注释模板定义方法开头的注释步骤方法注

Python虚拟环境终极(含PyCharm的使用教程)

《Python虚拟环境终极(含PyCharm的使用教程)》:本文主要介绍Python虚拟环境终极(含PyCharm的使用教程),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录一、为什么需要虚拟环境?二、虚拟环境创建方式对比三、命令行创建虚拟环境(venv)3.1 基础命令3

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

OpenCV图像形态学的实现

《OpenCV图像形态学的实现》本文主要介绍了OpenCV图像形态学的实现,包括腐蚀、膨胀、开运算、闭运算、梯度运算、顶帽运算和黑帽运算,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起... 目录一、图像形态学简介二、腐蚀(Erosion)1. 原理2. OpenCV 实现三、膨胀China编程(

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.

Python 安装和配置flask, flask_cors的图文教程

《Python安装和配置flask,flask_cors的图文教程》:本文主要介绍Python安装和配置flask,flask_cors的图文教程,本文通过图文并茂的形式给大家介绍的非常详细,... 目录一.python安装:二,配置环境变量,三:检查Python安装和环境变量,四:安装flask和flas