visual Studio MFC 平台实现拉普拉斯和拉普拉斯与直方图均衡化与中值滤波相结合实现比较

拉普拉斯变换的原理与应用

本文使用visual Studio MFC 平台实现图像增强中的拉普拉斯变换,同时拉普拉斯一般不会单独使用,与其他平滑操作相结合,本文使用了拉普拉斯与直方图均衡化以及与中值滤波相结合,也对三种方式进行了对比

关于基础工程的创建可以参考
01-Visual Studio 使用MFC 单文档工程绘制单一颜色直线和绘制渐变颜色的直线

02-visual Studio MFC 绘制单一颜色三角形、渐变颜色边框三角形、渐变填充三角形、边框渐变的正方形与填充渐变的正方形实例
03-visual Studio MFC 平台实现图像增强中的线性变换(负变换)和非线性变换(对数与幂律)
04-MFC实现图像增强–分段式变换(灰度级切片,对比度拉伸,Bit-plane slicing)
05-visual Studio MFC 平台实现对灰度图添加椒盐噪声,并进行均值滤波与中值滤波

文章目录

  • 拉普拉斯变换的原理与应用
    • 一、 拉普拉斯变换的原理
    • 二、 拉普拉斯实现
      • 2.1单独拉普拉斯实现代码
      • 单独拉普拉斯实现效果
      • 2.2 拉普拉斯与直方图均衡化相结合实现代码
      • 拉普拉斯与直方图均衡化相结合实现效果
      • 2.3 拉普拉斯与中值滤波相结合实现
      • 中值滤波与拉普拉斯相结合实现效果

一、 拉普拉斯变换的原理

拉普拉斯变换的原理如下:

拉普拉斯变换是图像处理中一种用于增强图像边缘的技术。它可以通过高通滤波来突出图像中的边缘特征。拉普拉斯变换的离散形式通常通过卷积运算实现。

  1. 离散拉普拉斯运算符: 在离散图像中,拉普拉斯运算符可以表示为:

∇ 2 f ( x , y ) = f ( x + 1 , y ) + f ( x − 1 , y ) + f ( x , y + 1 ) + f ( x , y − 1 ) − 4 f ( x , y ) \nabla^2 f(x, y) = f(x+1, y) + f(x-1, y) + f(x, y+1) + f(x, y-1) - 4f(x, y) 2f(x,y)=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)4f(x,y)

其中, f ( x , y ) f(x, y) f(x,y) 是图像在位置 ( x , y ) (x, y) (x,y)处的灰度值。

对于离散图像,拉普拉斯变换可以使用以下的卷积核来实现:

  0  -1   0-1   4  -10  -1   0

这个卷积核对图像进行卷积运算,计算每个像素与其周围像素的差异,从而强调了图像中的边缘。在卷积运算中,将卷积核与图像的每个像素进行乘法,然后将结果相加。这个过程在整个图像上进行,产生一个新的图像,其中强调了边缘。
2. 连续拉普拉斯运算符: 在连续图像中,拉普拉斯运算符可以表示为:

∇ 2 f ( x , y ) = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 \nabla^2 f(x, y) = \frac{\partial^2 f}{\partial x^2} + \frac{\partial^2 f}{\partial y^2} 2f(x,y)=x22f+y22f

它表示图像中各个点的强度与其周围点的强度之差的二阶导数。

  1. 应用: 对图像应用拉普拉斯变换将突出显示图像中的边缘和细节,因为这些区域通常具有灰度变化。拉普拉斯变换后的图像可以通过以下公式得到:

LaplacianImage = OriginalImage − SmoothedImage \text{LaplacianImage} = \text{OriginalImage} - \text{SmoothedImage} LaplacianImage=OriginalImageSmoothedImage

这里, SmoothedImage \text{SmoothedImage} SmoothedImage 是原始图像经过平滑处理(如高斯模糊)后的图像。
在实际应用中,拉普拉斯变换通常用于边缘检测或图像锐化。然而,由于它对噪声敏感,常常需要与其他技术一起使用,例如高斯滤波,以减小噪声的影响。

