使用傅里叶变换消除图像中的周期性噪声

11

我正在对一张图片执行二维FFT并获取其频谱成分。现在这张图片已经与另一张图片叠加在一起,形成了周期性噪声。

以下展示了原始图像和周期性噪声版本:

原始图像

enter image description here

周期性噪声图像

enter image description here

为了过滤掉这种噪声,我使用手动框选的方式遮罩了幅度谱中相对于其他成分来说非常大的部分如下所示。

enter image description here

完成此操作后,我执行逆FFT,但是却没有得到原始图像。

enter image description here

有人知道我做错了什么吗?

以下是掩蔽数值并对掩蔽后的频谱图执行二维逆FFT的代码:

pat1 = imread('Pattern1.png');

spec_orig = fft2(double(pat1));     
spec_orig2 = abs(spec_orig); 
spec_img = fftshift(spec_orig2);

for j = 115:125
    for n = 96:106
        spec_img(n,j) = 0; 
    end
    for n = 216:226
        spec_img(n,j) = 0; 
    end
    for n = 274:284
        spec_img(n,j) = 0; 
    end
    for n = 298:308
        spec_img(n,j) = 0; 
    end
    for n = 12:22
        spec_img(n,j) = 0; 
    end
    for n = 37:47
        spec_img(n,j) = 0; 
    end
end

%Getting Back the Image for Pattern1
figure;subplot(2,1,1);
spec_img = log(1 + spec_img);
imshow(spec_img,[]); 

subplot(2,1,2);
ptnfx = ifft2(spec_img);
imshow(ptnfx);

1
在开始时,那个双重循环可以通过利用数组索引来移除:spec_img([96:106 216:226],115:125)=0 等。 - Andras Deak -- Слава Україні
1
@AndrasDeak 我不知道你可以这样做 - 谢谢! - SDG
没问题。这就是我建议你熟悉matlab本身的原因 :) 对语言的基本要素有牢固的掌握可以让你的生活更加轻松,使你的代码更加优雅高效。 - Andras Deak -- Слава Україні
1
你在MATLAB Central论坛或是这里问过问题吗?这个问题显然不是太宽泛了。你向我们展示了你尝试过什么,以及你卡在哪里了。这非常适合在StackOverflow上提问。 - rayryeng
1
顺便说一句,你肯定可以继续问有关图像处理的问题:D。我和另外一个人是该标签下唯二拥有金徽章的人,这证明了我对这个领域的喜爱程度。 - rayryeng
显示剩余7条评论
1个回答

23
在频域进行滤波是一个棘手的问题。您的代码存在一些错误,阻止您重建原始图像:
  1. 您仅在幅度分量上应用了滤波器。您需要在原始图像频谱上执行此操作,而不仅仅是在幅度分量上。相位对于正确的重建至关重要。顺便说一句,根据信号处理术语,您正在实现一个notch filter或带阻滤波器,该滤波器会删除某些特定频率。

  2. 您通过fftshift使频谱居中,但在过滤后,您忘记了撤消这个移动。您必须在结果过滤图像上调用ifftshift以撤消居中操作。

  3. 您正在查找对数转换图像的逆FFT。请记住,对频谱进行对数变换仅用于显示目的。您在过滤或查找逆时不使用它。这样做将给您带来意想不到的后果,因为由于非线性操作,大多数频谱已经发生了改变。您必须在原始图像频谱上执行此操作。

  4. 一个小细节,但请确保在反FFT后过滤结果时调用real。由于计算浮点误差,很可能存在一些残留的虚数分量,因此调用real仅会提取信号的实部。

经过这些更正,这是我所拥有的代码。我从StackOverflow直接读取了您的图像以便复制:

pat1 = imread('http://i.stack.imgur.com/oIumJ.png');

%// Change
spec_orig = fft2(double(pat1)); 
spec_img = fftshift(spec_orig);

for j = 115:125
    for n = 96:106
        spec_img(n,j) = 0; 
    end
    for n = 216:226
        spec_img(n,j) = 0; 
    end
    for n = 274:284
        spec_img(n,j) = 0; 
    end
    for n = 298:308
        spec_img(n,j) = 0; 
    end
    for n = 12:22
        spec_img(n,j) = 0; 
    end
    for n = 37:47
        spec_img(n,j) = 0; 
    end
end

%// Change
ptnfx = real(ifft2(ifftshift(spec_img)));
imshow(ptnfx,[]);

我得到了这张图片:

enter image description here

我会添加一个相当不错的原始图像重建。你仍然会看到一些条纹,这在很大程度上取决于凹口滤波器的形状和大小。也许可以将大小调大,甚至更改凹口滤波器的形状为圆形。这样做有助于保留更多原始图像,因为方形边角引入的硬边缘会产生意外的振铃效应。

那是一个相当愚蠢的错误。我更新后的结果现在已经发布在问题上了。这是否与同一问题有关?如果不是,我很乐意将其作为答案接受。 - SDG
1
@SharanDuggirala 请看一下我上面的评论。我很乐意帮你调试这个问题,但我需要更多了解你如何获取该转换 - 原始图像在哪里?你用来转换图像的代码在哪里? - rayryeng
你能上传原始图像吗?而不是将其subplot到一个图中。 - rayryeng
1
刚刚尝试了一个圆形凹口滤波器,我可以确认图像的条纹明显减少了! - SDG
@SharanDuggirala 我早就预料到了。使用圆形滤波器可以更均匀地将频率的谐波滤除。而使用正方形则无法完全消除在这些频率上看到的谐波,因此你仍然会看到一些残留的“条纹”作为副作用。干得好! - rayryeng
显示剩余8条评论

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