数字图像处理:频率域滤波

数字图像处理:频率域滤波

笔者相关内容笔记:
1.傅里叶变换与图像处理
2.傅利叶变换在图像处理的应用

1.1 频率域滤波总体流程


1.2 DFT/IDFT



DFT的例子






1.3 常见频率域滤波器


过滤高频信息,保留低频信息,则图像模糊

过滤低频信息,保留高频信息,则显示图像细节

1.3.1 理想低通滤波器



1.3.2 Butterworth低通滤波器


1.3.3 Gauss低通滤波器


1.3.4 理想高通滤波器


1.3.5 Butterworth高通滤波器


1.3.6 Gauss高通滤波器


1.4 代码实现

(1)对一副图像进行缩放,显示原始图像和缩放后的图像,分别对其进行傅里 叶变换,显示变换后结果;

import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np# 读取一幅图像(以灰度模式)
img_dir = r'D:\Document\Experiment\data\image1.jpg'  # 图像路径
gray = cv.imread(img_dir, 0)  # 读取图像,0表示以灰度图像模式读取# 对图像进行缩放
rows, cols = gray.shape[:2]  # 获取原图像的行和列数
resize_gray = cv.resize(gray, (int(cols * 0.6), int(rows * 0.6)))  # 将图像缩放到原来的60%# 显示原始图像和缩放后的图像
plt.figure(figsize=(10, 5))  # 创建一个10x5英寸的图形窗口
plt.subplot(1, 2, 1)  # 创建一个1行2列的子图,并选择第1个
plt.title("gray")  # 设置子图的标题
plt.imshow(gray, cmap='gray')  # 显示原始灰度图像plt.subplot(1, 2, 2)  # 选择第2个子图
plt.title("Resize_gray")  # 设置子图的标题
plt.imshow(resize_gray, cmap='gray')  # 显示缩放后的灰度图像plt.show()  # 显示所有子图# 对原图像进行傅立叶变换
dft = cv.dft(np.float32(gray), flags=cv.DFT_COMPLEX_OUTPUT)  # 计算图像的离散傅里叶变换
dft_shift = np.fft.fftshift(dft)  # 将零频率分量移动到频谱中心
mag, angle = cv.cartToPolar(dft_shift[:, :, 0], dft_shift[:, :, 1])  # 从复数形式转换为极坐标形式,获取幅度和相位
mag = 20 * np.log(mag)  # 对幅度进行对数缩放,以便更好地可视化# 对缩放后的图像进行傅立叶变换
resize_dft = cv.dft(np.float32(resize_gray), flags=cv.DFT_COMPLEX_OUTPUT)  # 计算缩放图像的傅里叶变换
resize_dft_shift = np.fft.fftshift(resize_dft)  # 将零频率分量移动到频谱中心
resize_mag, angle = cv.cartToPolar(resize_dft_shift[:, :, 0], resize_dft_shift[:, :, 1])  # 从复数形式转换为极坐标形式
resize_mag = 20 * np.log(resize_mag)  # 对幅度进行对数缩放# 显示原图和缩放后图像的傅立叶变换结果
plt.figure(figsize=(10, 5))  # 创建一个新的图形窗口
plt.subplot(1, 2, 1)  # 创建1行2列的子图,选择第1个
plt.title("DFT")  # 设置子图的标题
plt.imshow(mag, cmap='gray')  # 显示原图的傅里叶变换结果plt.subplot(1, 2, 2)  # 选择第2个子图
plt.title("Resize_DFT")  # 设置子图的标题
plt.imshow(resize_mag, cmap='gray')  # 显示缩放图像的傅里叶变换结果plt.show()  # 显示所有子图


分析原图的傅里叶频谱和缩放后的傅里叶频谱的对应关系
当图像缩小时,频谱的幅度分布会有所变化,尤其是高频成分的能量可能会被削弱,导致模糊。在频域中,频谱的中心部分代表低频信息,而边缘部分代表高频信息。因此,缩放后,频谱的范围也会随之缩小。

(2)对一副图像进行旋转,显示原始图像和旋转后的图像,分别对其进行傅里 叶变换,显示变换后结果;

