C++版OpenCV_03_图像增强

图像增强

  • 3.1 直方图
  • 3.2 线性变换
  • 3.3 直方图归一化
  • 3.4 Gamma变换

3.1 直方图

概念:计算图像单个通道像素的分布。
步骤:把图像灰度级分为n个区间,计算每个区间像素的频数,把频数转化为频率,得到图像的直方图。如果图像有多个通道,分别计算每个通道的直方图。


Mat calcGrayHist02(const Mat &image,int bins)
{   // histogram矩阵Mat histogram = Mat::zeros(Size(1, bins), CV_32SC1);int step = int(256/bins);//图像的高和宽int rows = image.rows;int cols = image.cols;for (int r = 0; r < rows; r++){for (int c = 0; c < cols; c++){int index = int(image.at<uchar>(r, c));index /= step;if index>bins-1{index-=index}histogram.at<int>(0, index) += 1;}}return histogram;
}

3.2 线性变换

/*Mat::convertTo(OutputArray m, int rtype, double alpha=1, double beta=0)
m 代表输出矩阵;
参数 rtype 是输出矩阵 m 的数据类型;
参数 alpha 和 beta 分别可以理解为线性变换中的 𝑎 和 𝑏。
*/
Mat I = (Mat_<uchar>(2, 2) << 10, 30, 31, 25);
Mat O;
I.convertTo(O, CV_8UC1, 1.5, 3);
//第二种方法
Mat O=1.5*I+20;
//线性变换的第三种方式
//convertScaleAbs(InputArray src, OutputArray dst, double alpha=1, double beta=0)
Mat I = (Mat_<uchar>(2, 2) << 0, 200, 23, 4);
Mat O;
convertScaleAbs(I,O,1.23,10);

3.3 直方图归一化

把图像直方图缩放到指定区间

/*
o(i,j) = o_min+ (img(i,j)-img_min)*((o_max-o_min)/(img_max-img_min))+void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc
=0, Point* maxLoc=0, InputArray mask=noArray())src 输入矩阵
minVal 最小值,double 类型指针
maxVal 最大值,double 类型指针
minLoc 最小值的位置索引,Point 类型指针
maxLoc 最大值的位置索引,Point 类型指针
*/Mat I = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
//找到 I 的最大值和最小值
double Imax, Imin;
minMaxLoc(I, &Imin, &Imax, NULL, NULL);
//设置 Omin和Omax
double Omin = 0, Omax = 255;
//计算 a 和 b
double a = (Omax - Omin) / (Imax - Imin);
double b = Omin - a*Imin;
//线性变换
Mat O;
convertScaleAbs(I, O, a, b);
//显示原图和直方图正规化的效果
imshow("I", I);
imshow("O", O);

归一化函数 normalize

/*
void normalize(InputArray src, OutputArray dst, double alpha=1, double beta=0,
int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray())
src 输入矩阵
dst 输出矩阵
alpha 系数
beta 系数
norm_type 归一化类型:一范数、二范、无穷大范数、NORM_MINMAX(先把像素值缩放到0~1之间,再乘以目标区间范围(最大减最小),最后加上目标区间的最小值。
dtype 数据类型
*/
#include<opencv2/core.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/highgui.hpp>
using namespace cv;
int main(int argc, char*argv[])
{//输入图像Mat src = imread(argv[1], CV_LOAD_IMAGE_ANYCOLOR);if (!src.data)return -1;//直方图正规化Mat dst;normalize(src, dst, 255-20, 20, NORM_MINMAX, CV_8U);
}

3.4 Gamma变换

Gamma变换用来调节图像的亮度,先把图像I除以255得到I1,使得像素值归一化到0~1之间,再求I1的r次方。当r<1时,图像整体变亮;当r>1时,图像整体变暗。

