使用Matlab中的FFT去除图像中的噪点和模式

17

我正在使用clown.jpg图像,以便能够消除其明显的图案/噪点。

在对图像进行FFT之前,我所采取的第一步是将其重新调整为2的幂的正方形图像(即256 x 256)。在Matlab中使用FFT和fftshift可以得到中心强度的快速傅里叶变换。以下图片是使用上述函数的结果。

通过手动将FFT图像上的“星星”清零,我成功地去除了图案/噪点,如下所示:

通过取IFFT,我得到了更高质量的图片(未显示)。

我想知道是否有自动清零“星星”的方法? 我创建了一个区间来清零图像,因为我们不想去除最亮的“星星”,即直流分量,也不想去除低值。 这样的阈值如下:

filter = (fLog > .7*max(fLog(:)) ) | (fLog < .25*max(fLog(:)) )

where fLog is the log(1+abs(Fourier image)) and .7 and .25 are the corresponding
interval percentages.

下面是输出掩模(我将其乘以傅里叶图像)的内容。黑色对应于值为0,白色对应于1。请注意,此掩模的滤波会去除一些“星星”并保留一些DC分量。显然,这种方法不是最好的。

enter image description here

我正在研究如何进行高通滤波,但似乎会移除傅里叶图像中的所有外部值。这是基于我的先前测试(我没有包含那些图像)。

您是否有建议可以突出高强度值而不包括DC分量?理想情况下,我希望使掩模看起来像:

enter image description here

来源:http://users.accesscomm.ca/bostrum/Imaging/tips/tip1.html

在另一个网站上,提到要使用“高通滤波并校正FFT数据,以仅保留表示光栅图案的散点”。我不清楚如何具体操作。

来源:http://www.robotplanet.dk/graphics/raster_removal/

您的帮助将不胜感激。

以下是我的源代码以供参考:

I = imread('clown.jpg'); % Read Image

% convert to grayscale
I = rgb2gray(I);

% normalize the image and conver to doubleI
I = double(mat2gray(I));

% Resize the image
I = imresize(I, [256 256]);

% get the size of the image
[rows,cols] = size(I);

% apply FFT
f = fftshift(fft2(I));

% used to plot the image
fLog = log(1 + abs(f));

% filter by a range based on fLog

filter = (fLog > .7*max(fLog(:)) ) | (fLog < .25*max(fLog(:)) );

B = abs(ifft2(f.*filter));

colormap(gray)
subplot(2,2,1),imagesc(I); title('Original Image')
subplot(2,2,2),imagesc(fLog); title('Fourier Image')
subplot(2,2,3),imagesc(filter); title('Zeroed Fourier Image')
subplot(2,2,4),imagesc(B); title('Cleaned Image')
annotation('textbox', [0 0.9 1 0.1], ...
    'String', 'Fourier Analysis on Clown Image', ...
    'EdgeColor', 'none', ...
    'HorizontalAlignment', 'center', ...
    'FontSize', 15, ...
    'FontWeight', 'bold')

你知道直流分量在哪里,为什么不明确排除它们呢? - Mark Ransom
@MarkRansom 是的,那是真的。不过,我在想是否有一些代码可以自动化完成所有事情。 - Luciano Rodriguez
@tom10,确实众所周知光盘的效果很好。但是,如果能够得到所有亮度值的正确形状,那么图像将会更好。我只是想知道我提到的网站上的人们是如何清晰地使用遮罩的。所以我想,如果他们能做到,也许其他人已经做过类似的事情,并且很慷慨地分享了他们的方法。 - Luciano Rodriguez
2个回答

3

我试图在频域中检测局部最大振幅,并将它们与其邻域一起清零。虽然不是特别干净,但至少在某种程度上实现了一些自动清零。

enter image description here

我的代码:

I=I-mean(I(:));
f = fftshift(fft2(I));
fabs=abs(f);

roi=3;thresh=400;
local_extr = ordfilt2(fabs, roi^2, ones(roi));  % find local maximum within 3*3 range

result = (fabs == local_extr) & (fabs > thresh);

[r, c] = find(result);
for i=1:length(r)
    if (r(i)-128)^2+(c(i)-128)^2>400   % periodic noise locates in the position outside the 20-pixel-radius circle
        f(r(i)-2:r(i)+2,c(i)-2:c(i)+2)=0;  % zero the frequency components
    end
end

Inew=ifft2(fftshift(f));
imagesc(real(Inew)),colormap(gray),

非常有趣的算法。它使用正方形作为掩模来工作。虽然不完全是我想要的,但这是一个自动化的过程。谢谢你分享。 - Luciano Rodriguez
在进行这项任务时,请考虑制作“钝边缘”掩模的影响。这会在空间域中产生所谓的“振铃”现象。您应该始终制作锥形掩模以在变换域中减弱频率。 - Ashutosh Gupta
看起来不错!如果能在代码中添加一些注释,对于那些(像我这样)不熟悉Matlab的人来说会更好。为什么要减去图像媒体?(line I=I-mean(I(:)); - Rodrigo Laguna

0

我最近为我的作业编写了降噪滤波器,我苦于找不到示例代码,这是我的代码,希望它能有所帮助。感谢大家。

它是一种理想的陷波滤波器,可用于消除周期性噪声。

I = imread('clown.jpg'); %read image
I = imresize(I, [256 256]); %resize image
[m,n] = size(I);%get size of image as m and n
[X,Y]=meshgrid(1:256,1:256); % it is a meshgrid for circle mask
filter=ones(m,n); % filter initially only ones in it
%according to notch filter equation it will find point on image is on    imaginary circle.i found circle coordinates.
for i=1:m-1
  for j=1:n-1
  d0 = i-130)^2 + (j-130)^2 <= 32^2 && (i-130)^2 + (j-130)^2 >=20^2; 
      if d0
         filter(i,j)=0;
     else
         filter(i,j)=1;
     end
   end
 end
f = fftshift(fft2(I));
G = abs(ifft2(f.*filter));
figure(1),imshow(G,[]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接