使用Python numpy 进行二维傅里叶变换 和 图片自相关

本篇主要记录一下
使用Python numpy库 进行求解图像的FFT 以及求解图片的自相关函数

研究背景:
1)某M姓知名数学矩阵分析工具由于灯塔国的政策导致不许使用,平常在M中跑的函数需要转到Python中;
2)笔者的研究课题需要研究一个图片的自相关函数(Auto correlation)
所以使用Python实现了一下

废话结束下面是正文:

#FFT:
#使用 numpy.fft.fft2(正变换) 和numpy.fft.ifft2函数(反变换)
#与Mxxxxx一样,需要np.fft.fftshift 和np.fft.ifftshift调整(相关文章一大堆)
#(画图部分以及完整代码在下面)
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f)

求图片的自相关:网上的资料较少,先给出公式:
在这里插入图片描述
中间的圆圈和叉的组合符号 是相关符号 使用傅里叶变换的卷积定理(相关定理) 不同的教科书叫法不同,找一本图像处理的书都有讲到 下面截取自超星阅读中 某一本数字图像处理的内容:
在这里插入图片描述
笔者只需要求自相关即可 所以上文中共轭相乘变成了求FT模的平方
下面是公式:

#Auto correlation:
AC = np.fft.ifft2(np.abs(f) ** 2 )
AC = np.fft.fftshift(AC)

完整代码如下:

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
plt.rcParams['figure.dpi'] = 150
pic = Image.open('Lena.png').convert('L')
image = np.asarray(pic)
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f)
iff = np.fft.ifft2(f)
#AC = np.fft.ifft2(np.abs(f) ** 2 )
#AC = np.fft.ifftshift(AC)
#上面两行与下面两行效果相同。
AC = np.fft.ifft2(np.abs(f) ** 2 )
AC = np.fft.fftshift(AC)

plt.subplot(221)
plt.imshow(image,cmap='gray')
plt.title('Origin Image')
plt.axis('off')
plt.subplot(222)
plt.imshow(abs(AC),cmap='hot')
plt.title('AutoCorrelation')
plt.axis('off')
plt.show()
plt.subplot(223)
plt.imshow(20 * np.log(np.abs(fshift)),cmap='gray')
plt.axis('off')
plt.title('Fourier Transform')
plt.subplot(224)
plt.imshow(np.abs(iff),cmap='gray')
plt.title('ifft2')
plt.axis('off')
plt.show()

结果:
在这里插入图片描述
在这里插入图片描述

下面是需要注意的问题
1)对于求解的傅里叶频谱图像,在使用plt.imshow()的时候,展示的内容前面需要求 一个 np.log 不知道为什么缘故,有些博文中说,为了修改一下数据范围 (如果不加修改,我的程序结果是一个黑色的方块,感觉就是数据范围的锅) 需要提醒的是仅仅在展示部分需要np.log 对于后续处理还是用原矩阵,别粗心搞错
2)np.ifft2后得到的也是一个复数矩阵,就是截图的右下角ifft2这张图,plt.show()时候,需要加上np.abs()

3)关于自相关计算 计算机编程中, 自相关=二维卷积 甚至比如卷积层 和 说的卷积 其实求的也是自相关计算。关于这一点,如果你真的需要 求解 数学意义上的 二维卷积 需要 对矩阵进行 (上下颠倒+左右颠倒) 也就是旋转180度,由于和本次记录无关,按下不表。
4) 求解自相关的时候 对 f (傅里叶频谱图)求平方 然后求反变换,为啥后面还要加一个fftshift(ifftshift)?
答: 不太清楚,猜测是一个数学问题 ,经过尝试 我认为需要加fftshift这句话
因为如果不加 效果如图
在这里插入图片描述
怎么看都不对把 -_-||

记录完毕 2小时就弄了这点东西
还不开学迟早完蛋~~(已经完蛋了)~~

要对一张图片进行二维傅里叶变换,需要用到Python中的NumPy和OpenCV库。首先,我们需要读取图片并转换为灰度图像: ```python import cv2 import numpy as np # 读取图片并转换为灰度图像 img = cv2.imread('image.jpg', 0) ``` 然后,我们可以使用NumPy中的fft2函数对图像进行二维傅里叶变换: ```python # 对图像进行二维傅里叶变换 f = np.fft.fft2(img) ``` 接下来,我们需要将频域中的直流分量移动到图像中心,并将频域的原点移动到左上角: ```python # 将频域中的直流分量移动到图像中心 fshift = np.fft.fftshift(f) # 将频域的原点移动到左上角 magnitude_spectrum = 20 * np.log(np.abs(fshift)) ``` 最后,我们可以使用OpenCV中的imshow函数显示傅里叶变换后的图像: ```python # 显示傅里叶变换后的图像 cv2.imshow('Magnitude Spectrum', magnitude_spectrum) cv2.waitKey(0) cv2.destroyAllWindows() ``` 完整代码如下: ```python import cv2 import numpy as np # 读取图片并转换为灰度图像 img = cv2.imread('image.jpg', 0) # 对图像进行二维傅里叶变换 f = np.fft.fft2(img) # 将频域中的直流分量移动到图像中心 fshift = np.fft.fftshift(f) # 将频域的原点移动到左上角 magnitude_spectrum = 20 * np.log(np.abs(fshift)) # 显示傅里叶变换后的图像 cv2.imshow('Magnitude Spectrum', magnitude_spectrum) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这样就可以对一张图片进行二维傅里叶变换了。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值