/*
Gamma变换公式
img = (img/255.0)**y 
对矩阵中的每一个值进行幂运算:
void pow(InputArray src, double power, OutputArray dst)*/
//输入图像矩阵
Mat I = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
//灰度值归一化
Mat fI;
I.convertTo(fI, CV_64F, 1.0 / 255, 0);
//伽马变换
double gamma = 0.5;
Mat O;
pow(fI, gamma, O);//注意 O 和 fI 有相同的数据类型
//显示伽马变换后的效果
imshow("O",O);
O.convertTo(O, CV_8U, 255,0);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/49988.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV 遍历Mat,像素操作,使用TrackBar 调整图像的亮度和对比度 C++实现

文章目录 1.使用C遍历Mat,完成颜色反转1.1 常规遍历方式1.2 迭代器遍历方式1.3指针访问方式遍历&#xff08;最快&#xff09;1.4不同遍历方式的时间对比 2.图像像素操作&#xff0c;提高图像的亮度3.TrackBar 进度条操作3.1使用TrackBar 调整图像的亮度3.2使用TrackBar 调整图…

Windows波形音频MMEAPI简介

Windows波形音频MMEAPI简介 使用MMEAPI时需要导入头文件&#xff1a;#include<mmeapi.h> mmeapi.h文件的主要内容 mmeapi.h 文件是 Windows 多媒体 API 的一部分&#xff0c;主要用于处理波形音频&#xff08;Waveform Audio&#xff09;的输入和输出。以下是该文件的…

GNU/Linux - Bazaar版本管理工具

GNU Bazaar&#xff08;以前称为Bazaar-NG&#xff0c;命令行中称为bzr&#xff09;是由Canonical赞助开发的分布式和主从式版本控制系统。并用来进行Ubuntu项目的版本控制。 Bazaar 可以由一个开发本地内容的多个分支的开发人员使用&#xff0c;也可以由跨网络协作的团队使用。…

学术研讨 | 区块链网络体系结构研讨会顺利召开

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 近日&#xff0c;国家区块链技术创新中心组织了“区块链网络体系结构研讨会”&#xff0c;会议面向跨域交互多、计算规模大、数据管理复杂、性能与扩展性要求高等特征的区块链网络的体系结构展开交流研讨&…

docker相关内容学习

一、docker的四部分 二、镜像相关命令 三、容器相关命令

视频生成【文章汇总】SVD, Sora, Latte, VideoCrafter12, DiT...

视频生成【文章汇总】SVD, Sora, Latte, VideoCrafter12, DiT... 数据集指标 【arXiv 2024】MiraData: A Large-Scale Video Dataset with Long Durations and Structured Captions【CVPR 2024】VBench : Comprehensive Benchmark Suite for Video Generative Models【arxiv 20…

学习记录——day15 数据结构 链表

链表的引入 顺序表的优缺点 1、优点:能够直接通过下标进行定位元素&#xff0c;访问效率高&#xff0c;对元素进行查找和修改比较快 2、不足:插入和删除元素需要移动大量的元素&#xff0c;效率较低 3、缺点:存储数据元素有上限&#xff0c;当达到MAX后&#xff0c;就不能再…

[python]数字与字符串

目录 Python 数字类型转换 Python 数字运算 Python字符串操作 修改 查询 Python 数字数据类型用于存储数值。 数据类型是不允许改变的&#xff0c;这就意味着如果改变数字数据类型的值&#xff0c;将重新分配内存空间。 Python 支持三种不同的数值类型&#xff1a; 整型…

javafx的ListView代入项目的使用

目录 1. 创建一个可观察的列表&#xff0c;用于存储ListView中的数据,这里的User是包装了用户的相关信息。 2.通过本人id获取friendid&#xff0c;及好友的id&#xff0c;然后用集合接送&#xff0c;更方便直观一点。 3.用for遍历集合&#xff0c;逐个添加。 4.渲染器&…

Vue.js中自定义Markdown插件实现References解析

在现代Web应用程序中&#xff0c;Markdown已经成为一种流行的轻量级标记语言&#xff0c;它允许开发者以简单的文本格式编写文档&#xff0c;然后转换成HTML。Vue.js应用程序中经常需要将Markdown内容渲染到页面上。 为了实现这一点&#xff0c;我们可以使用Markdown解析器&am…

