当前位置: 首页 > news >正文

OpenCV图像亮度与对比度调整

1. Mat类和图像基本操作

在OpenCV中,图像是通过Mat类(Matrix)表示的,这实际上是一个二维的矩阵,矩阵中的每个元素对应图像中的一个像素。一个图像的每个像素值都有多个通道,例如BGR图像每个像素包含三个值(蓝色、绿色和红色)。

  • src:输入图像。

  • dst:处理后的输出图像。

  • m:用于调整亮度或对比度的辅助矩阵。

2. 亮度调整的原理

亮度调整实际上是对每个像素值增加一个常数。例如,增加某个值会让所有像素变亮,减少某个值会让图像变暗。

代码中的亮度调整是通过add()函数实现的,它的作用是将输入图像src和一个辅助矩阵m按像素加和。

代码解析:
m = Scalar(lightness, lightness, lightness); // 创建一个与src同大小的矩阵m,每个元素的值为lightness
add(src, m, dst);  // 将src和m相加,结果存入dst,实现亮度调整
  • Scalar(lightness, lightness, lightness):创建一个常量矩阵m,每个通道的值都为lightness。这个矩阵的作用是调整亮度。

  • add(src, m, dst)add函数会将图像src和矩阵m中的每个像素相加,结果保存在dst中。如果m的值是正的,图像就会变亮,负的则变暗。

3. 对比度调整的原理

对比度调整是通过放大或缩小像素值之间的差异来实现的。如果图像的像素差异被放大,对比度就增加;如果被缩小,对比度就降低。

代码解析:
addWeighted(image, 1.0, m, 0, b, dst); // 使用加权和来调整亮度
  • addWeighted():是OpenCV中用于加权合并两幅图像的函数。其公式为:
    [ dst = \text{image} \times \alpha + m \times \beta + \gamma ]

    • image 是原始图像。

    • m 是辅助矩阵,通常是零矩阵。

    • alphabeta 分别控制图像和矩阵的权重。

    • gamma 是一个常数,用于调整亮度。

在这里,addWeighted(image, 1.0, m, 0, b, dst) 实现了通过加权合成图像来调整亮度,其中b代表亮度调整的值。

4. 滑动条(Trackbar)的使用

OpenCV中的**滑动条(Trackbar)**允许用户通过GUI界面实时控制图像的亮度和对比度。当滑动条的值发生变化时,会触发一个回调函数,从而实时更新图像。

代码解析:
createTrackbar("Value Bar:", "亮度调整", &lightness, max_value, on_track);
  • createTrackbar:用于创建一个滑动条控件,用来调整图像的参数(如亮度和对比度)。

    • "Value Bar:":滑动条的标签。

    • "亮度调整":滑动条所在的窗口名称。

    • &lightness:指向亮度值的指针,滑动条的当前值会存储在lightness变量中。

    • max_value:滑动条的最大值,表示亮度的最大调整值。

    • on_track:当滑动条值发生变化时,会调用的回调函数。

5. 回调函数(Callback Function)

回调函数on_lightnesson_contrast在滑动条的值发生变化时被调用。每当用户调整滑动条时,on_track函数会被触发,它会重新计算亮度或对比度,并更新图像。

代码解析:
static void on_lightness(int b, void* userdata) {Mat image = *((Mat*)userdata);  // 将用户数据(图像)转换为Mat类型Mat dst = Mat::zeros(image.size(), image.type());  // 创建一个空的目标图像Mat m = Mat::zeros(image.size(), image.type());  // 创建一个空的矩阵,用于亮度调整addWeighted(image, 1.0, m, 0, b, dst);  // 调整亮度imshow("亮度与对比度调整", dst);  // 显示调整后的图像
}
  • int b:表示当前滑动条的值,控制亮度。

  • (void* userdata):传递给回调函数的用户数据,这里是图像数据。

  • addWeighted(image, 1.0, m, 0, b, dst):通过加权合成图像来调整亮度。

  • imshow("亮度与对比度调整", dst):显示处理后的图像。

6. 总结:如何使用滑动条调整亮度和对比度

  • 创建窗口:使用namedWindow创建一个窗口来显示图像。

  • 创建滑动条:通过createTrackbar函数创建滑动条,用于调节图像的亮度和对比度。

  • 回调函数:每当滑动条的值发生变化时,on_lightnesson_contrast回调函数会被调用,重新计算图像的亮度和对比度,并更新显示的图像。

  • 图像更新:通过imshow实时显示调整后的图像。

