OpenCV调整图像对比度和亮度
一、学习目标
- 理解图像对比度和亮度调整的原理
- 对比三种不同亮度和对比度调整方法
二、原理理解
1、对比度
对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,差异范围越大代表对比越大,差异范围越小代表对比越小,好的对比率120:1就可容易地显示生动、丰富的色彩,当对比率高达300:1时,便可支持各阶的颜色。但对比率遭受和亮度相同的困境,现今尚无一套有效又公正的标准来衡量对比率,所以最好的辨识方式还是依靠使用者眼睛。
对比度对视觉效果的影响非常关键,一般来说对比度越大,图像越清晰醒目,色彩也越鲜明艳丽;而对比度小,则会让整个画面都灰蒙蒙的。高对比度对于图像的清晰度、细节表现、灰度层次表现都有很大帮助。在一些黑白反差较大的文本显示、CAD显示和黑白照片显示等方面,高对比度产品在黑白反差、清晰度、完整性等方面都具有优势。相对而言,在色彩层次方面,高对比度对图像的影响并不明显。对比度对于动态视频显示效果影响要更大一些,由于动态图像中明暗转换比较快,对比度越高,人的眼睛越容易分辨出这样的转换过程。
2、亮度
图象亮度是指画面的明亮程度,单位是堪德拉每平米(cd/m2)或称nits。图象亮度是从白色表面到黑色表面的感觉连续体,由反射系数决定,亮度侧重物体,重在“反射”。亮度是一副图像给人的一种直观感受,如果是灰度图像,则跟灰度值有关,灰度值越高则图像越亮。在RGB图像中,亮度体现为每个点的像素值的大小,像素值越大,亮度越高。
3、对比度和亮度调整公式

参数α>0和β通常被称为增益参数和偏置参数;有时这些参数被称为分别控制对比度和亮度。
可以认为 f(x) 是源图像像素,g(x) 是输出图像像素。然后,我们可以更方便地将表达式写成:

其中i和j表示像素位于第i行和第j列。α 作为系数乘以源像素值,会扩大最大像素值和最小像素值之间的差异,从而提升对比度。β 作为加数,直接增大源像素值,能提升亮度。
三、对比度、亮度调整
1、直接套用公式实现
for( int y = 0; y < image.rows; y++ ) {
for( int x = 0; x < image.cols; x++ ) {
for( int c = 0; c < image.channels(); c++ ) {
new_image.at<Vec3b>(y,x)[c] =
saturate_cast<uchar>( alpha*image.at<Vec3b>(y,x)[c] + beta );
}
}
}
执行操作 g(i,j) = α ⋅ f(i,j) + β ,访问图像中的每个像素。因为我们是在操作BGR图像,所以每个像素有三个值(B, G和R),所以我们需要分别访问它们。
2、使用 cv::Mat::convertTo() 函数
cv::Mat::convertTo 的函数原型为:
void cv::Mat::convertTo (OutputArray m,
int rtype,
double alpha = 1,
double beta = 0) const
- 参数 m:输出矩阵;如果在操作之前没有正确的大小或类型,则重新分配。
- 参数 rtype:所需的输出矩阵类型,或者更确切地说,深度,通道的数量与输入相同;如果rtype为负,则输出矩阵将与输入矩阵具有相同的类型。
- 参数 alpha:可选的比例因子,用于调整对比度。
- 参数 beta:可选的缩放因子,用于调整亮度。
该函数是Mat对象的一个方法,用于将Mat的数组转换为另一种可选伸缩的数据类型。
该方法将源像素值转换为目标数据类型。其转换公式为:

satate_cast <> 应用于最后以避免可能的数值溢出。计算公式基本与对比度和亮度调整公式一致。
调用代码如下:
image.convertTo(new_image, -1, alpha

本文介绍如何使用OpenCV调整图像的对比度和亮度,包括对比度和亮度的概念、调整原理,以及通过不同方法实现调整的具体步骤。还探讨了伽玛校正作为一种改进方案的应用。

7931

被折叠的 条评论
为什么被折叠?



