高通巴特沃斯滤波器在MATLAB中对图像进行滤波

时间:2015-05-16 16:41:04

标签: image matlab image-processing filtering signal-processing

我需要在MATLAB中实现一个高通Butterworth滤波器,用于图像滤波。我已经实现了一个,但看起来它不起作用。这是我写的代码。有谁能告诉我出了什么问题?

$t_slot_times

2 个答案:

答案 0 :(得分:11)

首先,没有名为ifftshow的命令。其次,你没有过滤任何东西。您所做的只是可视化图像的光谱。

在可视化频谱方面,您现在如何做到这一点非常危险。首先,您可视化每个空间频率分量的系数,其本质上是复值。如果您希望以对我们大多数人有意义的方式可视化频谱,那么最好先了解幅度阶段。但是,因为这是Butterworth滤波器,所以最好将其应用于滤波器的大小。

您可以使用abs函数找到频谱的幅度。即使你这样做,如果你直接对量值进行了imshow,那么除了之外,你将得到一个零>的可视化。这是因为直流分量太大,而其余光谱相比较小。

让我举个例子。这是摄像师图像,它是图像处理工具箱的一部分:

im = imread('cameraman.tif');
figure;
imshow(im);

enter image description here

现在,让我们可视化光谱并确保DC组件位于图像的中心 - 您已使用fftshift执行此操作。 将图像投射到double 以确保数据的最佳精确度也是一个好主意。此外,请务必使用abs来查找幅度:

fftim = fftshift(fft2(double(im)));
mag = abs(fftim);
figure;
imshow(mag, []);

enter image description here

正如您所看到的,由于我提到的原因,它并不是非常有用。可视化图像光谱的更好方法通常是对光谱应用 log 变换。如果您想要取消平均值或删除平均值以使动态范围更适合显示,这也很有用。换句话说,您可以将1加到幅度上,然后将对数应用于幅度,以便更高的值可以逐渐减小。使用哪个基数并不重要,所以我只使用log命令封装的自然对数:

figure;
imshow(log(1 + mag), []);

enter image description here

现在更多更好了。现在我们将介绍您的过滤机制。您的巴特沃斯滤波器略有不正确。 meshgrid坐标略有错误。在结束时间间隔的-1操作需要到外面:

[x y]=meshgrid(-floor(w/2):floor(w/2)-1,-floor(h/2):floor(h/2)-1);

请记住,您正在定义关于图像中心的对称间隔,而您最初所做的并不正确。我还想提一下,这看起来像是一个高通滤波器,因此输出应该看起来像边缘检测。此外,Butterworth高通滤波器的定义不正确。频域中滤波器的正确定义是:

enter image description here

D(u,v)是频域中距图像中心的距离,Do是截止距离,而B是控制所需增益的控制比例因子。截止距离。 n是过滤器的顺序。在您的情况下,Dod = 50。在实践中,B = sqrt(2) - 1使得在DoD(u,v) = 1 / sqrt(2) = 0.707的截止距离处,这是在电子电路滤波器中最常见的3dB截止频率。有时,为了简单起见,您会将B设置为1,但将此设置为B = sqrt(2) - 1会很常见。

但是,您当前的代码不进行任何过滤。要在频域中进行滤波,只需将图像的频谱与滤波器本身的频谱相乘即可。这相当于空间域中的卷积。完成后,您只需撤消对图像执行的fftshift,进行逆FFT,然后消除由于数值不精确而导致的任何虚部。另外,让我们转发uint8以确保我们尊重原始图片类型。

可以这样做:

%// Your code with meshgrid fix
n=1;
d=50;
h=size(im,1);
w=size(im,2);
fftim = fftshift(fft2(double(im)));
[x y]=meshgrid(-floor(w/2):floor(w/2)-1,-floor(h/2):floor(h/2)-1);
%hhp=(1./(d./(x.^2+y.^2).^0.5).^(2*n));

%%%%%%// New code
B = sqrt(2) - 1; %// Define B
D = sqrt(x.^2 + y.^2); %// Define distance to centre
hhp = 1 ./ (1 + B * ((d ./ D).^(2 * n)));
out_spec_centre = fftim .* hhp;

%// Uncentre spectrum
out_spec = ifftshift(out_spec_centre);

%// Inverse FFT, get real components, and cast
out = uint8(real(ifft2(out_spec)));

%// Show image
imshow(out);

如果您想查看滤波后的频谱,请执行以下操作:

figure;
imshow(log(1 + abs(out_spec_centre)), []);

我们得到:

enter image description here

这是有道理的。您可以看到,在光谱的中间,与光谱的外边缘相比,它稍微更暗。这是因为使用高通巴特沃斯滤波器,您可以放大更高频率的项,并且可视化为更高的强度。

现在,out包含您的过滤图片,我们终于明白了:

enter image description here

这看起来很不错!但是,天真地将图像转换为uint8会将任何负值截断为0,将任何正值大于255到255.因为这是边缘检测,您需要检测负转换和正转换...所以a好的想法是规范化输出,使其范围从[0,1],然后在乘以255后使用uint8进行转换。这样,图像中没有任何变化可视化为灰色,负面变化可视化为黑暗,正面变化可视化为白色......所以你做了类似这样的事情:

%// Your code with meshgrid fix
n=1;
d=50;
h=size(im,1);
w=size(im,2);
fftim = fftshift(fft2(double(im)));
[x y]=meshgrid(-floor(w/2):floor(w/2)-1,-floor(h/2):floor(h/2)-1);
%hhp=(1./(d./(x.^2+y.^2).^0.5).^(2*n));

%%%%%%// New code
B = sqrt(2) - 1; %// Define B
D = sqrt(x.^2 + y.^2); %// Define distance to centre
hhp = 1 ./ (1 + B * ((d ./ D).^(2 * n)));
out_spec_centre = fftim .* hhp;

%// Uncentre spectrum
out_spec = ifftshift(out_spec_centre);

%// Inverse FFT, get real components
out = real(ifft2(out_spec));

%// Normalize and cast
out = (out - min(out(:))) / (max(out(:)) - min(out(:)));
out = uint8(255*out);

%// Show image
imshow(out);

我们得到了这个:

enter image description here

答案 1 :(得分:1)

我认为你的工作应该有点不同

n=1;
D0=50; % change the name for d0, d is usuaally the (u²+v²)⁽1/2)

A=1.5; % normally the amplitude is 1

im=imread('cameraman.jpg');

[M,N]=size(im); % is easy to get the h and w like this

% compute the 2d fourier transform in order to multiply

F=fft2(double(im));

% compute your filter and do the meshgrid for your matrix but it is M*n, and get only the real part

u=0:(M-1);
v=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);
D=sqrt(U.^2+V.^2);
H =A * (1./(1 + (D0./D).^(2*n)));

% multiply element by element

G=H.*F;
g=real(ifft2(double(G)));
subplot(1,2,1); imshow(im); title('Input image');
subplot(1,2,2); imshow(g,[ ]); title('filtered image');