数字图像处理(番外)图像增强
图像增强
图像增强的方法是通过一定手段对原图像附加一些信息或变换数据,有选择地突出图像中感兴趣的特征或者抑制(掩盖)图像中某些不需要的特征,使图像与视觉响应特性相匹配。
图像对比度
图像对比度计算方式如下:
C = ∑ δ δ ( i , j ) P δ ( i , j ) C=\displaystyle\sum_{{\delta}}\delta(i,j)P_\delta(i,j) C=δ∑δ(i,j)Pδ(i,j)
其中, δ ( i , j ) = ∣ i − j ∣ \delta(i,j)=\lvert i-j\rvert δ(i,j)=∣i−j∣,即相邻像素间的灰度差; P δ ( i , j ) P_\delta(i,j) Pδ(i,j)为相邻像素灰度差为 δ \delta δ的像素分布概率。可以是四邻域,也可以是八邻域。具体过程如下:
原始图像为:
L = [ 1 3 5 2 1 3 3 6 0 ] L=\begin{bmatrix} 1 & 3 &5\\ 2 & 1 &3 \\ 3 & 6&0 \end{bmatrix} L= 123316530
按照四邻域进行计算,对比度 C L = [ ( 1 2 + 2 2 ) + ( 2 2 + 2 2 + 2 2 ) + ( 1 2 + 1 2 + 1 2 ) + ( 2 2 + 2 2 + 1 2 + 5 2 ) + ( 2 2 + 2 2 + 3 2 ) + ( 1 2 + 3 2 ) + ( 5 2 + 3 2 + 6 2 ) + ( 3 2 + 6 2 ) / 22 C_L=\lbrack(1^2+2^2)+(2^2+2^2+2^2)+(1^2+1^2+1^2)+(2^2+2^2+1^2+5^2)+(2^2+2^2+3^2)+(1^2+3^2)+(5^2+3^2+6^2)+(3^2+6^2)/22 CL=[(12+22)+(22+22+22)+(12+12+12)+(22+22+12+52)+(22+22+32)+(12+32)+(52+32+62)+(32+62)/22。22就是平方的个数。
1.对比度展宽
对比度展宽的目的是通过增强图像的亮暗对比程度而改善画质,使图像的显示效果更加清晰。
线性对比度展宽
通过抑制非重要信息的对比度来腾出空间给重要信息进行对比度的展宽。

原图的灰度为 f ( i , j ) f(i,j) f(i,j),处理后的图像灰度为 g ( i , j ) g(i,j) g(i,j)。原图中的重要景物的灰度分布假设分布在 [ f a , f b ] \lbrack f_a,f_b\rbrack [fa,fb]的范围内,则对比度线性展宽的目的是使处理后图像的重要景物的灰度分布在 [ g a , g b ] \lbrack g_a,g_b\rbrack [ga,gb]的范围内,当 Δ f = ( f b − f a ) < Δ g = ( g b − g a ) \varDelta f=(f_b-f_a)<\varDelta g=(g_b-g_a) Δf=(fb−fa)<Δg=(gb−ga),则可达到对比度展宽的目的。
计算方式如下:
g ( i , j ) = { α f ( i , j ) 0 ≤ f ( i , j ) < a β ( f ( i , j ) − a ) + g a a ≤ f ( i , j ) < b γ ( f ( i , j ) − b ) + g b b ≤ f ( i , j ) < 255 g(i,j)= \begin{cases} \alpha f(i,j) &\text{ } 0\le f(i,j)<a \\ \beta (f(i,j)-a)+g_a &\text{ } a\le f(i,j)<b \\ \gamma (f(i,j)-b)+g_b &b\le f(i,j)<255 \end{cases} g(i,j)=⎩ ⎨ ⎧αf(i,j)β(f(i,j)−a)+gaγ(f(i,j)−b)+gb 0≤f(i,j)<a a≤f(i,j)<bb≤f(i,j)<255
其中, α = g a f a , β = g b − g a f b − f a , γ = 255 − g b 255 − f b \alpha =\frac{g_a}{f_a},\beta =\frac{g_b-g_a}{f_b-f_a},\gamma =\frac{255-g_b}{255-f_b} α=faga,β=fb−fagb−ga,γ=255−fb255−gb。
C++代码如下:
cv::Mat image = cv::imread("Lena.bmp");cv::Mat grayImage(image.size(), CV_8UC1);cv::Mat dstImage(grayImage.size(), CV_8UC1);cv::cvtColor(image, grayImage, CV_BGR2GRAY);int fa = 50, fb = 100;float ga = 30, gb = 120;for (int row = 0; row < grayImage.rows; row++){uchar *currentData = grayImage.ptr<uchar>(row);for (int col = 0; col < grayImage.cols; col++){if (*(currentData + col) >= 0 && *(currentData + col) < fa){dstImage.at<uchar>(row, col) = uchar(ga / fa * (*(currentData + col)));}if (*(currentData + col) >= fa && *(currentData + col) < fb){dstImage.at<uchar>(row, col) = uchar((gb-ga) / (fb-fa) * (*(currentData + col)-fa)+ga);}if (*(currentData + col) >= fb && *(currentData + col) < 255){dstImage.at<uchar>(row, col) = uchar((255-gb) / (255-fb) * (*(currentData + col)-fb)+gb);}}//currentData++;}
结果如下:

非线性对比度展宽
通过一个光滑的映射曲线,使得处理后图像的灰度变化比较光滑。计算公式如下:
g ( i , j ) = c ⋅ l g ( 1 + f ( i , j ) ) g(i,j)=c\cdot lg(1+f(i,j)) g(i,j)=c⋅lg(1+f(i,j))
实际上完成的作用是,抑制高亮度区域,扩展低亮度区域。
2.直方图均衡化
在信息论中有这样一个结论:当数据的分布接近均匀分布的时候,数据所承载的信息量(熵)为最大。
灰度直方图的基本原理是:对在图像中像素个数多的灰度级(即对画面起主要作用的灰度值)进行展宽,而对像素个数少的灰度值(即对画面不起主要作用的灰度值)进行归并。
直方图均衡化方法的具体步骤如下:
- 求出原图 f ( i , j ) M × N f(i,j)_{M\times N} f(i,j)M×N的灰度直方图,设用256维的向量 h f h_f hf表示;
- 有 h f h_f hf求原图的灰度分布概率,记作 p f p_f pf,则有 p f ( i ) = 1 N f ⋅ h f ( i ) , i = 0 , 1 , … , 255 p_f(i)=\frac{1}{N_f}\cdot h_f(i),i=0,1,\dots ,255 pf(i)=Nf1⋅hf(i),i=0,1,…,255
其中, N f = M × N N_f=M\times N Nf=M×N( M , N M,N M,N分别为图像的长和宽)为图像的总像素个数; - 计算图像各个灰度值的累计分布概率,记作 p a p_a pa,则有 p a ( i ) = ∑ k = 0 i p f ( k ) , i = 1 , 2 , … , 255 p_a(i)=\displaystyle\sum_{k=0}^ip_f(k),i=1,2,\dots ,255 pa(i)=k=0∑ipf(k),i=1,2,…,255
其中,令 p a ( 0 ) = 0 p_a(0)=0 pa(0)=0。 - 进行直方图均衡化计算,得到处理后图像的像素值 g ( i , j ) g(i,j) g(i,j)为: g ( i , j ) = 255 ⋅ p a ( k ) g(i,j)=255\cdot p_a(k) g(i,j)=255⋅pa(k)
C++代码如下所示:
cv::Mat image = cv::imread("Lena.bmp");cv::Mat src(image.size(), CV_8UC1);//转为灰度图像cv::cvtColor(image, src, CV_BGR2GRAY);cv::Mat dst(image.size(), CV_8UC1);float hf[256] = { 0 };for (int row = 0; row < src.rows; row++){uchar *currentData = src.ptr<uchar>(row);for (int col = 0; col < src.cols; col++){hf[*(currentData + col)] += 1;}}float pf[256] = { 0 };for (int i = 0; i < 256; i++){pf[i] = hf[i] / (src.rows*src.cols);}float pa[256] = { 0 };for (int i = 1; i < 256; i++){float sumNumber = 0;for (int j = 0; j < i+1; j++){sumNumber += pf[j];}pa[i] = sumNumber;}for (int row = 0; row < dst.rows; row++){uchar * currentData = dst.ptr<uchar>(row);for (int col = 0; col < dst.cols; col++){*(currentData + col) = uchar(255 * pa[src.at<uchar>(row, col)]);}}
结果展示:

相关文章:
数字图像处理(番外)图像增强
图像增强 图像增强的方法是通过一定手段对原图像附加一些信息或变换数据,有选择地突出图像中感兴趣的特征或者抑制(掩盖)图像中某些不需要的特征,使图像与视觉响应特性相匹配。 图像对比度 图像对比度计算方式如下: C ∑ δ δ ( i , j …...
flutter:轮播
前言 介绍几个比较有不错的轮播库 swipe_deck 与轮播沾边,但是更多的是一种卡片式的交互式界面设计。它的主要概念是用户可以通过左右滑动手势浏览不同的卡片,每张卡片上都有不同的信息或功能。 Swipe deck通常用于展示图片、产品信息、新闻文章、社…...
高忆管理:股票投资策略是什么?有哪些?
在进行股票买卖过程中,出资者需求有自己的方案和出资战略,并且主张严格遵从出资战略买卖,不要跟风操作。那么股票出资战略是什么?有哪些?下面就由高忆管理为我们剖析: 股票出资战略简略来说便是能够协助出资…...
为公网SSH远程Ubuntu配置固定的公网TCP端口地址主图
文章目录 为公网SSH远程Ubuntu配置固定的公网TCP端口地址 为公网SSH远程Ubuntu配置固定的公网TCP端口地址 在上篇文章中,我们通过cpolar建立的临时TCP数据隧道,成功连接了位于其他局域网下的Ubuntu系统,实现了不同操作系统、不同网络下的系统…...
【前端知识】React 基础巩固(四十一)——手动路由跳转、参数传递及路由配置
React 基础巩固(四十一)——手动路由跳转、参数传递及路由配置 一、实现手动跳转路由 利用 useNavigate 封装一个 withRouter(hoc/with_router.js) import { useNavigate } from "react-router-dom"; // 封装一个高阶组件 function withRou…...
Qt几种字符类型的相互转换
Qt几种字符类型的相互转换 将const QString转换为const char*将const char*转换为const QStringQstring转换为string把string转换为QstringQt中弹出一个窗口 将const QString转换为const char* #include <QString> #include <iostream>int main() {const QString …...
软件测试员的非技术必备技能
成为软件测试人员所需的技能 非技术技能 以下技能对于成为优秀的软件测试人员至关重要。 将您的技能组合与以下清单进行比较,以确定软件测试是否适合您 - 分析技能:优秀的软件测试人员应具备敏锐的分析能力。 分析技能将有助于将复杂的软件系统分解为…...
渗透测试:Linux提权精讲(二)之sudo方法第二期
目录 写在开头 sudo expect sudo fail2ban sudo find sudo flock sudo ftp sudo gcc sudo gdb sudo git sudo gzip/gunzip sudo iftop sudo hping3 sudo java 总结与思考 写在开头 本文在上一篇博客的基础上继续讲解渗透测试的sudo提权方法。相关内容的介绍与背…...
ansible安装lnmp(集中式)
文章目录 一、安装nginx二、安装mysql三、安装php测试: 一、安装nginx - name: the nginx playhosts: webserversremote_user: roottasks:- name: stop firewalld #关闭防火墙service: namefirewalld statestopped enabledno- name: selinux stopc…...
Tomcat的基本使用,如何用Maven创建Web项目、开发完成部署的Web项目
Tomcat 一、Tomcat简介二、Tomcat基本使用三、Maven创建Web项目3.1 Web项目结构3.2开发完成部署的Web项目3.3创建Maven Web项目3.3.1方式一3.3.2方式二(个人推荐) 总结 一、Tomcat简介 Web服务器: Web服务器是一个应用程序(软件&…...
微信小程序测试要点
一、什么是小程序? 可以将小程序理解为轻便的APP,不用安装就可以使用的应用。用户通过扫一扫或者搜索的方式,就可以打开应用。 小程序最主要的特点是内嵌于微信之中,而使用小程序的目的是为了能够方便用户不在受下载多个APP的烦…...
TCP网络通信编程之netstat
【netstat指令】 【说明】 (1)Listening 表示某个端口在监听 (2)如果有一个外部程序(客户端)连接到该端口,就会显示一条连接信息 (3)指令netstat -anb 可以参看是那个…...
Stable Diffusion:网页版 体验 / AI 绘图
一、官网地址 Stable Diffusion Online 二、Stable Diffusion AI 能做什么 Stable Diffusion AI绘图是一种基于Stable Diffusion模型的生成式AI技术,能够生成各种类型的图像,包括数字艺术、照片增强和图像修复等。以下是一些可能的应用: …...
一文了解JavaScript 与 TypeScript的区别
TypeScript 和 JavaScript 是两种互补的技术,共同推动前端和后端开发。在本文中,我们将带您快速了解JavaScript 与 TypeScript的区别。 一、TypeScript 和 JavaScript 之间的区别 JavaScript 和 TypeScript 看起来非常相似,但有一个重要的区…...
从更广阔的角度看待产业互联网,它展现的是一次重构的过程
如果产业互联网仅仅只是在传统的供求关系之下,如果产业互联网仅仅只是在传统的平衡之下,缺少了一次对于供求关系的重新建构,那么,所谓的产业互联网,依然是无法跳出以往的发展困境,依然是无法摆脱以往的发展…...
【PHP】简记问题:使用strtotime(‘-1 month‘, time)获取上个月第一天时间戳出错
发生场景 在7月31号是查看统计上个月订单购买总金额,查询结果为0 $preMonthStart strtotime(date(Ym01, strtotime("-1 month"))); $curMonthStart strtotime(date(Ym01)); # 统计上月份实际订单金额 $sql "SELECT count(money) FROM orders WH…...
舌体分割的初步展示应用——依托Streamlit搭建demo
1 前言 去年在社区发布了有关中医舌象诊断的博文,其中舌象识别板块受到了极高的关注和关注。😊最近,我接触到了Python的Streamlit库,它可以帮助数据相关从业人员轻松搭建数据看板。本文将介绍如何使用Streamlit构建舌体分割的演示…...
从Vue层面 - 解析发布订阅模式和观察者模式区别
目录 前言一、发布订阅模式什么是发布订阅模式?应用场景 二、观察者模式1)什么是观察者模式?2)应用场景3)vue中的观察者模式观察者(订阅者) - Watcher目标者(发布者) - D…...
面向对象之_多态_1
目录 一. 多态 多态是什么 二. 多态的构成条件 1. 虚函数 2. 虚函数重写(隐藏) 3. 父类型的引用或者指针调用 4. 多态的特殊情况 1) 子类可以不加 virtual 关键字 2) 协变 三. 关键字 1. virtual 2. final 3. override 四. 多态的原理 1. 虚…...
Spring学习笔记之spring概述
文章目录 Spring介绍Spring8大模块Spring特点 Spring介绍 Spring是一个轻量级的控制反转和面向切面的容器框架 Spring最初的出现是为了解决EJB臃肿的设计,以及难以测试等问题。 Spring为了简化开发而生,让程序员只需关注核心业务的实现,尽…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
