任何连续的周期信号,都可以由一组适当的正弦曲线组合而成。
下列左上图由其他三图构成。
左图经过傅里叶变换,由时域图转换到频域图。相互可逆
相位:不是同时开始的一组余弦函数,在叠加时要体现刚开始的时间。
sin(wx+a)中a是相位
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.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()
返回结果=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()
返回结果=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学习笔记汇总目录(适合基础入门学习)
电气专业的计算机小白,写博文不容易。如果你觉得本文不错。请点个赞支持下。谢谢