文件包涵条件竞争(ctfshow82)

Web82 利用 session.upload_progress 包含文件漏洞 <!DOCTYPE html> <html> <body> <form action"https://09558c1b-9569-4abd-bf78-86c4a6cb6608.challenge.ctf.show//" method"POST" enctype"multipart/form-data"> …

记录转换接口返回的JSON树形结构

一、前言 调用第三方接口返回JSON树形结构 String json "{\n" " \"code\": \"1\",\n" " \"msg\": \"成功\",\n" " \"sub_code\": \"\",\n" " \&quo…

grafana对接zabbix数据展示

目录 1、初始化、安装grafana 2、浏览器访问 3、安装zabbix 4、zabbix数据对接grafana 5、如何导入模板&#xff1f; ① 设置键值 ② 在zabbix web端完成自定义监控项 ③ garafana里添加nginx上面的的三个监控项 6、如何自定义监控项&#xff1f; 以下实验沿用上一篇z…

【React学习打卡第三天】

Redux快速上手、三个核心概念、React组件使用、修改store的数据、提交action传参、异步操作、Redux调试 一、Redux快速上手1.概念2.快速体验(纯redux计数案例&#xff09; 3.三个核心概念 二、Redux与React-环境准备1.配套工具2.配置基础环境3.store目录结构设计![在这里插入图…

SpringMvc有几个上下文

你好&#xff0c;我是柳岸花明。 SpringMVC作为Spring框架的重要组成部分&#xff0c;其启动流程和父子容器机制是理解整个框架运行机制的关键。本文将通过一系列详细的流程图&#xff0c;深入剖析SpringMVC的启动原理与父子容器的源码结构。 SpringMVC 父子容器 父容器的创建 …

Leetcode700.二叉搜索树中搜索具体值

二叉搜索树的定义&#xff1a; 一颗空树或者具有以下性质的二叉树&#xff1a; 若任意节点的左子树不空&#xff0c;则左子树上所有节点的值均小于它的根节点的值&#xff1b;若任意节点的右子树不空&#xff0c;则右子树上所有节点的值均大于它的根节点的值&#xff1b;任意节…

Perl文件系统过滤:数据筛选的艺术

Perl文件系统过滤&#xff1a;数据筛选的艺术 在Perl编程中&#xff0c;文件系统过滤是一种强大的技术&#xff0c;它允许开发者根据特定的规则对文件和目录进行筛选。通过文件系统过滤&#xff0c;可以轻松实现文件搜索、数据提取和自动化任务。本文将详细介绍Perl中的文件系…

数据结构初阶(c语言)-双向链表

这里首先纠正上篇文章一个错误&#xff0c;链表的一个有效数据点应该称为结点而不是节点。 一&#xff0c;双向链表的概念与结构 1.1概念与结构示意图 我们所说的双向链表全称为带头双向循环链表&#xff0c;也就是说此链表带有哨兵位结点(不存放任何数据的结点&#xff0c;且…

c++ 学习笔记之多线程:线程锁,条件变量,唤醒指定线程

基于CAS线程加锁方式 CAS&#xff08;Compare-And-Swap&#xff09;和 mutex 都是用于实现线程安全的技术&#xff0c;但它们适用于不同的场景&#xff0c;具有不同的性能和复杂性。下面是对两者的区别和使用场景的详细解释&#xff1a; CAS&#xff08;Compare-And-Swap&…

【Git多人协作开发】知识点总结

目录 知识点总结 1.创建dev分支开发 1.1在本地创建 1.1在远程创建&#xff08;推荐&#xff09; 2.远程分支和本地分支建立连接☞pull和push操作 2.1情况1 2.2情况2 2.3情况3 3.本地仓库对远程仓库的拉取pull操作 3.1情况1 3.2情况2 4.将开发分支的内容合并到远程m…