import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np# 读取一幅图像(以灰度模式)
img_dir = r'D:\Document\Experiment\data\image1.jpg'  # 图像路径
gray = cv.imread(img_dir, 0)  # 读取图像,0表示以灰度图像模式读取# 对图像进行旋转
rows, cols = gray.shape[:2]  # 获取原图像的行和列数
# 获取旋转矩阵,中心点为图像中心,旋转角度为45度,缩放因子为1
rot_matrix = cv.getRotationMatrix2D((cols / 2, rows / 2), 45, 1)  
# 使用仿射变换对图像进行旋转
rotated_gray = cv.warpAffine(gray, rot_matrix, (cols, rows))# 显示原始图像和旋转后的图像
plt.figure(figsize=(10, 5))  # 创建一个10x5英寸的图形窗口
plt.subplot(1, 2, 1)  # 创建一个1行2列的子图,并选择第1个
plt.title("gray")  # 设置子图的标题
plt.imshow(gray, cmap='gray')  # 显示原始灰度图像plt.subplot(1, 2, 2)  # 选择第2个子图
plt.title("Rotated_gray")  # 设置子图的标题
plt.imshow(rotated_gray, cmap='gray')  # 显示旋转后的灰度图像plt.show()  # 显示所有子图# 对原图像进行傅立叶变换
dft = cv.dft(np.float32(gray), flags=cv.DFT_COMPLEX_OUTPUT)  # 计算图像的离散傅里叶变换
dft_shift = np.fft.fftshift(dft)  # 将零频率分量移动到频谱中心
mag, angle = cv.cartToPolar(dft_shift[:, :, 0], dft_shift[:, :, 1])  # 从复数形式转换为极坐标形式,获取幅度和相位
mag = 20 * np.log(mag)  # 对幅度进行对数缩放,以便更好地可视化# 对旋转后的图像进行傅立叶变换
rotated_dft = cv.dft(np.float32(rotated_gray), flags=cv.DFT_COMPLEX_OUTPUT)  # 计算旋转图像的傅里叶变换
rotated_dft_shift = np.fft.fftshift(rotated_dft)  # 将零频率分量移动到频谱中心
rotated_mag, angle = cv.cartToPolar(rotated_dft_shift[:, :, 0], rotated_dft_shift[:, :, 1])  # 从复数形式转换为极坐标形式
rotated_mag = 20 * np.log(rotated_mag)  # 对幅度进行对数缩放# 显示原图和旋转后图像的傅立叶变换结果
plt.figure(figsize=(10, 5))  # 创建一个新的图形窗口
plt.subplot(1, 2, 1)  # 创建1行2列的子图,选择第1个
plt.title("DFT")  # 设置子图的标题
plt.imshow(mag, cmap='gray')  # 显示原图的傅里叶变换结果plt.subplot(1, 2, 2)  # 选择第2个子图
plt.title("Rotated_DFT")  # 设置子图的标题
plt.imshow(rotated_mag, cmap='gray')  # 显示旋转图像的傅里叶变换结果plt.show()  # 显示所有子图


分析原图的傅里叶频谱和旋转后的傅里叶频谱的对应关系;
在旋转操作中,频谱的中心(表示低频成分)仍然保持在原来的位置,但高频成分的分布会发生变化。具体来说,旋转图像后的频谱在相位上可能会有明显的变化,反映出旋转方向和角度。

