MATLAB图像处理学习笔记(一):频域滤波
记录一下基本的课程实验。
一、空域转换为频域
通过傅里叶变换得到图像的频谱图:
img = imread('1.jpg');
figure;
imshow(img);
title('原图');
f=rgb2gray(img);
F=fft2(f); %傅里叶变换
F1=log(abs(F)+1);
Fs=fftshift(F); %将频谱图中零频率移动到图像中心
S=log(abs(Fs)+1);
figure;
imshow(S,[]);title('频谱');
上面的代码中有一行:
S=log(abs(Fs)+1);
这行代码的目的是将Fs取模并进行缩放,因为原来的Fs是一个复数矩阵,所以Fs是不能直接被imshow函数调用的(虽然说imshow会自动选择只显示Fs的实部部分),另外,如果不将Fs的实部缩放到一般灰度图的取值范围(0 - 255),显示效果会十分感人,这个自己去试一试就知道了。这一步是为了显示才进行的,运算的时候还是用Fs进行操作。
二、自定义滤波窗口
以低通滤波为例,简单的来说,越靠近频谱图的中央一带,其所对应的信号频率就越低;反之,越靠近频谱图的边缘,对应的信号频率就越高。为了实现低通滤波,可以将频谱图中央一带的信号保留下来,然后去除频谱图边缘的高频信号。
filter_low = zeros(400, 600);
r = 50;
for i=(400/2-r+1):(400/2+r)
for j=(600/2-r+1):(600/2+r)
filter_low(i,j)=1;
end
end
figure;
imshow(filter_low,[]);
title('低通滤波窗口');
由于之后要进行点乘操作,所以这个filter_low矩阵的大小要和原图像一致。
dst = filter_low.* Fs;
figure;
S2=log(abs(dst)+1); %取模并进行缩放
imshow(S2,[]);
title('经过滤波后的频谱图');
点乘后的图像长这样:
最后进行傅里叶逆变换:
fr=real(ifft2(ifftshift(dst))); %频率域反变换到空间域,并取实部
ret=im2uint8(mat2gray(fr)); %更改图像类型
figure;
imshow(ret);
title('低通滤波结果');
得到的最终结果为:
如果想对彩色图像进行滤波的话,在导入图像以后不进行灰度处理就行了。
同理还可以设计对应的高通、带通、带阻滤波窗口。
整体代码:
img = imread('1.jpg');
figure;
imshow(img);
title('原图');
f=img;
F=fft2(f);
F1=log(abs(F)+1);
%subplot(2,2,2);imshow(F1,[]);title('傅里叶变换频谱图');
Fs=fftshift(F);
S=log(abs(Fs)+1);
figure;
imshow(S,[]);
title('频谱');
filter_low = zeros(400, 600);
r = 50;
for i=(400/2-r+1):(400/2+r)
for j=(600/2-r+1):(600/2+r)
filter_low(i,j)=1;
end
end
figure;
imshow(filter_low,[]);
title('低通滤波窗口');
dst = filter_low.* Fs;
figure;
S2=log(abs(dst)+1);
imshow(S2,[]);
title('经过滤波后的频谱图');
fr=real(ifft2(ifftshift(dst)));
ret=im2uint8(mat2gray(fr));
figure;
imshow(ret);
title('低通滤波结果');