通过Numpy和OpenCV两种方法都可实现傅里叶变换。本节介绍OpenCV方法。

OpenCV提供了函数cv2.dft()cv2.idft()来实现傅里叶变换和逆傅里叶变换。

实现傅里叶变换

函数cv2.dft()的语法格式为:

返回结果 = cv2.dft(原始图像, 转换标识)
  • 对于参数“原始图像”,要首先使用np.float32()函数将图像转换成np.float32格式
  • “转换标识”的值通常为cv2.DFT_COMPLEX_OUTPUT,用来输出一个复数阵列

cv2.dft返回的值是双通道的,第1个通道是结果的实数部分,第2个通道是结果的虚数部分。

经过cv2.dft()的变换后,得到了原始图像的频谱信息。此时,零频率分量并不在中心位置,为了处理方便,需要将其移到中心位置。可以用numpy.fft.fftshift()实现。

dftshift = np.fft.fftshift(dft)

经过这些处理之后,频谱图像还是一个由实部和虚部构成的值,要将其显示出来,还要进一步处理。

函数cv2.magnitude()可以计算频谱信息的幅度。语法:

返回值 = cv2.magnitude(参数1, 参数2)
  • 参数1:浮点型x坐标值,也就是实部
  • 参数2:浮点数y的坐标值,也就是虚部

得到频谱信息的幅度后,通常还要对幅度值做进一步的转换,以便将频谱信息以图像的形式表达出来。

简单说,就是将幅度值映射到灰度图像的灰度空间[0,255]内,使其以灰度图像的形式展示。使用公式:

result = 20 * np.log(cv2.magnitude(实部, 虚部))

例1:用OpenCV函数对图像进行傅里叶变换,并展示其频谱信息。

import numpy as np
import cv2
import matplotlib.pyplot as plt

img = cv2.imread(r'E:\Blog\OpenCV\Process\fisher.png',0)
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(121),plt.imshow(img,cmap='gray')
plt.title('ORIGINAL'),plt.axis('off')
plt.subplot(122),plt.imshow(result,cmap='gray')
plt.title('RESULT'),plt.axis('off')
plt.show()

运行结果:

实现逆傅里叶变换

在OpenCV中,使用函数cv2.idft()实现逆傅里叶变换,该函数是傅里叶函数cv2.dft()的逆函数:

返回结果 = cv2.idft(原始数据)

得到返回结果之后,还需要将频谱从中心移回到原来的位置:

结果 = numpy.fft.ifftshift()

需要注意,在进行逆傅里叶变换后,得到的值仍旧是复数,需要使用函数cv2.magnitude()计算其幅值。

例:用OpenCV函数对图像进行傅里叶变换、逆傅里叶变换,并展示原始图像及经过逆傅里叶变化后得到的图像。

import numpy as np
import cv2
import matplotlib.pyplot as plt

img = cv2.imread(r'E:\Blog\OpenCV\Process\fisher.png',0)
dft = cv2.dft(np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)          #将频谱移到中心
idftShift = np.fft.ifftshift(dftShift)   #将频谱移回原来的位置
imag = cv2.idft(idftShift)
imag = cv2.magnitude(imag[:,:,0],imag[:,:,1])

plt.subplot(121),plt.imshow(img,cmap='gray')
plt.title('ORIGINAL'),plt.axis('off')
plt.subplot(122),plt.imshow(imag,cmap='gray')
plt.title('RESULT'),plt.axis('off')
plt.show()

运行结果:

低通滤波示例

在一幅图像内,低频信号对应图像内变化缓慢的灰度分量。例如,在一幅大草原的图像中,低频信号对应着颜色趋于一致的广袤草原。低通滤波器让高频信号衰减而让低频信号通过。经滤波后,图像会变得模糊。

构造一个中心位置60X60的低通滤波器:

rows, cols = img.shape
crow, ccol = int(rows/2), int(cols/2)
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1

然后,将其与频谱图像进行运算,实现低通滤波:

fShift = dftShift * mask

例:使用函数cv2.dft()对图像进行傅里叶变换,得到其频谱图像。然后,在频域内将其高频分量的值处理为0,实现低通滤波。最后,对图像进行逆傅里叶变换,得到恢复的原始图像。观察傅里叶变换前后图像的差异。

import numpy as np
import cv2
import matplotlib.pyplot as plt

img = cv2.imread(r'E:\Blog\OpenCV\Process\fisher.png',0)
dft = cv2.dft(np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)          #将频谱移到中心

rows, cols = img.shape
crow, ccol = int(rows/2), int(cols/2)
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30,ccol-30:ccol+30] = 1

fshift = dftShift * mask

idftShift = np.fft.ifftshift(fshift)   #将频谱移回原来的位置
imag = cv2.idft(idftShift)
imag = cv2.magnitude(imag[:,:,0],imag[:,:,1])

plt.subplot(121),plt.imshow(img,cmap='gray')
plt.title('ORIGINAL'),plt.axis('off')
plt.subplot(122),plt.imshow(imag,cmap='gray')
plt.title('RESULT'),plt.axis('off')
plt.show()

运行结果:


点击访问我的个人资源收藏网站~~



博主个人公众号
版权声明 ▶ 本网站名称:陶小桃Blog
▶ 本文链接:https://www.52txr.cn/2022/OpenCV47.html
▶ 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行核实删除。
▶ 转载本站文章需要遵守:商业转载请联系站长,非商业转载请注明出处!!

最后修改:2022 年 05 月 17 日
如果觉得我的文章对你有用,请随意赞赏