(3)读取图像进行傅里叶变换,之后使用Gauss高通滤波器进行滤波,最后逆傅里叶变换恢复图像

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt# 1. 读取一幅图像(以灰度模式)
img_dir = r'D:\Document\Experiment\data\image1.jpg'  # 图像路径
gray = cv.imread(img_dir, 0)  # 读取图像,0表示以灰度图像模式读取# 2. 进行傅里叶变换
# 使用 np.fft.fft2 进行二维傅里叶变换,并使用 np.fft.fftshift 将频率搬移到中心
dft = np.fft.fft2(gray)
dft_shift = np.fft.fftshift(dft)  # 将低频部分移动到中心# 3. 构建高斯高通滤波器
rows, cols = gray.shape
crow, ccol = rows // 2 , cols // 2  # 中心位置# 创建一个与图像尺寸相同的掩膜,初始值为1
mask = np.ones((rows, cols), np.float32)# 高斯高通滤波器:创建一个高斯核,大小为 rows x cols,中心值为 0
sigma = 50  # 控制滤波器的大小
for i in range(rows):for j in range(cols):distance = np.sqrt((i - crow)**2 + (j - ccol)**2)mask[i, j] = 1 - np.exp(-(distance**2) / (2 * (sigma**2)))# 4. 对频域图像应用滤波器
filtered_dft_shift = dft_shift * mask# 5. 进行逆傅里叶变换以恢复图像
# 使用 np.fft.ifftshift 将频率搬移回去
f_ishift = np.fft.ifftshift(filtered_dft_shift)
# 逆傅里叶变换
img_back = np.fft.ifft2(f_ishift)
# 取绝对值,得到实际图像
img_back = np.abs(img_back)# 6. 显示图像
plt.figure(figsize=(12, 8))# 原始图像
plt.subplot(221), plt.imshow(gray, cmap='gray')
plt.title('Original Image'), plt.axis('off')# 傅里叶变换后的频谱图
magnitude_spectrum = 20 * np.log(np.abs(dft_shift))
plt.subplot(222), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Fourier Transform (Magnitude Spectrum)'), plt.axis('off')# 经过高斯高通滤波后的频谱图
filtered_magnitude_spectrum = 20 * np.log(np.abs(filtered_dft_shift))
plt.subplot(223), plt.imshow(filtered_magnitude_spectrum, cmap='gray')
plt.title('Filtered Spectrum (Gaussian High-pass)'), plt.axis('off')# 恢复后的图像
plt.subplot(224), plt.imshow(img_back, cmap='gray')
plt.title('Recovered Image (After Inverse FFT)'), plt.axis('off')plt.tight_layout()
plt.show()

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

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

相关文章

特步引入IPD管理,钉钉项目 Teambition 助力高效产品研发管理

中国是全球第二大消费市场,运动鞋服行业拥有着巨大的发展潜力。在过去五年时间里,随着中国产品品牌和质量的提升,体育市场的占有率格局发生了显著变化,不同于部分国际品牌巨头营收持续减弱,国产领军体育运动品牌「特步…

RK平台 GPIO序号转换软件

RK平台 GPIO序号转换软件 下载地址 https://download.csdn.net/download/ruidongren/89900151 链接: link

大数据毕业设计选题推荐-电影数据分析系统-电影推荐系统-Python数据可视化-Hive-Hadoop-Spark

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

VSCode中的TypeScript教程

TypeScript 是JavaScript的类型化超集,可编译为纯JavaScript。它提供了类、模块和接口来帮助您构建健壮的组件。 安装 TypeScript 编译器 Visual Studio Code 包括 TypeScript 语言支持,但不包括 TypeScript 编译器tsc。您需要在全局或工作区中安装Typ…

空间解析几何 4:空间中线段到圆的距离【附MATLAB代码】

目录 理论公式 matlab代码 理论公式 对于解一元4次方程,请详见我的博客 一元四次方程求解 -【附MATLAB代码】-CSDN博客文章浏览阅读1.4k次,点赞41次,收藏4次。最近在研究机器人的干涉(碰撞)检测,遇到了一…

015_基于django旅游数据分析与推荐系统2024_cg8s735i

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍:CodeMentor毕业设计领航者、全网关注者30W群落,InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者,博客领航之星、开发者头条/腾讯云/AW…

使用Docker启动的Redis容器使用的配置文件路径等问题以及Python使用clickhouse_driver操作clickhouse数据库

一、使用Docker启动的Redis容器使用的配置文件路径等问题 1.docker启动的redis使用的配置文件路径是什么 使用docker搭建redis服务,本身redis启动的时候可以指定配置文件的, redis-server /指定配置文件路径/redis.conf。 但手上也没有一个redis配置文件…

win10上安装wsl(ubuntu)

