【opencv】教程代码 —ImgProc (3)亮度、对比度和gamma校正

亮度、对比度和gamma校正在图像处理中是非常重要的基础操作,它们用来改善图像的视觉效果,让图像的细节更加清晰,或者适应不同的显示设备和输出媒介。下面分别对这三种操作做个简要解释:

  1. 亮度调整(Brightness Adjustment):

  • 亮度是指图像的整体光度或明亮程度。

  • 调整图像的亮度可以提高或降低图像的整体亮度水平。

  • 在某些场合,比如照片太暗或太亮时,适当调整亮度可以使图像细节更加容易被观察到。

对比度调整(Contrast Adjustment):

  • 对比度是指图像中明暗区域间的差异程度。

  • 增加对比度会使明亮部分更亮,暗部分更暗,从而使图像的颜色或灰度跳跃更加明显,增强图像的深度感和立体感。

  • 减少对比度则会使图像看起来更柔和、细节更连续,但可能会导致图像看起来较为平淡。

Gamma校正(Gamma Correction):

  • Gamma校正是一种非线性的操作,用于校正图像的亮度,对中间色调的亮度有较大影响,而对于非常亮或非常暗的区域影响较小。

  • 它通常用于校正由于图像的捕获、显示或打印设备造成的色彩畸变。

  • Gamma校正通过调整图像的中值灰度,而不是整个范围内均匀地修改亮度,可以更自然地调整图像的明暗程度,使其更接近人眼对亮度的非线性感知,从而在暗部和高光部分均保留更多细节。

在应用中,这些操作可以单独或组合来使用,例如在提高图像对比度的同时调整亮度,使得图像更适合打印输出或者显示器查看。此外,在机器视觉领域,这些预处理步骤也可以帮助算法更好地识别图像中的特征。

如何利用亮度、对比度和gamma校正来提高图像的视觉效果?

2922f4faa1932e5ae47bdd77f76851e5.png

3. changing_contrast_brightness_image.cpp

b087e64c7c8efc1a6c940d3c57843342.png

这段代码用于演示如何使用OpenCV库来调整图像的亮度、对比度以及应用Gamma校正。它通过创建两个窗口和三个滑动条来让用户交互式地调整图像的属性,并将原始图像与调整后的图像并列显示,最后还可以将调整后的图像保存下来。

主要的过程如下:

  1. 利用命令行参数读入一个图像。

  2. 初始化全局变量和合成图像(用于显示效果)。

  3. 创建两个窗口,并对其中一个窗口添加三个滑动条,用于动态调整alpha(对比度)、beta(亮度)和gamma(用于Gamma校正)。

  4. 根据每个滑动条的位置,实时更新图像的效果。

  5. 当用户完成调整后,可以通过键盘输入保存调整过的图像。

#include <iostream> // 包含标准输入输出流的头文件
#include "opencv2/imgcodecs.hpp" // 包含OpenCV图像编解码的头文件
#include "opencv2/highgui.hpp" // 包含OpenCV高级用户界面的头文件


// 我们这里没有使用 "using namespace std;" ,以避免名称冲突,例如标准C++17中的std::beta和我们的变量beta
using std::cout; // 使用std命名空间中的cout
using std::endl; // 使用std命名空间中的endl
using namespace cv; // 使用cv命名空间,cv是OpenCV的命名空间


namespace // 匿名命名空间
{
/** 全局变量 */
int alpha = 100; // 用于线性变换对比度的全局变量
int beta = 100; // 用于线性变换亮度的全局变量
int gamma_cor = 100; // 用于Gamma矫正的全局变量
Mat img_original, img_corrected, img_gamma_corrected; // 分别存储原图像、线性变换后的图像和Gamma矫正后的图像


// 基础线性变换函数
void basicLinearTransform(const Mat &img, const double alpha_, const int beta_)
{
    Mat res;
    img.convertTo(res, -1, alpha_, beta_); // 将图像进行线性变换(对比度和亮度调整)


    hconcat(img, res, img_corrected); // 将原图像和调整后的图像拼接
    imshow("Brightness and contrast adjustments", img_corrected); // 显示亮度和对比度调整后的图像
}


// Gamma矫正函数
void gammaCorrection(const Mat &img, const double gamma_)
{
    CV_Assert(gamma_ >= 0); // 断言确保gamma_非负
    //! [changing-contrast-brightness-gamma-correction]
    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); // 填充查询表,应用Gamma变换


