使用VC++实现分段线性变换,直方图均衡化、锐化处理(使用拉普拉斯算子)
图像锐化1
实验要求
5.1实验目的、要求
实验目的:
(1)掌握图像增强的原理与相关方法。
(2)能使用VC++实现图像增强的一些相关功能。
实验要求:
A部分:
(1)对一幅256级灰度图像,使用VC++实现分段线性变换,直方图均衡化。
(2)对一幅256级灰度图像,使用VC++实现锐化处理(使用拉普拉斯算子)。
一、 分段线性变换
1. 分段线性变换的原理
灰度图像分段线性变换是一种调整图像灰度级别的方法,它通过将灰度范围划分为多个分段,然后对每个分段应用线性变换来调整图像的对比度和亮度。这种方法的主要目的是增强或减弱图像中特定灰度范围的细节,以改善图像的视觉效果。
下面是该方法的基本原理:
-
分段划分: 将整个灰度范围划分为多个不重叠的分段。每个分段代表图像中的一个灰度范围。这些分段由一个或多个分界点定义,这些分界点将整个灰度范围划分成不同的区域。
-
线性变换: 对每个分段应用线性变换。线性变换由斜率和截距两个参数定义。斜率决定了线的倾斜程度,而截距则控制了线的位置。通过调整这两个参数,可以实现对分段内灰度级别的调整。
-
像素更新: 对图像的每个像素应用上述的分段线性变换。首先,确定像素所属的分段,然后使用该分段对应的线性变换来更新像素的灰度值。这样,每个像素都会根据其原始灰度值和所属分段的线性变换进行调整。
通过灰度图像分段线性变换,可以实现对图像不同灰度范围的灰度级别进行差异化的调整。例如,可以增强图像中的低对比度区域或减弱过曝区域,从而更好地展现图像细节。这种方法在图像增强和调整方面具有一定的灵活性,但需要根据具体的应用场景和图像特性来选择适当的分段和线性变换参数。
2. 分段线性变换的实验代码
3. 分段线性变换的实验现象

左:原灰度图
右:灰度图像分段线性变换后