7. 相关知识点总结

  1. Mat:OpenCV的图像表示方式,每个像素包含多个通道(例如BGR图像有三个通道)。

  2. 图像加法(add:可以用来调整图像的亮度。

  3. 加权合成(addWeighted:用于调整图像的亮度和对比度,通过设置权重和常数来加权合并两幅图像。

  4. 滑动条(Trackbar):提供一种交互方式,让用户实时调整图像的参数。

  5. 回调函数:当滑动条的值变化时触发回调函数,更新图像。

8. 代码演示

#include<opencv2/opencv.hpp>
#include <string.h>
using namespace cv;
const std::string picpath = "C:\\Users\\ZZM\\Pictures\\豆绘AI_3711794.jpg";Mat src, dst, m;
int lightness = 50;  // 初始亮度值// 亮度调整的回调函数
static void on_lightness(int b, void* userdata) {Mat image = *((Mat*)userdata);  // 获取用户传递的图像数据Mat dst = Mat::zeros(image.size(), image.type());  // 创建目标图像Mat m = Mat::zeros(image.size(), image.type());  // 创建一个零矩阵,用于亮度调整// 调整亮度addWeighted(image, 1.0, m, 0, b, dst);imshow("亮度与对比度调整", dst);  // 显示调整后的图像
}// 对比度调整的回调函数
static void on_contrast(int b, void* userdata) {Mat image = *((Mat*)userdata);  // 获取用户传递的图像数据Mat dst = Mat::zeros(image.size(), image.type());  // 创建目标图像Mat m = Mat::zeros(image.size(), image.type());  // 创建一个零矩阵,用于对比度调整double contrast = b / 100.0;  // 将对比度值映射到[0, 2]范围addWeighted(image, contrast, m, 0, 0, dst);  // 调整对比度imshow("亮度与对比度调整", dst);  // 显示调整后的图像
}int main() {// 加载图像Mat image = imread(picpath);if (image.empty()) {std::cout << "无法加载图像!" << std::endl;return -1;}// 创建窗口namedWindow("亮度与对比度调整", WINDOW_NORMAL);resizeWindow("亮度与对比度调整", image.cols, image.rows);// 创建亮度滑动条int lightness = 50;int max_value = 250;createTrackbar("亮度:", "亮度与对比度调整", &lightness, max_value, on_lightness, (void*)(&image));// 创建对比度滑动条int contrast_value = 100;createTrackbar("对比度:", "亮度与对比度调整", &contrast_value, 200, on_contrast, (void*)(&image));// 初始亮度和对比度调整on_lightness(50, &image);on_contrast(100, &image);waitKey(0);  // 等待用户按键return 0;
}

http://www.dtcms.com/a/597029.html

相关文章:

  • 应急响应基础
  • jsp技术做网站有什么特点免费软件下载网站入口正能量
  • WSL2下Ubuntu20.04图形化环境配置
  • Ubuntu单用户
  • h5制作网站哪个好杭州做网站的公司
  • 软装设计师常用网站英文网站建设一般多少钱
  • 数据结构之顺序表(动态)
  • Prover9/Mace4 的形式化语言简介
  • CSDN文章如何转出为PDF文件保存
  • 多级缓存解决方案
  • C++ 二分查找(Binary Search):从原理到实战的全面解析
  • Synbo Protocol 受邀出席ETHShanghai 2025,以共识机制重构链上融资生态
  • 软考 系统架构设计师历年真题集萃(198)—— 2025年11月系统架构设计师真题1
  • 专业网站开发服务电商网站建设哪个好
  • 哈希表和unordered_map和unordered_set
  • HTTP报文格式
  • 厦门网页建站申请费用怎么找出网站的备案号
  • maven专题
  • 渭南市住房和城乡建设局官方网站定制网站和模板网站及仿站的区别
  • Data Agent业务场景方案分析
  • AWS ALB 和目标组异常事件监控实战
  • python中模拟浏览器操作之playwright使用说明以及打包浏览器驱动问题
  • pnpm环境下防止误使用npm的方法
  • 服务器证书与网站不符2020中国企业500强榜单
  • 医疗电子试验箱 生物电子实验箱 生物医学教学平台 嵌入式生物医学电子实验箱
  • 网易云音乐解析(无损音乐均可下载)
  • android StateFlow和sharedflow
  • 幽冥大陆(十八)手机摄像头注册到电脑源码——东方仙盟炼气期
  • 2025年渗透测试面试题总结-240(题目+回答)
  • 防滑齿构型与牙体组织损伤风险的相关性分析