图像的傅里叶变换(一)+https://developer.aliyun.com/article/1385010
对于这个掩膜我们这样做:
rows, cols = img.shape crow,ccol = int(rows/2) , int(cols/2) fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
具体代码是:
import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('image\\boat.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实现
对于OpenCV中的傅里叶变换函数是:返回结果=cv2.dft(原始图像,转换标识)
返回结果是双通道的,第一个是实数部分,第二个通道是虚数部分。
输入图像要首先转换成np.float32 格式, np.float32(img)
flags = cv2.DFT_COMPLEX_OUTPUT,输出一个复数阵列
移动频谱部分和numpy一致,是这样的,numpy.fft.fftshift,然后进行返回值=cv2.magnitude(参数1,参数2)这里参数1就是实数部分,参数2就是虚数部分,并且进行𝑑𝑠𝑡 𝐼 = 根号𝑥(𝐼)2 + 𝑦(𝐼)2操作。
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()
得到的图像和numpy一致。
傅里叶OpenCV逆变换实现
对于傅里叶变换的逆操作,使用OpenCV的函数就是返回结果=cv2.idft(原始数据)
,然后计算幅度函数仍然是返回值=cv2.magnitude(参数1,参数2)
,numpy.fft.ifftshift.
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()
频域的低通滤波
我们这里的想法就是:
自己构建一个低通滤波器,把中间位置设置成255,其余部分为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
低通滤波器构建代码。
然后我们完整代码就是:
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*mask ishift = 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('inverse'), plt.axis('off') plt.show()
傅里叶变换有什么应用场景
傅里叶变换可以将一个时域信号转换成在不同频率下对应的振幅及相位,其频谱就是时域信号在频域下的表现,而反傅里叶变换可以将频谱再转换回时域的信号。最简单最直接的应用就是时频域转换,比如在移动通信的LTE系统中,要把接收的信号从时域变成频域,就需要使用FFT(快速傅里叶变换)。又例如对一个采集到的声音做傅立叶变化就能分出好几个频率的信号。比如南非世界杯时,南非人吹的呜呜主拉的声音太吵了,那么对现场的音频做傅立叶变化(当然是对声音的数据做),会得到一个展开式,然后找出呜呜主拉的特征频率,去掉展开式中的那个频率的sin函数,再还原数据,就得到了没有呜呜主拉的嗡嗡声的现场声音。而对图片的数据做傅立叶,然后增大高频信号的系数就可以提高图像的对比度。同样,相机自动对焦就是通过找图像的高频分量最大的时候,就是对好了。
傅里叶变换matlab实现
[i,lcmp]=imread('F:/123.jpg');%=======读取图像 显示图像 subplot(2,2,1),imshow(i,lcmp); title('original'); ii=im2double(i); %=====将图像矩阵类型转换为double(图像计算很多是不能用整型的),没有这个会报错!! ,如果不用这个就必须转化为灰度图! i1 = fft2(ii); %======傅里叶变换 i2 =fftshift(i1); %======将变换的频率图像四角移动到中心(原来良的部分在四角 现在移动中心,便于后面的处理) i3=log(abs(i2)); %=====显示中心低频部分,加对数是为了更好的显示 subplot(2,2,2),imshow(i3,[]); title('Fourier'); map=colormap(lcmp); %===取色谱 imwrite(i3,map,'f:/ffttank.bmp'); %===将上面i3输入到ffttank文件中 i5 = real(ifft2(ifftshift(i2))); %===频域的图反变换到空域 并取实部 i6 = im2uint8(mat2gray(i5)); %===取其灰度图 imwrite(i6,map,'f:/tank2.bmp','bmp'); %===利用灰度图和原来取得颜色模板 还原图像 subplot(2,2,3),imshow(i6); title('anti-Fourier'); i7=rgb2gray(i); i8=fft2(i7);%===对灰色图才能归一化。因为那是2维矩阵,彩色图是3维矩阵,需要转化为2维灰图 m=fftshift(i8); %直流分量移到频谱中心 %RR=real(m); %取傅立叶变换的实部 %II=imag(m); %取傅立叶变换的虚部 A=abs(m);%计算频谱幅值 %A=sqrt(RR.^2+II.^2); A=(A-min(min(A)))/(max(max(A))-min(min(A)))*225; %归一化 subplot(2,2,4),imshow(A); %显示原图像 colorbar; %显示图像的颜色条 title('FFT spectrum'); %图像命名
如果觉得博主的文章还不错或者您用得到的话,可以免费的关注一下博主,如果三连收藏支持就更好啦!这就是给予我最大的支持!