基于Python实现图像的傅里叶变换
作者:一马归一码 发布时间:2023-12-14 09:10:34
标签:Python,图像,傅里叶变换
前言
首先是本文总体代码,改一下图像的读取路径就可以运行了,但我还是建议大家先看后面的步骤一行行敲代码,这样效果更好:
"""
Author:XiaoMa
date:2021/11/7
"""
import cv2
import matplotlib.pyplot as plt
import numpy as np
#读取图像信息
from numpy.fft import ifftshift
img0 = cv2.imread("E:\From Zhihu\For the desk\cvthirteen2.jpg")
img1 = cv2.resize(img0, dsize = None, fx = 0.5, fy = 0.5)
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) #转化为灰度图
h, w = img1.shape[:2]
print(h, w)
cv2.namedWindow("W0")
cv2.imshow("W0", img2)
cv2.waitKey(delay = 0)
#将图像转化到频域内并绘制频谱图
##numpy实现
plt.rcParams['font.family'] = 'SimHei' #将全局中文字体改为黑体
f = np.fft.fft2(img2)
fshift = np.fft.fftshift(f) #将0频率分量移动到图像的中心
magnitude_spectrum0 = 20*np.log(np.abs(fshift))
#傅里叶逆变换
#Numpy实现
ifshift = np.fft.ifftshift(fshift)
# 将复数转为浮点数进行傅里叶频谱图显示
ifimg = np.log(np.abs(ifshift))
if_img = np.fft.ifft2(ifshift)
origin_img = np.abs(if_img)
imggroup = [img2, magnitude_spectrum0, ifimg, origin_img]
titles0 = ['原始图像', '经过移动后的频谱图', '逆变换得到的频谱图', '逆变换得到的原图']
for i in range(4):
plt.subplot(2, 2, i + 1)
plt.xticks([]) #除去刻度线
plt.yticks([])
plt.title(titles0[i])
plt.imshow(imggroup[i], cmap = 'gray')
plt.show()
##OpenCV实现
dft = cv2.dft(np.float32(img2), flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum1 = 20*np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.subplot(121), plt.imshow(img2, cmap = 'gray')
plt.title('原图'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum1, cmap = 'gray')
plt.title('频谱图'), plt.xticks([]), plt.yticks([])
plt.show()
(1)基本概念
一般我们观察信号是直接在时域内(声音信号)或者空间内(图像)对其进行分析,这样虽然符合常理,但信号中的一些有用的条件就不会被我们考虑进去,从而达不到分析的效果,所以我们要将信号转化到其他的一些变换域中进行分析。
(2)读取图像信息
本系列文章经典操作:
"""
Author:XiaoMa
date:2021/11/7
"""
import cv2
import matplotlib.pyplot as plt
import numpy as np
#读取图像信息
img0 = cv2.imread("E:\From Zhihu\For the desk\cvthirteen2.jpg")
img1 = cv2.resize(img0, dsize = None, fx = 0.5, fy = 0.5)
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) #转化为灰度图
h, w = img1.shape[:2]
print(h, w)
cv2.namedWindow("W0")
cv2.imshow("W0", img1)
cv2.waitKey(delay = 0)
得到图像信息如下:
540 960
1. 傅里叶变换
代码参考:OpenCV官网
(1)基本概念
当我们描述一段声音时,我们不仅会说它的音量的大小如何,还有可能会说它的频率是高的还是低的,那么我们该怎么理解频率这个概念呢?以前学习三角函数时我们被告知每一个正弦信号有它的固定的频率,就是它的周期的倒数。那么什么是频域呢?我们也接触过其他形状的波形,比如方波、三角波等等,而这些不同形状的波呢,就是用一个个频率不相同的正弦波组成的,如果我们将那些不同频率的正弦波按照它们的频率大小排列起来,就得到了一个频率轴(这是一维的),然后我们将各个频率对应的幅度值给它们对应起来(就像xoy平面一样)得到的二维的平面,就是频域了。傅里叶变换就是将信号从时域转化到频域的一个工具。对于傅里叶变换中的的理解可以参考下面的图片:
当然如果你想更加深入的了解傅里叶变换,你可以按照图片上的水印去搜索,他那里讲的非常清晰。
(2)numpy实现
#将图像转化到频域内并绘制频谱图
plt.rcParams['font.family'] = 'SimHei' #将全局中文字体改为黑体
f = np.fft.fft2(img2)
fshift = np.fft.fftshift(f) #将0频率分量移动到中心
magnitude_spectrum = 20*np.log(np.abs(fshift))
plt.xticks([]) #除去刻度线
plt.yticks([])
plt.title("频谱图")
plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.show()
(3)OpevCV实现
#OpenCV实现
dft = cv2.dft(np.float32(img2), flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum1 = 20*np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.subplot(121), plt.imshow(img2, cmap = 'gray')
plt.title('原图'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum1, cmap = 'gray')
plt.title('频谱图'), plt.xticks([]), plt.yticks([])
plt.show()
2. 傅里叶逆变换
(1)基本概念
前面提到,经过傅里叶变换图像可以转化到频域内,那么经过傅里叶逆变换,图像肯定能从频域内转化到时域中,所以傅里叶逆变换就是将信号从频域转化到时域的工具。
(2)代码实现
此处的代码接上面的使用 Numpy 进行傅里叶变换
#傅里叶逆变换
#Numpy实现
ifshift = np.fft.ifftshift(fshift)
# 将复数转为浮点数进行傅里叶频谱图显示
ifimg = np.log(np.abs(ifshift))
if_img = np.fft.ifft2(ifshift)
origin_img = np.abs(if_img)
imggroup = [img2, magnitude_spectrum0, ifimg, origin_img]
titles0 = ['原始图像', '经过移动后的频谱图', '逆变换得到的频谱图', '逆变换得到的原图']
for i in range(4):
plt.subplot(2, 2, i + 1)
plt.xticks([]) #除去刻度线
plt.yticks([])
plt.title(titles0[i])
plt.imshow(imggroup[i], cmap = 'gray')
plt.show()
来源:https://blog.csdn.net/qq_52309640/article/details/120941249


猜你喜欢
- JS脚本语言的基础语法:输出语法 alert("警告!"); confirm("确定吗
- 一、serialize()方法格式:var data = $("#formID").serialize();功能:将表单
- 问题今天用nohup后台执行python程序,并将标准输出和错误输出重定向到一个log文件,但发现log文件隔好久才会更新,很煎熬。。。然而
- 前言首先来讲一下服务端渲染,直白的说就是在服务端拿数据进行解析渲染,直接生成html片段返回给前端。具体用法也有很多种比如:传统的服务端模板
- 需要准备环境:python3.6、vultr(或者其他服务器)、xshell第一步:python安装必备环境Django库Xshell链接远
- Ubuntu 安装jdk:[链接]Ubuntu安装eclipse:[链接]Ubuntu下安装MySQL与mysql workbench:[链
- Python中对象的行为是由它的类型 (Type) 决定的。所谓类型就是支持某些特定的操作。数字对象在任何编程语言中都是基础元素,支持加、减
- python编写的语音天气预报本系统主要包括四个函数:1、获取天气数据1、输入要查询天气的城市2、利用urllib模块向中华万年历天气api
- 分享一下 IntelliJ IDEA 2021.1 的激活破解教程,相当于永久激活了,亲测有效,下面是详细文档哦~申明:本教程 Intell
- 一、题目描述题目内容:题目示例:题目解析:1 <= nums.length <= 104-107 <= nums
- 阅读上一篇:交互设计模式(二)-Pagination(分页,标记页数) Tagging(标签)问题摘要用户往往想通过流行或最详尽的主题来浏览
- 1. 安装Pyechartspip install pyecharts2. 图表基础2.1 主题风格添加主题风格使用的是 InitOpts(
- 这句话后面的1200是什么单位来的啊?delete from online where datediff(""s&quo
- Node.js中的事件触发器所引发的思考今天在看 Node.js 文档的时候讲到事件触发器,其中的 emit 方法让我想到了 Vue 中的自
- 用pytorch训练一个神经网络时,我们通常会很关心模型的参数总量。下面分别介绍来两种方法求模型参数一 .求得每一层的模型参数,然后自然的可
- 1. 训练运行时候指定GPU运行时候加一行代码:CUDA_VISIBLE_DEVICES=1 python train.py2. 运行过程中
- 可变参数可变参数应该最简单,在C/C++和Java等语言中都有,就是用*号来表示,例如def testArg(*arg)你可以传入任意多个元
- INI介绍INI是英文“初始化”(initialization)的缩写,被用来对操作系统或特定程序初
- 本文实例讲述了Python3.5 Json与pickle实现数据序列化与反序列化操作。分享给大家供大家参考,具体如下:1、Json:不同语言
- 本文实例讲述了MySql数据库基础知识点。分享给大家供大家参考,具体如下:数据库基本操作1)创建数据库基本语法: create databa