二、直方图均衡化
1. 直方图均衡化的原理
直方图均衡化是一种用于增强图像对比度的图像处理技术。其基本原理是将图像的灰度直方图变换成一个均匀分布的直方图,从而拉伸图像的灰度范围,使得亮度水平更加均匀,细节更为突出。
具体的步骤如下:
-
计算直方图: 统计图像中每个灰度级别的像素数量,形成直方图。
-
计算累积分布函数(CDF): 将直方图进行归一化,得到每个灰度级别对应的累积概率。
C D F ( i ) = ∑ j = 0 i P ( j ) CDF(i) = \sum_{j=0}^{i} P(j) CDF(i)=j=0∑iP(j)
其中, P ( j ) P(j) P(j) 是灰度级别 j j j 的概率。
-
直方图均衡化变换函数: 将CDF的值映射到新的灰度级别范围。
H ( i ) = round ( C D F ( i ) × ( L − 1 ) N ) H(i) = \text{round}\left(\frac{CDF(i) \times (L-1)}{N}\right) H(i)=round(NCDF(i)×(L−1))
其中, H ( i ) H(i) H(i) 是新的灰度级别, L L L 是灰度级别的最大值, N N N 是图像的总像素数量。 r o u n d ( ) round() round() 是一个数学函数,通常用于将一个浮点数四舍五入为最接近的整数
-
应用变换: 将变换函数应用于图像的每个像素,更新图像的灰度级别。
通过直方图均衡化,原始图像中灰度分布不均匀的区域会被映射到更广泛的灰度范围,从而提高了图像的对比度,使细节更加清晰。
2. 直方图均衡化的实验代码
BOOL HistogramEqualize(CDib* pDib){// 指向源图像的指针unsigned char* lpSrc;// 临时变量int nTemp;// 循环变量int i,j;// 累积直方图,即灰度映射表BYTE byMap[256];// 直方图int nCount[256];// 图象的高度和宽度CSize sizeImage;sizeImage = pDib->GetDimensions();// 获得图象数据存储的高度和宽度CSize SizeSaveImage;SizeSaveImage = pDib->GetDibSaveDim();// 重置计数为0for (i = 0; i < 256; i ++){// 清零nCount[i] = 0;}// 计算各个灰度值的计数,即得到直方图for (i = 0; i < sizeImage.cy; i ++){for (j = 0; j < sizeImage.cx; j ++){lpSrc = (unsigned char *)pDib->m_lpImage + SizeSaveImage.cx * i + j;//表示从图像数据的起始位置开始,跳过 i 行,再移动 j 列,最终指向了图像中第 i 行、第 j 列的像素的位置,获取图像中第 i 行、第 j 列的像素的灰度值// 计数加1nCount[*(lpSrc)]++;//以灰度值的大小为下坐标,进行计数}}// 计算累积直方图for (i = 0; i < 256; i++){// 初始为0nTemp = 0;for (j = 0; j <= i ; j++){nTemp += nCount[j];}// 计算对应的新灰度值---公式byMap[i] = (BYTE) (nTemp * 255 / sizeImage.cy / sizeImage.cx);}// 每行for(i = 0; i < sizeImage.cy; i++){// 每列for(j = 0; j < sizeImage.cx; j++){// 指向DIB第i行,第j个象素的指针lpSrc = (unsigned char*)pDib->m_lpImage + pDib->GetPixelOffset(i,j);// 计算新的灰度值x*lpSrc = byMap[*lpSrc];//找到当前像素的原始灰度值,并将其映射为新的灰度值。}}// 返回return TRUE;}
3. 直方图均衡化的实验现象
左:原图
右:直方图均衡化增强后

三、 拉普拉斯算子实现锐化
拉普拉斯算子的原理
拉普拉斯算子(Laplacian operator)是一种用于图像处理的滤波器,主要用于检测图像中的边缘和细节。它通过计算图像中每个像素点的二阶导数来实现。
拉普拉斯算子的一维形式为:
L ( x ) = d 2 d x 2 L(x) = \frac{d^2}{dx^2} L(x)=dx2d2
而在二维图像上的应用是通过以下离散形式的卷积核:
[ 0 1 0 1 − 4 1 0 1 0 ] \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \\ \end{bmatrix} 0101−41010
应用拉普拉斯算子的过程是将这个卷积核与图像进行卷积运算。具体而言,对于图像中的每个像素,将其与卷积核中的对应元素相乘,然后将所有相乘的结果相加。这个过程可以用以下的数学表达式表示:
L ( x , y ) = ∑ i = − 1 1 ∑ j = − 1 1 kernel ( i , j ) × image ( x + i , y + j ) L(x, y) = \sum_{i=-1}^{1} \sum_{j=-1}^{1} \text{kernel}(i, j) \times \text{image}(x + i, y + j) L(x,y)=i=−1∑1j=−1∑1kernel(i,j)×image(x+i,y+j)
其中, kernel ( i , j ) \text{kernel}(i, j) kernel(i,j) 是卷积核中的元素, image ( x + i , y + j ) \text{image}(x + i, y + j) image(x+i,y+j) 是图像中对应位置的像素值。
拉普拉斯算子对图像进行了高通滤波,强调了图像中的高频细节和边缘。应用拉普拉斯算子后,边缘部分的像素值将发生变化,使得图像中的边缘更加明显。然而,拉普拉斯算子也会增加图像中的噪声。因此,在实际应用中,通常会结合其他技术,如平滑(低通滤波)来减少噪声的影响。
拉普拉斯算子的实验代码
/*************************************************************************** \函数名称:* LinearSharpen()** \输入参数:* LPBYTE lpImage - 指向图象数据得指针* int nWidth - 图象数据宽度* int nHeight - 图象数据高度** \返回值:* 无** \说明:* 线性锐化图象增强* 本函数采用拉普拉斯算子对图象进行线性锐化* 在原来图象上加上拉普拉斯算子锐化的信息***************************************************************************/
void LinearSharpen (LPBYTE lpImage, int nWidth, int nHeight)
{// 遍历图象的纵坐标int y;// 遍历图象的横坐标int x;double * pdGrad ;pdGrad = new double[nWidth*nHeight];//用于存储图像的梯度信息。// 初始化为0memset(pdGrad, 0, nWidth*nHeight*sizeof(double)) ;// 设置模板系数--设置拉普拉斯算子的卷积核,这是一个 3x3 的矩阵,用于计算图像中每个像素点的梯度。static int nWeight[3][3] ;nWeight[0][0] = -1 ; nWeight[0][1] = -1 ; nWeight[0][2] = -1 ; nWeight[1][0] = -1 ; nWeight[1][1] = 8 ; nWeight[1][2] = -1 ; nWeight[2][0] = -1 ; nWeight[2][1] = -1 ; nWeight[2][2] = -1 ; //这个变量用来表示Laplacian算子象素值int nTmp[3][3];// 临时变量double dGrad;// 模板循环控制变量int yy ;int xx ;for(y=1; y<nHeight-1 ; y++ )for(x=1 ; x<nWidth-1 ; x++ ){dGrad = 0 ; // Laplacian算子需要的各点象素值// 模板第一行nTmp[0][0] = lpImage[(y-1)*nWidth + x - 1 ] ; nTmp[0][1] = lpImage[(y-1)*nWidth + x ] ; nTmp[0][2] = lpImage[(y-1)*nWidth + x + 1 ] ; // 模板第二行nTmp[1][0] = lpImage[y*nWidth + x - 1 ] ; nTmp[1][1] = lpImage[y*nWidth + x ] ; nTmp[1][2] = lpImage[y*nWidth + x + 1 ] ; // 模板第三行nTmp[2][0] = lpImage[(y+1)*nWidth + x - 1 ] ; nTmp[2][1] = lpImage[(y+1)*nWidth + x ] ; nTmp[2][2] = lpImage[(y+1)*nWidth + x + 1 ] ; // 计算梯度for(yy=0; yy<3; yy++)for(xx=0; xx<3; xx++){dGrad += nTmp[yy][xx] * nWeight[yy][xx] ;}// 梯度值写入内存*(pdGrad+y*nWidth+x)=dGrad;}//将计算得到的梯度值加到原始图像上,实现锐化效果。for(y=0; y<nHeight ; y++ ){for(x=0 ; x<nWidth ; x++ ){lpImage[y*nWidth+x] = (unsigned char)max(0,min(255,(lpImage[y*nWidth+x] + (int)pdGrad[y*nWidth+x]) ));}}//释放申请的内存delete []pdGrad ;pdGrad = NULL ;
}
拉普拉斯算子的实验现象
左:原图
右:经过拉普拉斯锐化

相关文章:
使用VC++实现分段线性变换,直方图均衡化、锐化处理(使用拉普拉斯算子)
图像锐化1 实验要求 5.1实验目的、要求 实验目的: (1)掌握图像增强的原理与相关方法。 (2)能使用VC实现图像增强的一些相关功能。 实验要求: A部分: (1)对一幅256级灰度…...
react class改hooks写法
类头修改 export default class EditUseTable extends Component 改为 export default function EditUseTable({})参数修改 constructor(props) {super(props)const {dbRecord, type, currentRecord, readOnly, updateTaxAmount} this.props改为(主函数的参数&a…...
桂院校园导航 | 云上高校导航 云开发项目 二次开发教程 1.3
Gitee代码仓库:桂院校园导航小程序 GitHub代码仓库:GLU-Campus-Guide 演示视频 中国大学生计算机设计大赛-移动应用与开发-云上高校导航 升级日志 1.3 优化了小程序的数据存储方式,对部分页面进行了调整,调整了功能和代码。 引…...
sscanf提取相应字符到数组
代码如下 #include<stdio.h> #include<string.h>int main(int argc, char const *argv[]) {char buf[128] {0};int m1 0, m2 0;int s1 0, s2 0;char lrc[128] "";sscanf("[02:16.33][04:11.44]我想大声宣布对你恋恋不舍","[%*1d%d…...
本地开发环境和服务器传输数据的几种方法
❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...
LeetCode之二叉树
发现更多计算机知识,欢迎访问Cr不是铬的个人网站 最近数据结构学到二叉树,就刷了刷力扣,写这篇文章也是辅助记忆。 103二叉树锯齿形遍历 要解出本道题,首先要会层次遍历。层次遍历我们都知道用一个队列去实现就行。但是力扣这里…...
论文学习——THE USTC SYSTEM FOR ADRESS-M CHALLENGE
文章目录 引言正文Abstract模型基本结构模型效果汇总 Introduction介绍跨语言任务的独特性思路启发和变化如何使用预定义好的音频特征如何使用预定义好的语言模型——语言模型中获取韵律信息结果说明 Dataset数据集Mthods方法使用设计好的特征进行AD检测使用的特征分类和训练方…...
第一百七十五回 如何创建放射形状渐变背景
文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在 上一章回中介绍了"如何创建扇形渐变背景"相关的内容,本章回中将介绍" 如何创建放射形状渐变背景"。闲话休提,让我们一起Talk Flutter吧…...
vue实现调用手机拍照、录像功能
目录 前言 准备工作 在这个示例中,我们将使用Vue.js框架来实现我们的目标。如果你还不熟悉Vue.js,推荐先学习一下Vue.js的基础知识。 接下来,我们需要创建一个基于Vue.js的项目。你可以使用Vue CLI来创建一个全新的Vue项目:# 安…...
WPF播放视频
在WPF中,你可以使用MediaElement来播放本地视频。下面是一个简单的例子: <Window x:Class"WPFVideoPlayer.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsof…...
交换机如何配置BGP协议
环境: 华为交换机 华三交换机 问题描述: 交换机如何配置BGP协议 解决方案: 华三交换机上配置案例 1.配置BGP协议,可以按照以下步骤进行: 登录交换机:使用SSH、Telnet或控制台等方式登录到华三交换…...
精通Nginx(14)-配置HTTPS
HTTPS是在 HTTP 协议的基础上使用 TLS/SSL 加密,其主要目标是提高数据传输的安全性。从HTTP2.0开始,HTTPS已经是网站的标准协议,很多开放平台非HTTPS不能访问。Nginx为HTTPS提供了强大的支持,且对应用服务器是完全透明的。 目录 SSL/TLS基础 发展历史 TLS握手过程 加密…...
封装一个简单的table组件
子组件 <template> <el-table :data"tableData" :headers"tableHeaders" style"width: 100%"> <el-table-column v-for"header in tableHeaders" :key"header.prop" :label"header.label" :pro…...
Avalonia UI框架介绍
Avalonia UI是一个跨平台的UI框架,它允许开发者使用XAML和C#语言创建可在多个平台上运行的应用程序,包括Windows、Linux、macOS等。Avalonia UI与WPF非常相似,但是它是开源的,并且更加灵活。 下面是一个简单的Avalonia UI应用程序…...
【入门篇】1.3 redis客户端之 jedis 高级使用示例
文章目录 0.前言1. 发布和订阅消息2. 事务操作3. 管道操作4. jedis 支持哨兵模式5. jedis 支持集群模式5. 参考链接 0.前言 Jedis是Redis的Java客户端,它支持所有的Redis原生命令,使用方便,且可以与Java项目无缝集成。 该库的最新版本支持Re…...
使用CXF调用WSDL(二)
简介 本篇文章主要解决了上篇文章中遗留的对象嵌套问题,要想全面解析无限极的对象嵌套需要使用递归去解决 上文链接: 使用CXF调用WSDL(一) 上文回顾 上文使用了单方法“ call() ”解决了List和基本类型(含String&…...
list.toArray
直接去看原文 原文链接:List的toArray()方法_list.toarray-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- toArray()介绍 toArray()方法是List接口中提供的方法ÿ…...
2013年11月10日 Go生态洞察:Go语言四周年回顾
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
Ubuntu上使用SSH连接到CentOS系统
确保CentOS系统上的SSH服务器已安装并正在运行: 在CentOS上,默认情况下,SSH服务器(sshd)应该已安装并正在运行。如果不确定,可以通过以下方式检查: sudo systemctl status sshd如果未安装&…...
【知识增强】A Survey of Knowledge-Enhanced Pre-trained LM 论文笔记
A Survey of Knowledge-Enhanced Pre-trained Language Models Linmei Hu, Zeyi Liu, Ziwang Zhao, Lei Hou, Liqiang Nie, Senior Member, IEEE and Juanzi Li 2023年8月的一篇关于知识增强预训练模型的文献综述 论文思维导图 思维导图网页上看不清的话,可以存…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...