    Mat res = img.clone();
    LUT(img, lookUpTable, res); // 应用查询表进行Gamma矫正
    //! [changing-contrast-brightness-gamma-correction]


    hconcat(img, res, img_gamma_corrected); // 将原图像和Gamma矫正后的图像拼接
    imshow("Gamma correction", img_gamma_corrected); // 显示Gamma矫正后的图像
}


// 处理对比度调节滑动条的回调函数
void on_linear_transform_alpha_trackbar(int, void *)
{
    double alpha_value = alpha / 100.0; // 将滑动条的值转换为实际的alpha值
    int beta_value = beta - 100; // 将滑动条的值转换为实际的beta值
    basicLinearTransform(img_original, alpha_value, beta_value); // 应用基础线性变换
}


// 处理亮度调节滑动条的回调函数
void on_linear_transform_beta_trackbar(int, void *)
{
    double alpha_value = alpha / 100.0; // 将滑动条的值转换为实际的alpha值
    int beta_value = beta - 100; // 将滑动条的值转换为实际的beta值
    basicLinearTransform(img_original, alpha_value, beta_value); // 应用基础线性变换
}


// 处理Gamma校正滑动条的回调函数
void on_gamma_correction_trackbar(int, void *)
{
    double gamma_value = gamma_cor / 100.0; // 将滑动条的值转换为实际的Gamma值
    gammaCorrection(img_original, gamma_value); // 应用Gamma矫正
}
}


int main( int argc, char** argv )
{
    CommandLineParser parser( argc, argv, "{@input | lena.jpg | input image}" ); // 解析命令行参数
    img_original = imread( samples::findFile( parser.get<String>( "@input" ) ) ); // 读入图像
    if( img_original.empty() ) // 判断图像是否为空
    {
      cout << "Could not open or find the image!\n" << endl;
      cout << "Usage: " << argv[0] << " <Input image>" << endl;
      return -1;
    }


    img_corrected = Mat(img_original.rows, img_original.cols*2, img_original.type()); // 创建空白图像用于存放线性变换后的图像
    img_gamma_corrected = Mat(img_original.rows, img_original.cols*2, img_original.type()); // 创建空白图像用于存放Gamma矫正后的图像


    hconcat(img_original, img_original, img_corrected); // 初始时将原图像拼接成宽度为两倍的图像
    hconcat(img_original, img_original, img_gamma_corrected); // 同上


    namedWindow("Brightness and contrast adjustments"); // 创建窗口
    namedWindow("Gamma correction"); // 创建窗口


    // 创建滑动条
    createTrackbar("Alpha gain (contrast)", "Brightness and contrast adjustments", &alpha, 500, on_linear_transform_alpha_trackbar);
    createTrackbar("Beta bias (brightness)", "Brightness and contrast adjustments", &beta, 200, on_linear_transform_beta_trackbar);
    createTrackbar("Gamma correction", "Gamma correction", &gamma_cor, 200, on_gamma_correction_trackbar);


    // 初始调用回调函数进行图像显示
    on_linear_transform_alpha_trackbar(0, 0);
    on_gamma_correction_trackbar(0, 0);


    waitKey(); // 等待用户响应


    // 保存调整后的图像
    imwrite("linear_transform_correction.png", img_corrected);
    imwrite("gamma_correction.png", img_gamma_corrected);


    return 0;
}

a7c5d1c47216fce529889240ec4ca0a5.png

a42615a354306dc6273fdeae0a22c7bb.png

f5fffad9d2be5916a4ef0dd0a1b96b83.png

最近更新

  1. TCP协议是安全的吗?

    2024-03-28 11:12:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-28 11:12:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-28 11:12:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-28 11:12:03       18 阅读

热门阅读

  1. Linux系统账号文件

    2024-03-28 11:12:03       16 阅读
  2. axios配置以及说明

    2024-03-28 11:12:03       18 阅读
  3. Flutter 绘制原理

    2024-03-28 11:12:03       19 阅读
  4. 数据结构奇妙旅程之深入解析希尔排序

    2024-03-28 11:12:03       17 阅读
  5. Unity DOTS系列之IJobChunk来迭代处理数据

    2024-03-28 11:12:03       23 阅读
  6. 3月26日,每日信息差

    2024-03-28 11:12:03       15 阅读