OpenCV 4.10.0
开源计算机视觉
|
上一教程: 使用 OpenCV 添加(混合)两张图像
下一教程: 离散傅里叶变换
最初作者 | Ana Huamán |
兼容性 | OpenCV >= 3.0 |
在本教程中,您将学习如何
两个常用的点进程是乘法和加法,常量
\[g(x) = \alpha f(x) + \beta\]
您可以将 \(f(x)\) 视为源图像像素,将 \(g(x)\) 视为输出图像像素。然后,我们可以更方便地将表达式写为
\[g(i,j) = \alpha \cdot f(i,j) + \beta\]
其中 \(i\) 和 \(j\) 表示像素位于第 i 行和第 j 列。
我们观察到 cv::Mat::zeros 返回基于 image.size() 和 image.type() 的 Matlab 风格的零初始化程序
请注意以下内容(仅限 C++ 代码)
其中cv::Mat::convertTo会有效地执行*new_image = a*image + beta*。但是,我们想向你展示如何访问每个像素。无论如何,这两种方法都会给出相同的结果,但是convertTo更加优化,并且运行速度快得多。
在本段中,我们将实践已学内容,通过调节图像的亮度和对比度,来校正曝光不足的图像。我们还将了解另一种校正图像亮度的技术,即伽马校正。
增加(/ 减少)\(\beta\)值会向每个像素添加(/ 减去)一个常量值。位于 [0 ; 255] 范围之外的像素值将饱和(即像素值高于 (/ 低于) 255 (/ 0) 将被夹制为 255 (/ 0))。
直方图对于每个颜色级别表示具有该级别颜色的像素数量。暗图像具有很多带有低颜色值的像素,因此其直方图会在其左部分呈现一个峰。叠加一个常量偏差后,由于我们为所有像素叠加了一个常量偏差,因此直方图向右移动。
\(\alpha\) 参数将修改级别展开方式。如果 \( \alpha < 1 \),则颜色级别将被压缩,结果将是一幅对比度较小的图像。
请注意,这些直方图已使用 Gimp 软件中的亮度-对比度工具获取。亮度工具应与 \(\beta\) 偏差参数相同,但对比度工具似乎不同于 \(\alpha\) 增益,且输出范围在 Gimp 中似乎是居中的(您可以在前一个直方图中注意到这一点)。
可能会发生这种情况,即使用 \(\beta\) 偏差可以提升亮度,但同时还会使图像略显朦胧,因为对比度会降低。可以使用 \(\alpha\) 增益来减弱这种效果,但由于饱和度,我们在原始亮部区域中会丢失一些细节。
Gamma 校正可用于通过在输入值和映射输出值之间使用非线性变换来校正图像亮度
\[O = \left( \frac{I}{255} \right)^{\gamma} \times 255\]
由于这一关系是非线性的,因此效果对于所有像素来说并不相同,而且将取决于它们的原始值。
当 \( \gamma < 1 \) 时,原始暗区域将变得更亮,并且直方图向右移动,而当 \( \gamma > 1 \) 时则相反。
已使用以下方式校正了以下图像:\( \alpha = 1.3 \) and \( \beta = 40 \)。
整体亮度已得到提升,但您会注意到由于使用的实现的数值饱和(摄影中的高光裁切),现在云层极度饱和。
已使用以下方式校正了以下图像: \( \gamma = 0.4 \)。
由于映射是非线性的,并且不存在如前一种方法中的数值饱和,因此 Gamma 校正趋于增加更少饱和度效果。
上图 (y 轴范围对于三个直方图不同) 对比了这三张图像的直方图。你可以注意到对于原图来说,大多数像素值位于直方图的较低部分。在进行 \( \alpha \), \( \beta \) 校正之后,我们可以看到由于饱和而在 255 处有一个较大的峰值以及向右偏移。在进行伽马校正之后,直方图向右偏移,但黑暗区域的像素偏移更多 (参见 伽马曲线图),比明亮区域的像素偏移更多。
在本教程中,你看到了两种简单的调节图像对比度和亮度的办法。它们是基本技术,不打算用作光栅图形编辑器的替代品!
伽马校正代码
查找表用于提高计算的性能,因为只需要计算一次 256 个值。