在数字图像处理中,通常使用卷积操作来实现拉普拉斯变换。卷积核的选择影响着变换的效果。拉普拉斯变换对于边缘检测和图像增强等任务非常有用。

二、 拉普拉斯实现

2.1单独拉普拉斯实现代码

 // 定义拉普拉斯核int laplacianKernel[3][3] = {{ -1, -1, -1 },{ -1,  8, -1 },{ -1, -1, -1 }};// 应用卷积运算for (int y = 1; y < bmpHeight - 1; ++y) {for (int x = 1; x < bmpWidth - 1; ++x) {int sum = 0;for (int i = -1; i <= 1; ++i) {for (int j = -1; j <= 1; ++j) {sum += laplacianKernel[i + 1][j + 1] * gray_data[(y + i) * bmpWidth + (x + j)];}}laplacian_data[y * bmpWidth + x] = static_cast<unsigned char>(sum);}}CClientDC dc(this);CDC* pDC = &dc;m_pBmp->drawGrayBmp(pDC, laplacian_data, bmpWidth, bmpHeight, offset_left, offset_top +4 * bmpHeight+30);// 释放临时数组内存delete[] laplacian_data;

单独拉普拉斯实现效果

在这里插入图片描述

2.2 拉普拉斯与直方图均衡化相结合实现代码

// 计算直方图
int histogram[256] = { 0 };
for (int i = 0; i < bmpWidth * bmpHeight; ++i) {histogram[gray_data[i]]++;
}// 计算累积分布函数(CDF)
int cdf[256] = { 0 };
cdf[0] = histogram[0];
for (int i = 1; i < 256; ++i) {cdf[i] = cdf[i - 1] + histogram[i];
}// 映射灰度级别到临时变量
unsigned char* temp_data = new unsigned char[bmpWidth * bmpHeight];
int min_cdf = cdf[0];
for (int i = 0; i < bmpWidth * bmpHeight; ++i) {temp_data[i] = static_cast<unsigned char>(255 * (cdf[gray_data[i]] - min_cdf) / (bmpWidth * bmpHeight - min_cdf));
}// 应用拉普拉斯变换
unsigned char* laplacian_data = new unsigned char[bmpWidth * bmpHeight];
int laplacianKernel[3][3] = {{ -1, -1, -1 },{ -1,  8, -1 },{ -1, -1, -1 }
};
for (int y = 1; y < bmpHeight - 1; ++y) {for (int x = 1; x < bmpWidth - 1; ++x) {int sum = 0;for (int i = -1; i <= 1; ++i) {for (int j = -1; j <= 1; ++j) {sum += laplacianKernel[i + 1][j + 1] * temp_data[(y + i) * bmpWidth + (x + j)];}}laplacian_data[y * bmpWidth + x] = static_cast<unsigned char>(sum);}
}// 绘制均衡化后的图像
//m_pBmp->drawGrayBmp(pDC, temp_data, bmpWidth, bmpHeight, offset_left + 900, offset_top);// 绘制经拉普拉斯变换后的图像
m_pBmp->drawGrayBmp(pDC, laplacian_data, bmpWidth, bmpHeight, offset_left+bmpWidth, offset_top + 4* bmpHeight + 30);

拉普拉斯与直方图均衡化相结合实现效果

在这里插入图片描述

2.3 拉普拉斯与中值滤波相结合实现

