用OpenCV改变图像的对比度和亮度

两个常用的函数是常数的乘法加法

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

这里的i,j表示该像素位于第i第j列。

以下代码执行该操作

cpp 复制代码
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
 
// we're NOT "using namespace std;" here, to avoid collisions between the beta variable and std::beta in c++17
using std::cin;
using std::cout;
using std::endl;
using namespace cv;
 
int main( int argc, char** argv )
{
    CommandLineParser parser( argc, argv, "{@input | lena.jpg | input image}" );
    Mat image = imread( samples::findFile( parser.get<String>( "@input" ) ) );
    if( image.empty() )
    {
      cout << "Could not open or find the image!\n" << endl;
      cout << "Usage: " << argv[0] << " <Input image>" << endl;
      return -1;
    }
 
    Mat new_image = Mat::zeros( image.size(), image.type() );
 
    double alpha = 1.0; /*< Simple contrast control */
    int beta = 0;       /*< Simple brightness control */
 
    cout << " Basic Linear Transforms " << endl;
    cout << "-------------------------" << endl;
    cout << "* Enter the alpha value [1.0-3.0]: "; cin >> alpha;
    cout << "* Enter the beta value [0-100]: ";    cin >> beta;
 
    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 );
            }
        }
    }
 
    imshow("Original Image", image);
    imshow("New Image", new_image);
 
    waitKey();
    return 0;
}

结果:

在本段中,我们将实践所学知识,通过调整图像的亮度和对比度来校正曝光不足的图像。我们还将看到另一种校正图像亮度的技术,称为伽马校正。

亮度和对比度调整

增加(/减少)β值将为每个像素添加(/减去)一个常数值。超出 [0 ; 255] 范围的像素值将饱和(即,高于(/小于)255(/ 0)的像素值将被限制为 255(/ 0))。

直方图表示每个颜色级别的像素数量。暗色图像将有许多低色值像素,因此直方图的左侧部分将出现峰值。添加恒定偏差时,直方图会向右移动,因为我们已向所有像素添加了恒定偏差。

这α参数将修改水平的分布方式。如果α<1,色彩级别将被压缩,导致图像对比度降低。

请注意,这些直方图是使用 Gimp 软件中的亮度对比度工具获得的。亮度工具应与β偏差参数,但对比工具似乎与α增益,其中输出范围似乎以 Gimp 为中心(正如您在前面的直方图中看到的)。

可能会发生β偏差会提高亮度,但同时图像会因对比度降低而出现轻微的模糊。α可以使用增益来减弱这种影响,但由于饱和度,我们会丢失原始明亮区域的一些细节。

伽马校正

伽马校正可用于通过在输入值和映射的输出值之间使用非线性变换来校正图像的亮度:

由于这种关系是非线性的,因此对于所有像素而言,效果不会相同,并且取决于它们的原始值。

什么时候γ<1,原来的暗区将变得更亮,直方图将向右移动,而γ>1。

校正曝光不足的图像

以下图片已修正:α=1.3和β=40。

整体亮度有所改善,但您可以注意到,由于所用实现的数值饱和度(摄影中的高光剪辑),云现在已大大饱和。

以下图片已修正:γ=0.4。


左:alpha、beta校正后的直方图;中:原始图像的直方图;右:gamma校正后的直方图

上图比较了三幅图像的直方图(三幅直方图的 y 范围不一样)。您可以注意到,原始图像的大多数像素值都位于直方图的下半部分。经过α,β校正后,我们可以观察到由于饱和度而导致的 255 处的大峰值以及向右的偏移。经过伽马校正后,直方图向右移动,但暗区像素的偏移比亮区像素更大(参见伽马曲线)。

在本教程中,您已经了解了两种调整图像对比度和亮度的简单方法。它们是基本技术,并非旨在替代光栅图形编辑器!

伽马校正的代码:

cpp 复制代码
    Mat lookUpTable(1, 256, CV_8U);
    uchar* p = lookUpTable.ptr();
    for( int i = 0; i < 256; ++i)
        p[i] = saturate_cast<uchar>(pow(i / 255.0, gamma_) * 255.0);
 
    Mat res = img.clone();
    LUT(img, lookUpTable, res);

参考:OpenCV官方文档。

相关推荐
文心快码BaiduComate29 分钟前
百度云与光本位签署战略合作:用AI Agent 重构芯片研发流程
前端·人工智能·架构
风象南1 小时前
Claude Code这个隐藏技能,让我告别PPT焦虑
人工智能·后端
Mintopia2 小时前
OpenClaw 对软件行业产生的影响
人工智能
陈广亮2 小时前
构建具有长期记忆的 AI Agent:从设计模式到生产实践
人工智能
会写代码的柯基犬3 小时前
DeepSeek vs Kimi vs Qwen —— AI 生成俄罗斯方块代码效果横评
人工智能·llm
Mintopia3 小时前
OpenClaw 是什么?为什么节后热度如此之高?
人工智能
爱可生开源社区3 小时前
DBA 的未来?八位行业先锋的年度圆桌讨论
人工智能·dba
叁两6 小时前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
前端付豪6 小时前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain