python fft得到有效值 python fft函数
一、图像频谱
在 numpy 库的 fft 模块中有计算二维离散傅里叶变换的函数 fft2,此外图像
变换到频域后,原点需要移动到频域矩形的中心,所以要对fft2的结果使用fftshift
函数实现频谱中心化。计算二维离散逆傅里叶变换的函数为 ifft2,频谱去中心化
的函数为 ifftshift。
输入一张灰度图,输出经过二维离散傅里叶变换后的结果,但是傅里叶变换
的结果为复数,需要通过使用 abs 函数求模才可以进行可视化,且因为傅里叶频
谱范围很大,所以要用对数变换来改善视觉效果。
在使用 log 函数的时候,要写成 log(1 + x) 而不是直接用 log(x),以避免出
现 x=0 的情况。
读入一幅灰度图像,求其频谱,代码示例如下:
from skimage import data
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=12)
img = data.camera()
f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f) # 将原点转移到中间位置
fimg = np.log(np.abs(fshift)+1) # fft 结果是复数,求模之后才是振幅
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(img, 'gray')
plt.title('原始图像',fontproperties=font_set)
plt.subplot(122)
plt.imshow(fimg, 'gray')
plt.title('傅里叶变换图像',fontproperties=font_set)
plt.show()
输出:
利用函数(np.zeros)生成一个 600* 600 的单通道图像,并在该图中心生成
一个高 400 宽 100 的白色矩形,得到亮块图像,求此图像的频谱图,代码示例如
下:
from skimage import data,transform
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=12)
image=np.zeros((600,600),dtype='uint8')
image[100:500,250:350]=255
f=np.fft.fft2(image)
fshift = np.fft.fftshift(f)
fimg = np.log(np.abs(fshift)+1)
plt.figure(figsize=(6,8))
plt.subplot(121)
plt.imshow(image, plt.cm.gray)
plt.title('单通道图像',fontproperties=font_set)
plt.subplot(122)
plt.imshow(fimg, plt.cm.gray)
plt.title('傅里叶变换图像',fontproperties=font_set)
plt.show()
image2 =transform.rotate(image,45)
f=np.fft.fft2(image2)
fshift = np.fft.fftshift(f)
fimg = np.log(np.abs(fshift)+1)
plt.figure(figsize=(6,8))
plt.subplot(121)
plt.imshow(image2,plt.cm.gray)
plt.title('旋转图像',fontproperties=font_set)
plt.subplot(122)
plt.imshow(fimg,plt.cm.gray)
plt.title('傅里叶变换图像',fontproperties=font_set)
plt.show()
输出:
二、图像频域低通滤波
1. 理想低通滤波器
读入一幅灰度图像,用理想低通滤波器做滤波,代码示例如下:
from skimage import data
import numpy as np
from math import sqrt
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=12)
img = data.camera()
f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f) # 将原点转移到中间位置
fimg = np.log(np.abs(fshift)+1) # fft 结果是复数,求模之后才是振幅
#实现理想低通滤波器
D=30
rows,cols=img.shape
crow,ccol=int(rows/2),int(cols/2) #计算频谱中心
mask=np.zeros((rows,cols),np.uint8) #生成 rows 行 cols 的矩阵,数据格式为 uint8
for i in range(rows):
for j in range(cols):
dis = sqrt((i - crow) ** 2 + (j - ccol) ** 2)
if dis <=D:# 将距离频谱中心小于 D 的部分低通信息 设置为 1,属于低通滤波
mask[i,j]=1
else:
mask[i,j]=0
f1_shift=fshift*mask
f_ishift=np.fft.ifftshift(f1_shift)
img_back=np.fft.ifft2(f_ishift)
img_back=np.abs(img_back)
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(fimg,plt.cm.gray)
plt.title('原始频谱',fontproperties=font_set)
plt.subplot(122)
plt.imshow(np.log(np.abs(f1_shift)+1),plt.cm.gray)
plt.title('滤波后频谱',fontproperties=font_set)
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(img, plt.cm.gray)
plt.title('原始图像',fontproperties=font_set)
plt.subplot(122)
plt.imshow(img_back, plt.cm.gray)
plt.title('理想低通滤波后图像',fontproperties=font_set)
plt.show()
输出:
2. Butterworth 低通滤波器
读入一幅灰度图像,用 Butterworth 低通滤波器做滤波,代码示例如下:
from skimage import data
import numpy as np
from math import sqrt
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=12)
img = data.camera()
f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f) # 将原点转移到中间位置
transfor_matrix = np.zeros(img.shape)
#实现 Butterworth 低通滤波器
d=30
n=2
rows,cols=img.shape
crow,ccol=int(rows/2),int(cols/2) #计算频谱中心
for i in range(rows):
for j in range(cols):
dis = sqrt((i - crow) ** 2 + (j - ccol) ** 2)
transfor_matrix[i, j] = 1 / (1 + (dis / d) ** (2*n))
f1_shift=fshift*transfor_matrix
f_ishift=np.fft.ifftshift(f1_shift)
img_back=np.fft.ifft2(f_ishift)
img_back=np.abs(img_back)
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(img, plt.cm.gray)
plt.title('原始图像',fontproperties=font_set)
plt.subplot(122)
plt.imshow(img_back, plt.cm.gray)
plt.title('Butterworth 低通滤波后图像',fontproperties=font_set)
plt.show()
输出:
3. 高斯低通滤波器
读入一幅灰度图像,用高斯低通滤波器做滤波,代码示例如下:
from skimage import data
import numpy as np
from math import sqrt
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=12)
img = data.camera()
f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f) # 将原点转移到中间位置
transfor_matrix = np.zeros(img.shape)
#实现高斯低通滤波器
d=30
rows,cols=img.shape
crow,ccol=int(rows/2),int(cols/2) #计算频谱中心
for i in range(rows):
for j in range(cols):
dis = sqrt((i - crow) ** 2 + (j - ccol) ** 2)
transfor_matrix[i, j] =np.exp(-dis ** 2/(2 * d ** 2))
f1_shift=fshift*transfor_matrix
f_ishift=np.fft.ifftshift(f1_shift)
img_back=np.fft.ifft2(f_ishift)
img_back=np.abs(img_back)
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(img, plt.cm.gray)
plt.title('原始图像',fontproperties=font_set)
plt.subplot(122)
plt.imshow(img_back, plt.cm.gray)
plt.title('Gauss 低通滤波后图像',fontproperties=font_set)
plt.show()
输出:
三、图像频域高通滤波
1. 理想高通滤波器
读入一幅灰度图像,用理想高通滤波器做滤波,代码示例如下:
from skimage import data
import numpy as np
from math import sqrt
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=12)
img = data.camera()
f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f) # 将原点转移到中间位置
fimg = np.log(np.abs(fshift)+1) # fft 结果是复数,求模之后才是振幅
#实现理想高通滤波器
D=30
rows,cols=img.shape
crow,ccol=int(rows/2),int(cols/2) #计算频谱中心
mask=np.zeros((rows,cols),np.uint8) #生成 rows 行 cols 的矩阵,数据格式为 uint8
for i in range(rows):
for j in range(cols):
dis = sqrt((i - crow) ** 2 + (j - ccol) ** 2)
if dis <=D:
# 将距离频谱中心大于 D 的部分高通信息设置为 1,属于高通滤波
mask[i,j]=0
else:
mask[i,j]=1
f1_shift=fshift*mask
f_ishift=np.fft.ifftshift(f1_shift)
img_back=np.fft.ifft2(f_ishift)
img_back=np.abs(img_back)
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(fimg,plt.cm.gray)
plt.title('原始频谱',fontproperties=font_set)
plt.subplot(122)
plt.imshow(np.log(np.abs(f1_shift)+1),plt.cm.gray)
plt.title('滤波后频谱',fontproperties=font_set)
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(img, plt.cm.gray)
plt.title('原始图像',fontproperties=font_set)
plt.subplot(122)
plt.imshow(img_back, plt.cm.gray)
plt.title('理想高通滤波后图像',fontproperties=font_set)
plt.show()
输出:
2. Butterworth 高通滤波器
读入一幅灰度图像,用 Butterworth 高通滤波器做滤波,代码示例如下:
from skimage import data
import numpy as np
from math import sqrt
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=12)
img = data.camera()
f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f) # 将原点转移到中间位置
transfor_matrix = np.zeros(img.shape)
#实现 Butterworth 高通滤波器
d=30
n=2
rows,cols=img.shape
crow,ccol=int(rows/2),int(cols/2) #计算频谱中心
for i in range(rows):
for j in range(cols):
dis = sqrt((i - crow) ** 2 + (j - ccol) ** 2)
transfor_matrix[i, j] =1- 1 / (1 + (dis / d) ** (2*n))
f1_shift=fshift*transfor_matrix
f_ishift=np.fft.ifftshift(f1_shift)
img_back=np.fft.ifft2(f_ishift)
img_back=np.abs(img_back)
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(img, plt.cm.gray)
plt.title('原始图像',fontproperties=font_set)
plt.subplot(122)
plt.imshow(img_back, plt.cm.gray)
plt.title('Butterworth 高通滤波后图像',fontproperties=font_set)
plt.show()
输出:
3. 高斯高通滤波器
读入一幅灰度图像,用高斯高通滤波器做滤波,代码示例如下:
from skimage import data
import numpy as np
from math import sqrt
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=12)
img = data.camera()
f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f) # 将原点转移到中间位置
transfor_matrix = np.zeros(img.shape)
#实现高斯高通滤波器
d=30
rows,cols=img.shape
crow,ccol=int(rows/2),int(cols/2) #计算频谱中心
for i in range(rows):
for j in range(cols):
dis = sqrt((i - crow) ** 2 + (j - ccol) ** 2)
transfor_matrix[i, j] =1-np.exp(-dis ** 2/(2 * d ** 2))
f1_shift=fshift*transfor_matrix
f_ishift=np.fft.ifftshift(f1_shift)
img_back=np.fft.ifft2(f_ishift)
img_back=np.abs(img_back)
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(img, plt.cm.gray)
plt.title('原始图像',fontproperties=font_set)
plt.subplot(122)
plt.imshow(img_back, plt.cm.gray)
plt.title('Gauss 高通滤波后图像',fontproperties=font_set)
plt.show()
输出:每日“大饼”:
只要你想 这个世界就会有奇迹
上一篇: 数字图像处理——图像变换(二维离散傅里叶正逆变换fft2/fft2、离散余弦正逆变换dct2/idct2、频谱正逆平移fftshift/ifftshift、幅度谱与相位谱)| 例题与分析
下一篇: 利用傅立叶变换进行图像处理的代码演示
推荐阅读
-
fft python绘制 python的fft
-
14-傅里叶变换的代码实现-一、numpy实现傅里叶变换和逆傅里叶变换 1.numpy实现傅里叶变换numpy.fft.fft2实现傅里叶变换,返回一个复数数组(complex ndarray),也就是频谱图像numpy.fft.fftshift将零频率分量移到频谱中心(将左上角的低频区域,移到中心位置) 20*np.log(np.abs(fshift))设置频谱的范围。可以理解为,之前通过傅里叶变换得到复数的数组,是不能通过图像的方法展示出来的,需要转换为灰度图像(映射到[0,255]区间)需要注意的是1> 傅里叶得到低频、高频信息,针对低频、高频处理能够实现不同的目的2> 傅里叶过程是可逆的,图像经过傅里叶变换、逆傅里叶变换后,能够恢复到原始图像3> 在频域对图像进行处理,在频域的处理会反映在逆变换图像上 # 将绘制的图显示在窗口 %matplotlib qt5 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread(r"image\lena.bmp",cv2.IMREAD_GRAYSCALE) # 傅里叶变换 f = np.fft.fft2(img) # 移动中心位置 fshift = np.fft.fftshift(f) # 调整值范围 result = 20*np.log(np.abs(fshift)) plt.subplot(1,2,1) plt.imshow(img,cmap=plt.cm.gray) plt.title("original") plt.axis("off") plt.subplot(1,2,2) plt.imshow(result,cmap=plt.cm.gray) plt.title("result") plt.axis("off") plt.show 傅里叶变换的频谱图像: 2.numpy实现逆傅里叶变换numpy.fft.ifft2实现逆傅里叶变换,返回一个复数数组(complex ndarray)numpy.fft.ifftshiftfftshift函数的逆函数,将中心位置的低频,重新移到左上角iimg = np.abs(逆傅里叶变化结果)设置值的范围,映射到[0,255]区间 # 将绘制的图显示在窗口 %matplotlib qt5 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread(r"image\boat.bmp",cv2.IMREAD_GRAYSCALE) # 傅里叶变换 f = np.fft.fft2(img) fshift = np.fft.fftshift(f) # 逆傅里叶变换 ishift = np.fft.ifftshift(fshift) iimg = np.fft.ifft2(ishift) iimg = np.abs(iimg) plt.subplot(1,2,1) plt.imshow(img,cmap=plt.cm.gray) plt.title("original") plt.axis("off") plt.subplot(1,2,2) plt.imshow(iimg,cmap=plt.cm.gray) plt.title("iimg") plt.axis("off") plt.show 将一副图像,进行傅里叶变换和逆傅里叶变换后,进行对比(一样的) 实例:通过numpy实现高通滤波,保留图像的边缘信息 获取图像的形状rows,cols = img.shape获取图像的中心点crow,ccol = int(rows/2),int(cols/2)将频谱图像的中心区域(低频区域)设置为0(黑色)fshift[crow-30:crow+30,ccol-30:ccol+30] = 0 # 将绘制的图显示在窗口 %matplotlib qt5 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread(r"image\boat.bmp",cv2.IMREAD_GRAYSCALE) # 傅里叶变换 f = np.fft.fft2(img) fshift = np.fft.fftshift(f) # 高通滤波 rows,cols = img.shape crow,ccol = int(rows/2),int(cols/2) fshift[crow-30:crow+30,ccol-30:ccol+30] = 0 # 逆傅里叶变换 ishift = np.fft.ifftshift(fshift) iimg = np.fft.ifft2(ishift) iimg = np.abs(iimg) plt.subplot(1,2,1) plt.imshow(img,cmap=plt.cm.gray) plt.title("original") plt.axis("off") plt.subplot(1,2,2) plt.imshow(iimg,cmap=plt.cm.gray) plt.title("iimg") plt.axis("off") plt.show 使用numpy实现高通滤波的实验结果: 二、opencv实现傅里叶变换和逆傅里叶变换 1.opencv实现傅里叶变换 返回结果 = cv2.dft(原始图像,转换标识)1> 返回结果:是双通道的,第一个通道是结果的实数部分,第二个通道是结果的虚数部分2> 原始图像:输入图像要首先转换成np.float32(img)格式3> 转换标识:flags = cv2.DFT_COMPLEX_OUTPUT,输出一个复数阵列numpy.fft.fftshift将零频率分量移到频谱中心(将左上角的低频区域,移到中心位置)调整频谱的范围,将上面频谱图像的复数数组,转换为可以显示的灰度图像(映射到[0,255]区间)返回值 = 20*np.log(cv2.magnitude(参数1,参数2))1> 参数1:浮点型X坐标值,也就是实部2> 参数2:浮点型Y坐标值,也就是虚部 # 将绘制的图显示在窗口 %matplotlib qt5 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread(r"image\lena.bmp",cv2.IMREAD_GRAYSCALE) # 傅里叶变换 dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT) # 移动中心位置 dftShift = np.fft.fftshift(dft) # 调整频谱的范围 result = 20*np.log(cv2.magnitude(dftShift[:,:,0],dftShift[:,:,1])) plt.subplot(1,2,1) plt.imshow(img,cmap=plt.cm.gray) plt.title("original") plt.axis("off") plt.subplot(1,2,2) plt.imshow(result,cmap=plt.cm.gray) plt.title("result") plt.axis("off") plt.show 傅里叶变换的频谱图像: 2.opencv实现逆傅里叶变换返回结果 = cv2.idft(原始数据)1> 返回结果:取决于原始数据的类型和大小2> 原始数据:实数或者复数均可numpy.fft.ifftshiftfftshift函数的逆函数,将中心位置的低频,重新移到左上角调整频谱的范围,映射到[0,255]区间返回值 = cv2.magnitude(参数1,参数2)1> 参数1:浮点型X坐标值,也就是实部2> 参数2:浮点型Y坐标值,也就是虚部 # 将绘制的图显示在窗口 %matplotlib qt5 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread(r"image\lena.bmp",cv2.IMREAD_GRAYSCALE) # 傅里叶变换 dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT) dftShift = np.fft.fftshift(dft) # 逆傅里叶变换 ishift = np.fft.ifftshift(dftShift) iimg = cv2.idft(ishift) iimg = cv2.magnitude(iimg[:,:,0],iimg[:,:,1]) plt.subplot(1,2,1) plt.imshow(img,cmap=plt.cm.gray) plt.title("original") plt.axis("off") plt.subplot(1,2,2) plt.imshow(iimg,cmap=plt.cm.gray) plt.title("inverse") plt.axis("off") plt.show 将一副图像,进行傅里叶变换和逆傅里叶变换后,进行对比(一样的) 实例:通过opencv实现低通滤波,模糊一副图像
-
python fft得到有效值 python fft函数
-
Python numpy.fft.fftshift示例解析-例子说明
-
Python示例:使用torch.fft.fftshift进行傅里叶转换位移-注意事项
-
使用Python进行快速傅里叶变换FFT
-
np.fft.fftshift python
-
python numpy.fft.fftshift
-
Python源码编写和介绍FFT算法
-
使用 python 进行傅立叶 FFT 频谱分析的详细教程