opencv学习笔记22:傅里叶变换,高通滤波,低通滤波

   日期:2020-07-11     浏览:169    评论:0    
核心提示:傅里叶变换原理任何连续的周期信号,都可以由一组适当的正弦曲线组合而成。下列左上图由其他三图构成。左图经过傅里叶变换,由时域图转换到频域图。相互可逆相位:不是同时开始的一组余弦函数,在叠加时要体现刚开始的时间。sin(wx+a)中a是相位numpy实现傅里叶变换numpy.fft.fft2()实现傅里叶变换,返回的是一个复数数组。numpy.fft.fftshift()将零频域分量移到频谱中心白色为fft.fft2得到的低频部分。将低频部分移到中心。20*np.log(np.ab_学习通

傅里叶变换原理

任何连续的周期信号,都可以由一组适当的正弦曲线组合而成。
下列左上图由其他三图构成。

左图经过傅里叶变换,由时域图转换到频域图。相互可逆

相位:不是同时开始的一组余弦函数,在叠加时要体现刚开始的时间。

sin(wx+a)中a是相位

numpy实现傅里叶变换

numpy.fft.fft2()
实现傅里叶变换,返回的是一个复数数组。
numpy.fft.fftshift()
将零频域分量移到频谱中心
白色为fft.fft2得到的低频部分。将低频部分移到中心。

20*np.log(np.abs(fshift))
傅里叶得到有负数数据,重新设置频谱的范围如【0-255】,否则图像无法展示。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('lena.bmp',0)
f = np.fft.fft2(img)@#傅里叶变换
fshift = np.fft.fftshift(f)#移动低频到中间
magnitude_spectrum = 20*np.log(np.abs(fshift))#设置频谱到【0-255】
plt.subplot(121)
plt.imshow(img, cmap = 'gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('result')
plt.axis('off')
plt.show()


傅里叶变换能得到高频,低频信息。针对低频,高频处理能得到不同的目的。

傅里叶变换是可逆的,逆傅里叶变换能得到原始图像。
在频域对图像进行处理后,在频域处理的结果能反映到逆傅里叶变换图像上。

numpy实现逆傅里叶变换

numpy.fft.ifftshift()
numpy.fft.fftshift()的逆操作
numpyfft.ifft2().
逆傅里叶变换
iimg = np.abs(逆傅里叶变换结果)
逆傅里叶变换也有负数,调整至的范围为[0-255}

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('boat.bmp',0)
f = np.fft.fft2(img)#傅里叶变换
fshift = np.fft.fftshift(f)#移动位置
ishift = np.fft.ifftshift(fshift)#逆移动位置
iimg = np.fft.ifft2(ishift)#逆傅里叶变换
print(iimg)
iimg = np.abs(iimg)#取绝对值
print(iimg)
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('iimg'),plt.axis('off')
plt.show()

高通滤波,低通滤波

低频对应图像中变化缓慢的灰度分量,例如在一幅草原图上,低频对应着广袤的颜色趋于一致额草原。
高频对应着图像内变化越来越快的灰度分量,是由灰度的过度尖锐造成的。如对应草原图中狮子的边缘信息。

滤波
接受或者拒绝一定频率的分量
通过低频的滤波器叫低通滤波器
通过高频的滤波器叫高通滤波器
频域滤波
修改傅里叶变换达到特殊目的,然后计算IDFT返回图像域
特殊目的:图像增强,图像去噪,边缘检测,特征提取,压缩,加密等。

低通滤波:衰减高频通低频,会模糊一张图。
高通滤波:衰减低频通高频,增强图像尖锐细节,但是会造成图像对比度下降。

高通滤波numpy实现

高通滤波:将频谱图像的中心的位置区域设置为0(中心部位为低频,之前傅里叶变换将低频移到中心位置啦,由前文得知低频为白色)

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('lena.bmp',0)
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(121),plt.imshow(img, cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('iimg'),plt.axis('off')
plt.show()

opencv实现傅里叶变换

返回结果=cv2.dft(原始图像,转换标识)
返回结果:是双通道的,第一个为结果的实数部分。第二个为结果的虚数部分。
原始图像:要求图像格式是np.float32。得首先转换np.float32(img)
转换标识: 一般使用flags = cv2.DFT_COMPLEX_OUTPUT,输出的是一个复数阵列。
numpy.fft.fftshift(dft)
仍然使用这个将频破谱谱图像低频移到中心位置
返回值=cv2.magnitude(参数1,参数2)
使用这个函数将数值转换到8位数值形式(图像形式)

result = 20*np.log(cv2.magnitude(dftShift[:,:,0],dftShift[:,:,1]))
使用这个将值转换到【0-255】

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('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()

opencv实现逆傅里叶变换

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

cv2.dft()的逆操作.
返回结果:取决于原始数据的类型和大小。
原始数据:实数或者复数均可。

返回值=cv2.magnitude(参数1,参数2)

使用这个将值转换到【0-255】即把这个数值转换到8位数值形式
ishift = np.fft.ifftshift(dftShift)
将中间低频部分,移动会原处。numpy.fft.fftshift(dft)的逆操作

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('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()

低通滤波opencv实现
前面实现了高通滤波
这里实现低通滤波。用opencv。也可以用numpy,参考前面高通滤波numpy实现.
低频是大量细节,高频是边缘。
低通滤波:相当于把下面右图中心部分白色保留,周围黑色舍弃。

实现方法

低通滤波器构造

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('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*mask
#逆傅里叶变换
ishift = np.fft.ifftshift(fShift)#移动中心位低频到原处
iImg = cv2.idft(ishift)#逆傅里叶变换
iImg= cv2.magnitude(iImg[:,:,0],iImg[:,:,1])#将数值变换到8位二进制数值图像格式
#图像显示
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()


总目录链接:
python3+opencv学习笔记汇总目录(适合基础入门学习)
电气专业的计算机小白,写博文不容易。如果你觉得本文不错。请点个赞支持下。谢谢

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服