OpenCV傅里叶变换

来源:互联网 发布:淘宝qps 编辑:程序博客网 时间:2024/05/21 10:55

傅里叶变换可以将图像的时域信号转换到频域,通过频域我们可以看到信号的另一面。我们可以在频域对图像进行滤波等处理,然后通过傅里叶反变换,将频域图像转换回时域,就可以看到处理后的图像。


实际应用中,更多的是在频域进行滤波器设计,设计合适的滤波器,然后将滤波器经过傅里叶反变换生成时域滤波器,最后在时域进行滤波操作。


下面通过一个例子,看看如何使用OpenCV进行傅里叶变换及其反变换。

import cv2import numpy as npimport matplotlib.pyplot as pltimage = cv2.imread(r'pics/lena.png', cv2.IMREAD_GRAYSCALE)dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)dft_shift = np.fft.fftshift(dft)magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))

导入相应的包后,先读取灰度图像,使用OpenCV的dft函数,可以进行傅里叶变换,之后使用numpy的fft模块的fftshift对频域进行中心化,这样更便于观察我们的频域图像。最后我们求取了频域的分贝表示的幅值,便于绘制。

image_back = np.fft.ifftshift(dft_shift)image_back = cv2.idft(image_back)image_back = cv2.magnitude(image_back[:, :, 0], image_back[:, :, 1])

接下来,我们直接对傅里叶变换后的数据进行了去中心化,然后利用OpenCV的idft函数进行了傅里叶反变换。之后重新求取反变换后的图像幅值,这样,我们就还原了原来的图像。

rows, cols = image.shapecenter_x, center_y = int(rows/2), int(cols/2)dft_shift[center_x-30:center_x+30, center_y-30:center_y+30] = 0filter_back = np.fft.ifftshift(dft_shift)filter_back = cv2.idft(filter_back)filter_back = cv2.magnitude(filter_back[:, :, 0], filter_back[:, :, 1])

接下来我们更进一步,使用傅里叶变换后的dft_shitf数据,将其中心部分半径为30的频率值置为0。之后同样进行了去中心化和傅里叶反变换,求取幅值后,就得到了滤波后的图像。

plt.subplot(221), plt.imshow(image, 'gray'), plt.title('Origin')plt.subplot(222), plt.imshow(magnitude_spectrum, 'gray'), plt.title('Fourier TransForm')plt.subplot(223), plt.imshow(image_back, 'gray'), plt.title('Origin Back')plt.subplot(224), plt.imshow(filter_back, 'gray'), plt.title('Transform Back')plt.show()

之后绘制了上面的四个图像,结果如下图。



右上角的图像就是频率谱,图像中越亮的部分代表频率幅值越大,上面的代码我们滤除了中心最亮的亮点,实际上就是滤除了最高频的部分,也就是说我们进行了低通滤波。


另外,需要特别说明一下,右下角是低通滤波后的图像,如果放大来看,可以看到振铃现象,这是由于我们使用的频域滤波器有陡峭的边缘,会导致振铃的发生,其数学原理不再赘述,有很多文章进行了说明,可以查阅。



原创粉丝点击