数字图像处理第三章——频域处理(中)

数字图像处理—频域处理

(四)从空域滤波器获得频域滤波器

通常,当滤波器较小时,使用空域滤波要比频域滤波在计算上更有效。 “小”的定义是很复杂的问题,答案取决于很多因素,比如使用的机器和算法、缓冲区的大小、所处理数据的复杂度等。空域是指图像平面本身,空域滤波这类方法直接对图像的像素进行处理。频域滤波是变换域滤波的一种,它是指将图像进行变换后(频域是指经过傅里叶变换之后),在变换域中对图像的变换系数进行处理(滤波),处理完毕后再进行逆变换,获得滤波后的图像。

下面我们来进行空域和频域滤波器的比较,编码分析,详细步骤在代码注释:

1 空域滤波器
使用空域模板进行的图像处理,被称为空域滤波。模板本身被称为空域滤波器。

代码编写:

g = imread('D:\数字图像处理\第三章学习\blackhole.png');
f = im2double(rgb2gray(g));    %把图像变为灰度图像
h = fspecial('sobel');         %使用 fspecial 生成空域滤波器
figure;
freqz2(h);                     %查看sobel算子的频域响应图形
gs = imfilter(f,h);            %生成滤波图
figure;
subplot(1, 3, 1), imshow(g), title('原图像');
subplot(1, 3, 2), imshow(f), title('原图像的灰度图像');
subplot(1, 3, 3), imshow(gs,[]), title('空域滤波图像');

代码运行效果如下:

在这里插入图片描述
频域滤波器

频域滤波是在频率域对图像做处理的一种方法。滤波器大小和频谱大小相同,相乘即可得到新的频谱。滤波后结果显示,低通滤波去掉了高频信息,即细节信息,留下的低频信息代表了概貌。

代码编写:

%从空间域中获得频域滤波器,
g = imread('D:\数字图像处理\第三章学习\blackhole.png');
f = im2double(rgb2gray(g));    %把图像变为灰度图像
h = fspecial('sobel');         %生成垂直sobel掩膜
PQ=paddedsize(size(f));        %获取填充尺寸
H=freqz2(h,PQ(1),PQ(2));       %获得sobel算子的频域响应
H1=ifftshift(H);               %重排数据序列,以使频域变换的原点位于频率矩形的左上角(因为freqz2产生的频域响应原点默认在频率矩形中心!)
gs = imfilter(f,h);            %空域滤波图像
gf=dftfilt(f,H1);              %采用默认值 0 填充边缘,频率域滤波函数,第一个参数为原始图像,后者为二维频率域滤器
figure;
subplot(2, 2, 1), imshow(g), title('原图像');
subplot(2, 2, 2), imshow(f), title('原图像的灰度图像');
subplot(2, 2, 3), imshow(gs ,[]), title('空域处理的滤波图像');
subplot(2, 2, 4), imshow(gf ,[]), title('频域处理的滤波图像');
figure;
subplot(1, 2, 1),imshow(abs(gs) ,[]), title('空域处理的滤波图像绝对值'); 
subplot(1, 2, 2),imshow(abs(gf) ,[]), title('频域处理的滤波图像绝对值');
figure;
subplot(1, 2, 1),freqz2(H), title('透视图H'); 
subplot(1, 2, 2),freqz2(H1), title('ifftshift 重排后透视图H1');
figure;
subplot(1, 2, 1), imshow(abs(H), [ ]), title('以图像形式显示H的绝对值');
subplot(1, 2, 2), imshow(abs(H1), [ ]), title('以图像形式显示H1的绝对值');

图像运行效果如下:



代码运行效果显示空域处理与频域处理图像显示一样,我们再通过计算它们的差别来证实这个事实:

d = abs(gs - gf);

最大差别为:
在这里插入图片描述
在现有应用中可以忽略。

最小差别是:
在这里插入图片描述
实验结论:可看见,差异很小。产生原因:频域操作中FFT和IFT中由于复数的存在产生的舍入误差(空域操作中不产生复数)。故结论:使用空间域滤波和频域滤波得到的图像对所有实用目的来说,都是相同的。

(五)在频域中直接生成滤波器

5.1 建立网格数组以实现频域滤波器

对于 M-函数最主要的是:需要在频率矩形中计算任意点到规定点的距离函数。称为dftuv的M-函数提供了距离计算以及其他类似应用所需要的网格数组。由 dftuv 生成的网格数组已经满足 fft2 和 ifft2 处理的需要,不需要数据重排。

dftuv 源码:

function [U, V] = dftuv(M, N) 
u = single(0:(M - 1)); 
v = single(0:(N - 1));
idx =  find(u > M/2}; 
u(idx) = u(idx) - M; 
idy = find(v > N/2); v(idy) = v(idy) - N;
[V, U] == meshgrid(v, u);

举例说明函数 dftuv的使用:

计算 8x5 大小的矩形上每一点到矩形原点距离的平方:

代码编写:

[U, V] = dftuv(8, 5);
DSQ = U.^2 + V.^2;

运行效果如下:

注意:距离在左上角是0,最大距离位置在频域矩形中心。可以使用函数 fftshift 来获得关于频域矩形中心的距离:

现在,距离为 0的点的坐标为(5, 3),数组关于这一点对称。

5.2 频域低通(平滑)滤波器

理想低通滤波器(ILPF)具有如下传递函数:
在这里插入图片描述
其中, D 0 D_0 为正数,D(u,v)为点(u,v)到滤波器 中心的距离。满足的点的轨迹为圆。 因为滤波器H(u,v)乘以一幅图像的傅立叶变换,我们看到理想滤波器切断(乘以0)圆外的所有 F(u,v)分量,而保留圆上和圆内的点不变(乘以 1)。虽然这个滤波器不能用类似的电子元件实现, 但的确可以在计算机中用前面介绍的传递函数实现。理想滤波器的特性通常用来解释振铃和折叠误差等现象。 图像处理中,对一幅图像进行滤波处理,若选用的频域滤波器具有陡峭的变化,则会使滤波图像产生“振铃”,所谓“振铃”,就是指输出图像的灰度剧烈变化处产生的震荡,就好像钟被敲击后产生的空气震荡。

现在对图像进行理想低通滤波:

编写代码:

X=imread('D:\数字图像处理\第三章学习\blackhole.png');
I1=X;
f=double(I1);
g=fft2(f);
g=fftshift(g);    %傅立叶变换
[N1,N2]=size(g);  %转换数据矩阵
n=1;
d0=30;            %可以通过修改d0来决定过滤掉多少高频,从而查看不同的理想低通的效果
n1=fix(N1/2);
n2=fix(N2/2);
for i=1:N1;
for j=1:N2;
    d=sqrt((i-n1)^2+(j-n2)^2);
if d>d0           %距离频域中心距离超过d0的都被完全过滤,体现理想低通
 h=0; 
else
  h=1; 
end
 result(i,j)=h*g(i,j); %这里是相乘,不是卷积
end
end
result=ifftshift(result);
X2=ifft2(result);
figure;
subplot(1,2,1),imshow(I1,[]),title('原图像');
subplot(1,2,2),imshow(real(X2),[]),title('截断频率d0=30的理想低通滤波结果');%存在振铃效应

代码运行效果如下:

n阶的布特沃斯低通滤波器(BLPF), 具有从滤波器中心到 A) 的距离的截止频率,传递函数为:
在这里插入图片描述
与理想低通滤波器不同,布特沃斯低通滤波器的传递函数在 A) 点没有尖锐的不连续。

现在对图像进行布特沃斯低通滤波:

编写代码:

I1=imread('D:\数字图像处理\第三章学习\blackhole.png');
f=double(I1);                %数据类型转换
g=fft2(f);                   %图像傅里叶转换
g=fftshift(g);               %傅里叶变换平移
F2=log(abs(g));              %对傅里叶变换结果取绝对值,然后取对数
[N1,N2]=size(g);             %傅里叶变换图像尺寸
n=2;                         %参数赋初始值
d0=5;
n1=fix(N1/2);                %数据圆整
n2=fix(N2/2);                %数据圆整
for i=1:N1                   %遍历图像像素
for j=1:N2 
d=sqrt((i-n1)^2+(j-n2)^2);
if d==0
h=0;
else
h=1/(1+(d/d0)^(2*n));
end
result(i,j)=h*g(i,j);         %图像矩阵计算处理
end
end
result=ifftshift(result);
X2=ifft2(result);
X3=uint8(real(X2));
subplot(1,2,1),imshow(I1),title('原图像');
subplot(1,2,2),imshow(X3),title('Butterworth低通滤波图像');


代码运行效果如下:

滤波器就是建立的一个数学模型,通过这个模型来将图像数据进行能量转化,噪声就是属于高频率部分,高斯滤波器平滑处理后降低噪声的影响。若使用理想滤波器,会在图像中产生振铃现象。采用高斯滤波器的话,系统函数是平滑的,避免了振铃现象。它的特性是连续性衰减,而不像理想滤波器那样陡峭变化,即明显的不连续性。因此采用该滤波器滤波在抑制噪声的同时,图像边缘的模糊程度大大减小,没有振铃效应产生。 可用于平滑处理,如图像由于量化不足产生虚假轮廓时,常可用低通滤波进行平滑以改进图像质量。传递函数由下式给出:

在这里插入图片描述
现在对图像进行高斯低通滤波:

编写代码:

w = imread('D:\数字图像处理\第三章学习\blackhole.png');
f = im2double(rgb2gray(w));    %把图像变为灰度图像
PQ = paddedsize(size(f));      %产生滤波时所需大小的矩阵
[U, V] = dftuv(PQ(1),PQ(2)); 
DO = 0.05*PQ(2);               %设定高斯滤波器的阈值
F = fft2(f, PQ(1), PQ(2));     %傅里叶变换
H = exp(-(U.^2+V.^2)/(2*(DO^2))); 
g = dftfilt(f,H);              %用滤波器对图像进行频域滤波
figure;
subplot(2, 2, 1), imshow(w), title('原图像');
subplot(2, 2, 2), imshow(fftshift(H),[]), title('以图像显示的高斯低通滤波器');
subplot(2, 2, 3), imshow(log(1 + abs(fftshift(F))),[]), title('对数增强并居中的fft');
subplot(2, 2, 4), imshow(g,[]), title('高斯低通滤波后的图像的谱');

三个滤波器分别在空域和频域进行对比:

代码编写:

d0=8;
M=60;N=60;
c1=floor(M/2);     
c2=floor(N/2);      
h1=zeros(M,N);      %理想低通滤波
h2=zeros(M,N);      %布特沃斯滤波
h3=zeros(M,N);      %高斯滤波
sigma=4;
n=4;%布特沃斯阶数
for i=1:M
    for j=1:N
        d=sqrt((i-c1)^2+(j-c2)^2);
        if d<=d0
            h1(i,j)=1;
        else
            h1(i,j)=0;
        end
        h2(i,j)=1/(1+(d/d0)^(2*n)); 
        h3(i,j)=exp(-d^2/(2*sigma^2)); 
    end
end
draw2(h1,'理想低通滤波器');
draw2(h2,'布特沃斯滤波器');
draw2(h3,'高斯低通滤波器');
 
function draw2(h,name)
figure;
surf(h);title(strcat('频域',name));
fx=abs(ifft2(h));
fx=fftshift(fx);
figure;surf(fx);title(strcat('空域',name));
end

代码运行效果如下:


实验结论:

理想滤波器有振铃现象发生,可以看出空域滤波函数图像外围有剧烈震荡,平滑效果较为粗糙;布特沃斯滤波器几乎没有振铃现象,图像较理想滤波器而言平滑效果也比较好,高斯滤波器没有振铃现象,其平滑效果是三者最好的。

5.3 线框及表面绘制

要画 MxN大小的二维函数 H 的线框图,最容易的方法是使用函数 mesh。

编写代码:

H = fftshift(lpfilter('gaussian', 500, 500, 50)); 
mesh(double(H(1:10:500, 1:10:500)));
axis tight;

代码运行效果如下:

线框图默认为彩色的,从底部为蓝色渐变到顶部为红色。通 过键入下面的命令,可以把绘图的线条变为黑色,并消除轴和栅格:

编写代码:

H = fftshift(lpfilter('gaussian', 500, 500, 50)); 
mesh(double(H(1:10:500, 1:10:500)));
colormap ( [0 0 0] );   %把绘图的线条变为黑色,
axis off ;      %消除轴
grid off ;      %消除栅格

代码运行效果如下:

将观察者稍微向右移,并保持仰角不变。view(az, el),az 和 el 分别代表方位角和仰角(以度表示)。默认值 是 az=-37.5,el=30。
在这里插入图片描述

编写代码:

H = fftshift(lpfilter('gaussian', 500, 500, 50)); 
mesh(double(H(1:10:500, 1:10:500)));
view (-25, 30);

代码运行效果如下:

保持方位角为-25 并将仰角设置为 0之后,
编写代码:

H = fftshift(lpfilter('gaussian', 500, 500, 50)); 
mesh(double(H(1:10:500, 1:10:500)));
view (-25, 0 );

代码运行效果如下:

有时候,需要能以表面图代替线框图的绘制函数。函数surf 可做这件事。

代码编写:

H = fftshift(lpfilter('gaussian', 500, 500, 50)); 
surf(double(H(1:10:500, 1:10:500)));
axis tight;
colormap(gray);   %将颜色转为灰度
axis off;

代码运行效果如下:

运行下面代码平滑小面描影和消除栅网线:

代码编写:

H = fftshift(lpfilter('gaussian', 500, 500, 50)); 
surf(double(H(1:10:500, 1:10:500)));
axis tight;
colormap(gray);
axis off;
shading interp;    %平滑小面描影和消除栅网线

代码运行效果如下:

如果目的是绘制含有两个变量的解析函数,就用 meshgrid 产生坐标值,并从这些坐标值 中产生将在 mesh 或 surf 中使用的离散(抽样)矩阵。

代码编写:

H = fftshift(lpfilter('gaussian', 500, 500, 50)); 
[Y, X] = meshgrid(-2:0.1:2, -2:0.1:2); 
Z = X.*exp(-X.^2 - Y.^2); 
surf(Z);
axis tight;

代码运行效果如下:

代码编写:

H = fftshift(lpfilter('gaussian', 500, 500, 50)); 
[Y, X] = meshgrid(-2:0.1:2, -2:0.1:2); 
Z = X.*exp(-X.^2 - Y.^2); 
mesh(Z);
axis tight;

代码运行效果如下:

猜你喜欢

转载自blog.csdn.net/Dujing2019/article/details/89204136