1,搜索到微软网站下载 Ubuntu Installer.exe文件,运行它。 2.根据提示点击获取ubuntu,自动下载完之后提示安装,do。 3.出错:Installing, this may take a few minutes... WslRegisterDistribution failed with error: 0x8007019e Error: 0x8…

吴伟仁《英国文学史及选读》第一二册课后答案PDF

新经典高等学校英语专业系列教材《英国文学史及选读》根据英国文学历史的顺序结合作品选读编写而成,在历史部分,对英国文学史的每个阶段作了简明扼要的概述,而在作品选读部分则尽可能遴选了文学史上的重要作家和重要作品。教材内容丰富&#…

Web集群服务-代理和负载均衡

1. 概述 1. 用户----->代理--->Web节点,后面只有一个节点,一般使用的是nginx代理功能即可 2. 后面如果是集群需要使用nginx负载均衡功能 2. 代理分类 代理分类方向应用正向代理用户(服务器)-->代理--->外部(某网站)服务器通过代理实现共享上网/访问公网反向代理用…

MySQL-事务Transaction详解

文章目录 事务概述事务基本概念事务四大特性(ACID)演示MySQL事务手动开启事务MySQL默认事务机制 事务的隔离级别隔离级别基本概述三种现象脏读不可重复读幻读 查看和设置隔离级别四种隔离级别及演示读未提交(read uncommitted)读提交(read committed)可重复读(repeatable read)…

颠覆Transformer的Mamba模型[精简版本]------S4

1、改进transformer不擅长处理超长的序列的问题:输入u到状态x 序列数据一般都是离散的数据 比如文本、图、DNA,但现实生活中还有很多连续的数据,比如音频、视频,对于音视频这种信号而言,其一个重要特点就是有极长的context window,而在transformer长context上往往会失败,…

Spring Boot技术栈的电影评论网站设计与实现

6系统测试 6.1概念和意义 测试的定义:程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为: 目的:发现程序的错误; 任务:通过在计算机上执行程序,暴露程序中潜在的错误。 另一个…

算法——python实现堆排序

文章目录 堆排序二叉树堆堆排序的过程:代码实现python中的heapq模块 堆排序 二叉树 关于二叉树的操作,其实核心就是 父节点找子节点,子节点找父节点 如果要将二叉树存储到队列中,就需要找出 父子节点之间的规律: 父…

什么是SYN flood,如何处理

在数字化时代,随着互联网的普及和技术的飞速发展,网络安全问题变得日益严峻。Flood攻击,作为一种典型的网络攻击手段,对个人和企业的信息安全构成了重大威胁。通过深入了解Flood攻击的概念、特点、影响及解决方案,我们…

Sentinel 快速入门

前置推荐阅读:Sentinel 介绍-CSDN博客 前置推荐阅读:Nacos快速入门-CSDN博客 快速开始 欢迎来到 Sentinel 的世界!这篇新手指南将指引您快速入门 Sentinel。 Sentinel 的使用可以分为两个部分: 核心库(Java 客户端)&#xff1a…

现代数字信号处理I-P4 CRLB+LMMSE 学习笔记

目录 学习资料视频链接: 1. 估计参数的CRLB回顾 2. 参数变换下的CRLB拓展 3. 矢量参数下的CRLB扩展 3.1 矢量参数下的CRLB公式 3.2 两个矩阵不等式关系的意义说明 3.3 矢量参数下CRLB公式的证明过程 4. 线性估计 重点注意事项:此处的线性估计&am…

【React】React18核心源码解读

前言 本文使用 React18.2.0 的源码,如果想回退到某一版本执行git checkout tags/v18.2.0即可。如果打开源码发现js文件报ts类型错误请看本人另一篇文章:VsCode查看React源码全是类型报错如何解决。 阅读源码的过程: 下载源码 观察 package…

【java面经thinking】二

目录 redis了解 使用原因 应用场景 数据类型 redis事务 数据持久化 RDB(快照): AOF(即时更新): 选择方式: redis快速的原因 redis单线程 单机瓶颈 经典3问 参考博客 redis了解 缓存中间件 使用原因 缓解高并发、提升高可用。…

Qt 实现动态时钟

1.实现效果 2.widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace