win10+Python3.7.3+OpenCV3.4.1入门学习(十四 傅里叶变换)————14.3 OpenCV实现傅里叶变换
Python版本是Python3.7.3,OpenCV版本OpenCV3.4.1,开发环境为PyCharm
文章目录
14.3 OpenCV实现傅里叶变换
OpenCV提供了函数cv2.dft()和cv2.idft()来实现傅里叶变换和逆傅里叶变换,下面分别展开介绍。
14.3.1 实现傅里叶变换
函数cv2.dft()的语法格式为:
返回结果=cv2.dft(原始图像,转换标识)
在使用该函数时,需要注意参数的使用规范:
● 对于参数“原始图像”,要首先使用np.float32()函数将图像转换成np.float32格式。
● “转换标识”的值通常为“cv2.DFT_COMPLEX_OUTPUT”,用来输出一个复数阵列。
函数cv2.dft()返回的结果与使用Numpy进行傅里叶变换得到的结果是一致的,但是它返回的值是双通道的,第1个通道是结果的实数部分,第2个通道是结果的虚数部分。
经过函数cv2.dft()的变换后,我们得到了原始图像的频谱信息。此时,零频率分量并不在中心位置,为了处理方便需要将其移至中心位置,可以用函数numpy.fft.fftshift()实现。例如,如下语句将频谱图像dft中的零频率分量移到频谱中心,得到了零频率分量位于中心的频谱图像dftshift。
dftShift = np.fft.fftshift(dft)
经过上述处理后,频谱图像还只是一个由实部和虚部构成的值。要将其显示出来,还要做进一步的处理才行。
函数cv2.magnitude()可以计算频谱信息的幅度。该函数的语法格式为:
返回值=cv2.magnitude(参数1,参数2)
式中两个参数的含义如下:
● 参数1:浮点型x坐标值,也就是实部。
● 参数2:浮点型y坐标值,也就是虚部,它必须和参数1具有相同的大小(size值的大小,不是value值的大小)。
函数cv2.magnitude()的返回值是参数1和参数2的平方和的平方根,公式为:
式中,I 表示原始图像,dst 表示目标图像。
得到频谱信息的幅度后,通常还要对幅度值做进一步的转换,以便将频谱信息以图像的形式展示出来。简单来说,就是需要将幅度值映射到灰度图像的灰度空间[0, 255]内,使其以灰度图像的形式显示出来。
这里使用的公式为:
result = 20*np.log(cv2.magnitude(实部,虚部))
下面对一幅图像进行傅里叶变换。如下代码针对图像“lena”进行傅里叶变换,并且计算了幅度值,对幅度值进行了规范化处理:
import numpy as np import cv2 img = cv2.imread('image\\lena.bmp', 0) dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT) print(dft) dftShift = np.fft.fftshift(dft)print(dftShift) result = 20 * np.log(cv2.magnitude(dftShift[:, :, 0], dftShift[:, :, 1])) print(result)
得到的值范围分别如下图所示。其中:
● 图( a )显示的是函数cv2.dft()得到的频谱值,该值是由实部和虚部构成的。
● 间( b )的图显示的是函数cv2.magnitude()计算得到的频谱幅度值,这些值不在标准的图像灰度空间[0, 255]内。
● 图( c )显示的是对函数cv2.magnitude()计算得到的频谱幅度值进一步规范的结果,现在值的范围在[0, 255]内。
eg1:用OpenCV函数对图像进行傅里叶变换,并展示其频谱信息。
:代码如下:
import numpy as np import cv2 import matplotlib.pyplot as plt img = cv2.imread('image\\lena.bmp',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()
运行上述代码后,得到如下图所示的结果。其中:
● 左图是原始图像。
● 右图是频谱图像,是使用函数np.fft.fftshift()将零频率分量移至频谱图像中心位置的结果。
14.3.2 实现逆傅里叶变换
在OpenCV中,使用函数cv2.idft()实现逆傅里叶变换,该函数是傅里叶变换函数cv2.dft()的逆函数。其语法格式为:
返回结果=cv2.idft(原始数据)
对图像进行傅里叶变换后,通常会将零频率分量移至频谱图像的中心位置。如果使用函数numpy.fft.fftshift()移动了零频率分量,那么在进行逆傅里叶变换前,要使用函数numpy.fft.ifftshift()将零频率分量恢复到原来位置。
还要注意,在进行逆傅里叶变换后,得到的值仍旧是复数,需要使用函数cv2.magnitude()计算其幅度。
eg2:用OpenCV函数对图像进行傅里叶变换、逆傅里叶变换,并展示原始图像及经过逆傅里叶变换后得到的图像。
代码如下:
import numpy as np import cv2 import matplotlib.pyplot as plt img = cv2.imread('image\\lena.bmp',0) 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(121),plt.imshow(img, cmap = 'gray') plt.title('original'), plt.axis('off') plt.subplot(122),plt.imshow(iImg, cmap = 'gray') plt.title('inverse'), plt.axis('off') plt.show()
运行上述代码后,得到如下图所示的结果。其中:
● 左图是原始图像img。
● 右图是对原始图像img进行傅里叶变换、逆傅里叶变换后得到的图像。
14.3.3 低通滤波示例
前面讲过,在一幅图像内,低频信号对应图像内变化缓慢的灰度分量。例如,在一幅大草原的图像中,低频信号对应着颜色趋于一致的广袤草原。低通滤波器让高频信号衰减而让低频信号通过,图像进行低通滤波后会变模糊。
例如,在下图中,左图original是原始图像,中间的图像result是对original进行傅里叶变换后得到的结果,右图是低通滤波后的图像。将傅里叶变换结果图像result中的高频信号值都替换为0(处理为黑色),就屏蔽了高频信号,只保留低频信号,从而实现了低通滤波。
在实现低通滤波时,可以专门构造一个如下图中左图所示的图像,用它与原图的傅里叶变换频谱图像进行与运算,就能将频谱图像中的高频信号过滤掉。
对于图中的左图,可以采用如下方式构造:
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
eg3:使用函数cv2.dft()对图像进行傅里叶变换,得到其频谱图像。然后,在频域内将其高频分量的值处理为0,实现低通滤波。最后,对图像进行逆傅里叶变换,得到恢复的原始图像。观察傅里叶变换前后图像的差异。
代码如下:
import numpy as np import cv2 import matplotlib.pyplot as plt img = cv2.imread('image\\lena.bmp',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*maskishift = np.fft.ifftshift(fShift) iImg = cv2.idft(ishift) iImg= cv2.magnitude(iImg[:,:,0],iImg[:,:,1]) plt.subplot(121),plt.imshow(img, cmap = 'gray') plt.title('original'), plt.axis('off') plt.subplot(122),plt.imshow(iImg, cmap = 'gray') plt.title('result'), plt.axis('off') plt.show()
运行上述代码,得到如下图所示的结果,左图为原始图像,右图为变换后的图像。可以看到,经过低通滤波后,图像的边缘信息被削弱了。
- 点赞
- 收藏
- 分享
- 文章举报
- Python OpenCV学习笔记之:图像直方图反向投影(backprojection)原理简单实现
- opencv-python 学习笔记2:实现目光跟随(又叫人脸跟随)
- 学习《深度学习入门:基于Python的理论与实现》高清中文版PDF+源代码
- opencv_python学习笔记十四
- 零基础入门学习Python(10)--列表:一个打了激素的数组
- 深度学习入门书籍推荐:《深度学习入门:基于Python的理论与实现》高清中文版PDF+源代码)
- Python 实现 CNKI批量下载 和FireFox Extension 入门学习笔记
- 深度学习入门---PCA,白化 Python实现
- python实现 opencv 学习笔记 图像二值化
- Python入门学习笔记————10 (oop)
- python实现opencv学习一:安装、环境配置、工具
- 深度学习入门基于python的理论与实现
- 11.python并发入门(part10 多进程之间实现通信,以及进程之间的数据共享)
- python opencv入门(学习笔记no.2)-视频的读入读出
- Win10+Python3.6.3(Anaconda3)+OpenCV3.2.0安装配置
- python OpenCV学习笔记实现二维直方图
- opencv-python学习之入门篇(一)实时追踪蓝色物体
- 《深度学习入门:基于Python的理论与实现》高清中文版PDF+源代码
- 逻辑回归(高效2分类)-基于opencv和python的学习笔记(十四)
- 《深度学习入门:基于Python的理论与实现》学习与总结(一)