首先说的是关于图象的傅里叶变化,这个数学概念只有部分工科的专业才学,大家可以自己上网看一下。
傅里叶变化通常用来分析不同滤波器的频率特征,我们使用离散傅里叶变换来分析图形的频域特征。实现DFT的一个快速算法被称为快速傅里叶变换(FFT)。
对于之歌正选信号(那种最普通的,scdn弄不出来公式,大家脑补吧。)她频率为f,如果把这个信号转到它的频域表示,我们会在频率f中看到一个峰值。如果我们的信号是采样产生的离散信号组成,我们会看到类似的频谱图,只不过是离散的。
我们对图象进行x方向和y方向的傅里叶变换,我们会得到这幅图象的频谱图 。
更直观一点,图象中的噪声和边界一般是频谱图中的高频分量,没有这么大幅度的我们称之为低频分量。
这里我先用numpy的函数求出频谱图。这里用到的是numpy的fft模块,提供了快速傅里叶变换的功能,在这个模块里很多函数都存在对应的逆操作。
numpy.fft.fft(a, n=None, axis=-1, norm=None)#计算一维的傅里叶变换
numpy.fft.ifft(a, n=None, axis=-1, norm=None)#上面函数的逆操作
numpy.fft.fft2(a, n=None, axis=-1, norm=None)#计算二维的傅里叶变换
numpy.fft.fftn#计算n维的傅里叶变换
numpy.fft.rfftn#计算n维实数的傅里叶变换
numpy.fft.fftfreq#返回傅里叶变换的采样频率
np.fft.fftshift#将FFT输出中的直流分量移动到频谱的中央
下面就是
import cv2
import numpy as np
import matplotlib.pyplot as plt
img1=cv2.imread('C:/Users/dell/Desktop/00.jpg',0)
f=np.fft.fft2(img1)
fshift=np.fft.fftshift(f)
#之所以要进行对数转换是因为傅里叶变换后的结果对于在显示器显示来讲范围比较大,这样的话对于一些小的变化或者是高的变换值不能进行观察
magnitude_spectrum=20*np.log(np.abs(fshift))
plt.subplot(1,2,1),plt.imshow(img1)
plt.title('input image by numpy'),plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(magnitude_spectrum)
plt.title('magnitude spectrum by numpy'),plt.xticks([]),plt.yticks([])
plt.show()
cv2.dft(src, dst=None, flags=None, nonzeroRows=None)
import cv2
import numpy as np
import matplotlib.pyplot as plt
img1=cv2.imread('C:/Users/dell/Desktop/00.jpg',0)
dft=cv2.dft(np.float32(img1),flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)
magnitude_spectrum=20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
plt.subplot(1,2,1),plt.imshow(img1)
plt.title('input image'),plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(magnitude_spectrum)
plt.title('magnitude spectrum'),plt.xticks([]),plt.yticks([])
plt.show()
我们要在画出频谱图的基础上对图象在频域上进行操作,然后在傅里叶逆变换回去。第一个了解的是高通滤波去除低频部分,通常可以求出边界来
import cv2
import numpy as np
import matplotlib.pyplot as plt
img1=cv2.imread('C:/Users/dell/Desktop/00.jpg',0)
f=np.fft.fft2(img1)
fshift=np.fft.fftshift(f)
rows,cols=img1.shape
crow,ccol=np.ceil(rows/2),np.ceil(cols/2)
crow,ccol=np.int(crow),np.int(ccol)
#注意fshift是用来与原图像进行掩模操作的但是具体的,我也看着很抽象。这一部分与低通的有些相对的意思。
fshift[crow-30:crow+30,ccol-30:ccol+30]=0
f_ishift=np.fft.ifftshift(fshift)
img_back=np.fft.ifft2(fshift)
img_back=np.abs(img_back)
plt.subplot(1,2,1),plt.imshow(img1)
plt.title('input image'),plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(img_back)
plt.title('image after HPF'),plt.xticks([]),plt.yticks([])
plt.show()
接下来我们实现的是低通滤波将gapin部分除去,实际上就是对图象进行模糊操作。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img1=cv2.imread('C:/Users/dell/Desktop/00.jpg',0)
dft=cv2.dft(np.float32(img1),flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)
magnitude_spectrum=20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
rows,cols=img1.shape
#下面有对数据的取整还有数据类型转换的操作,否则mask会出问题
crow,ccol=np.ceil(rows/2),np.ceil(cols/2)
crow,ccol=np.int(crow),np.int(ccol)
mask=np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30,ccol-30:ccol+30]=1
fshift=dft_shift*mask
f_ishift=np.fft.ifftshift(fshift)
img_back=cv2.idft(f_ishift)
img_back=cv2.magnitude(img_back[:,:,0],img_back[:,:,1])
plt.subplot(1,2,1),plt.imshow(img1)
plt.title('input image'),plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(img_back)
plt.title('magnitude spectrum'),plt.xticks([]),plt.yticks([])
plt.show()