// 中值滤波
for (int y = 1; y < bmpHeight - 1; ++y) {for (int x = 1; x < bmpWidth - 1; ++x) {// 获取3x3邻域内的像素值unsigned char neighborhood[9] = {gray_data[(y - 1) * bmpWidth + x - 1], gray_data[(y - 1) * bmpWidth + x], gray_data[(y - 1) * bmpWidth + x + 1],gray_data[y * bmpWidth + x - 1], gray_data[y * bmpWidth + x], gray_data[y * bmpWidth + x + 1],gray_data[(y + 1) * bmpWidth + x - 1], gray_data[(y + 1) * bmpWidth + x], gray_data[(y + 1) * bmpWidth + x + 1]};// 对邻域内像素值进行排序std::sort(neighborhood, neighborhood + 9);// 取中值作为当前像素值temp_data[y * bmpWidth + x] = neighborhood[4];}
}// 拉普拉斯变换
int laplacianKernel[3][3] = {{ -1, -1, -1 },{ -1,  8, -1 },{ -1, -1, -1 }
};// 应用卷积运算
for (int y = 1; y < bmpHeight - 1; ++y) {for (int x = 1; x < bmpWidth - 1; ++x) {int sum = 0;for (int i = -1; i <= 1; ++i) {for (int j = -1; j <= 1; ++j) {sum += laplacianKernel[i + 1][j + 1] * temp_data[(y + i) * bmpWidth + (x + j)];}}median_laplacian_data[y * bmpWidth + x] = static_cast<unsigned char>(sum);}
}CClientDC dc(this);
CDC* pDC = &dc;// 显示结果
//m_pBmp->drawGrayBmp(pDC, temp_data, bmpWidth, bmpHeight, offset_left, offset_top);
m_pBmp->drawGrayBmp(pDC, median_laplacian_data, bmpWidth, bmpHeight, offset_left + 2*bmpWidth, offset_top + 4 * bmpHeight + 30);

中值滤波与拉普拉斯相结合实现效果

在这里插入图片描述

可以观看出在添加一些平滑操作后,与单独进行拉普拉斯变换还是有一些区别的,当然最后实现的效果可以调节拉普拉斯算子进行调节,以达到相应的效果。

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

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

相关文章

如何提高Pycharm的使用体验?

汉化 文件---设置---插件---chinese---安装---重启ide 代码补全 tabnine 文件---设置---插件---tabnine---安装---重启ide 重启ide后生效&#xff0c;补全效果如下 自定义背景 文件---设置---外观---背景图像---选择图片---调整透明度保存即可 设置头部声明 英文版…

基于Java SSM框架实现社区疫情防控管理系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现社区疫情防控管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;社区疫情防控管理信息系统当然也不能排除在外。社区疫情防控管理信息系…

记录 | CUDA编程中使用#ifdef指令控制生成CPU和GPU代码

CUDA编程中使用#ifdef指令控制生成CPU和GPU代码 比如&#xff1a; #include <cstdio> #include <cuda_runtime.h>__host__ __device__ void say_hello(){ #ifdef __CUDA_ARCH__printf("Hello, world from GPU!\n"); #elseprintf("Hello, world fr…

Unity3D对CSV文件操作(创建、读取、写入、修改)

系列文章目录 Unity工具 文章目录 系列文章目录前言一、Csv是什么&#xff1f;二、创建csv文件2-1、构建表数据2-2、创建表方法2-3、完整的脚本&#xff08;第一种方式&#xff09;2-4、运行结果2-5、完整的脚本&#xff08;第二种方式&#xff09;2-6、运行结果2-7、想用哪种…

springboot075电影评论网站系统设计与实现

springboot075电影评论网站系统设计与实现 成品项目已经更新&#xff01;同学们可以打开链接查看&#xff01;需要定做的及时联系我&#xff01;专业团队定做&#xff01;全程包售后&#xff01; 2000套项目视频链接&#xff1a;https://pan.baidu.com/s/1N4L3zMQ9nNm8nvEVf…

ocpm @ ecpm @ ocpc@ ecpc

"o" 采用更准确的点击/转化率预估计值&#xff0c;将广告展示给最容易产生转化的用户。 以目标出价优化 千次展现成本 ocpm 以目标出价优化 单次点击出价 ocpc "e" 预估转化成本 ecpm 预估千次展现成本

flask 异步编程 asyncio

1. Flask 与异步编程 在编写Web应用程序时&#xff0c;有时需要调用可能需要一些时间的外部服务或执行耗时操作的函数。在传统的同步编程中&#xff0c;这将导致整个应用程序阻塞&#xff0c;直到该函数返回结果。为了提高应用程序的性能和响应能力&#xff0c;我们可以使用异…

Java中常用的垃圾回收器

在Java的世界里&#xff0c;"垃圾回收"是一个让许多开发者即侍俯首也感到神秘的术语。垃圾回收&#xff08;Garbage Collection, GC&#xff09;是Java虚拟机&#xff08;JVM&#xff09;的一个重要部分&#xff0c;它帮助开发者管理内存&#xff0c;确保程序能有效并…

面试题:公司规定所有接口都用 post 请求,这是为什么?

文章目录 前言get 与 post 的区别所有接口都用 post 请求&#xff1f;网友程墨 Morgan网友苏莉安网友大宽宽 前言 最近在逛知乎的时候发现一个有趣的问题&#xff1a;公司规定所有接口都用 post 请求&#xff0c;这是为什么&#xff1f; 看到这个问题的时候其实我也挺有感触的…

可编程电子负载的应用前景如何

可编程电子负载是一种模拟真实负载的电子设备&#xff0c;它可以模拟各种不同类型和规格的负载&#xff0c;如电阻、电容、电感等。通过可编程的方式&#xff0c;用户可以根据需要灵活地调整负载的大小、电压、电流等参数&#xff0c;以满足不同的测试需求。随着科技的不断发展…

pod容器内无法访问集群外部主机ipv6地址

一、背景 同事反馈他这边有一环境出现pod容器内无法请求集群外部主机ipv6地址&#xff0c;但是在pod所在集群所主机上是可以请求到外部主机ipv6地址。 二、问题处理过程 首先主机和主机之间ipv6地址能通讯&#xff0c;说明主机之间网络是没啥问题&#xff0c;哪问题就出在容器…

微信小程序已经审核通过但是提示订单中心path不通过

设置-基本设置-服务内容声明 更改path重新审核即可

history路由解决刷新出现404的问题

本文具体重点介绍怎么解决浏览器路由&#xff08;history模式&#xff09;解决404的问题。 在项目打包上线时&#xff0c;如果采用的是哈希模式&#xff0c;不会出现404&#xff0c;原因是 url 中 # 号后面的内容不会发给后端当作资源路径请求服务器。 具体流程&#xff08;哈…

ABCDE类网络的划分及保留网段

根据IP地址的分类&#xff0c;IP地址被分为A、B、C、D和E五类。下面是对ABCDE类网络的划分及保留网段的详细描述&#xff1a; A类网络&#xff1a;范围从1.0.0.0到127.0.0.0&#xff0c;网络地址的最高位必须是“0”&#xff0c;可用的A类网络有127个&#xff0c;每个网络能容…

【算法提升—力扣每日一刷】五日总结【11/30-12/04】

2023/11/30 力扣每日一刷&#xff1a;1.两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元…

TCP协议实现一对一聊天

服务端代码&#xff1a; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner;/*** 发送消息线程*/ class Send e…

【Linux】tar、zip与rar

前言 我解压过无数的文件&#xff0c;却唯独无法解压自己。 tar tar是一个常用的文件打包和归档工具&#xff0c;它在Linux系统中被广泛使用。它的名称"tar"代表"tape archive"&#xff08;磁带归档&#xff09;&#xff0c;最初用于将多个文件和目录打…

JVM的知识点

### 1. JVM基础知识 - **JVM结构&#xff1a;** 详细介绍JVM内部结构&#xff0c;包括类加载器、运行时数据区域&#xff08;堆、栈、方法区/元空间&#xff09;、执行引擎和本地接口等组成部分的功能和作用。 - **类加载器&#xff1a;** 深入了解类加载器的层次结构和加载过…

linux无法打开M4a格式音频的解决方法

linux是开源系统&#xff0c;之所以打不开&#xff0c;是因为部分linux系统为了避免版权问题&#xff0c;没有m4a的解码插件。所以&#xff0c;解决的办法是安装如下两个非常小的转换器&#xff0c;我们一般用不到转换器的功能&#xff0c;而是反向应用&#xff0c;通过两个几十…

『亚马逊云科技产品测评』活动征文|基于亚马逊EC2云服务器安装Bolo开源博客

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 亚马逊EC2云服务器&#xff08;Elastic Compute Cloud&#xff09;是亚马…