【问题标题】:Removing sinusoidal noise with Butterworth filter使用巴特沃斯滤波器去除正弦噪声
【发布时间】:2011-07-07 03:21:42
【问题描述】:

我正在尝试去除这张图片中的正弦噪声:

这是它的 DFT 谱(在应用对数和任意强度缩放之后):

我已经有一个 Butterworth 过滤器可应用于此图像。它将消除中频峰值。加载后,我注意将其从 [0..255] 缩放到 [0..1.0]。这是过滤器:

结果不是很好:

我的问题:

  • 为什么图像中仍然存在大量噪点?
  • 为什么结果比原始图像暗?过滤器显然没有触及 DC 项,所以我希望平均强度是相同的。
  • 为什么过滤器只去除一些峰?它来自教科书,所以我倾向于相信它是正确的,但光谱中还有其他峰值——它们也是噪音的一部分吗?我尝试使用同心滤镜去除它们,但效果不佳,而且图像变暗,无法辨认。

我从 Gonzalez 和 Woods 的书 Digital Image Processing 中拍摄了图像(裁剪)和过滤器。在他们的例子中,周期性噪声被过滤完全去除,图像的平均强度保持不变。

我的加载图片和滤镜、DFT、滤波、IDFT的源码如下:

import cv

def unshift_crop(comp, width, height):
    result = cv.CreateImage((width, height), cv.IPL_DEPTH_8U, 1)
    for x in range(height):
        for y in range(width):
            real, _, _, _ = cv.Get2D(comp, x, y)
            real = int(real) * ((-1)**(x+y))
            cv.Set2D(result, x, y, cv.Scalar(real))
    return result

def load_filter(fname):
    loaded = cv.LoadImage(fname, cv.CV_LOAD_IMAGE_GRAYSCALE)
    flt = cv.CreateImage(cv.GetSize(loaded), cv.IPL_DEPTH_32F, 2)
    width, height = cv.GetSize(loaded)
    for i in range(width*height):
        px, _, _, _ = cv.Get1D(loaded, i)
        #cv.Set1D(flt, i, cv.Scalar(px/255.0, 0))
        cv.Set1D(flt, i, cv.Scalar(px/255.0, px/255.0))
    return flt

if __name__ == '__main__':
    import sys
    fname, filt_name, ofname = sys.argv[1:]
    img = cv.LoadImage(fname, cv.CV_LOAD_IMAGE_GRAYSCALE)
    width, height = cv.GetSize(img)
    src = cv.CreateImage((width*2, height*2), cv.IPL_DEPTH_32F, 2)
    dst = cv.CreateImage((width*2, height*2), cv.IPL_DEPTH_32F, 2)
    cv.SetZero(src)
    for x in range(height):
        for y in range(width):
            px, _, _, _ = cv.Get2D(img, x, y)
            px = float(px) * ((-1) ** (x+y))
            cv.Set2D(src, x, y, cv.Scalar(px, 0))
    cv.DFT(src, dst, cv.CV_DXT_FORWARD)
    flt = load_filter(filt_name)
    cv.Mul(dst, flt, src)
    cv.DFT(src, dst, cv.CV_DXT_INV_SCALE)
    result = unshift_crop(dst, width, height)
    cv.SaveImage(ofname, result)

编辑

原始源代码中存在一个错误,其中过滤器虚构组件加载为零。这就是导致结果图像看起来比实际更暗的原因。我已修复此问题并评论了相关行。

使用@0x69 提供的固定源和过滤器(是的,我知道这不是真正的巴特沃斯过滤器,但在这个阶段我很乐意尝试任何东西),结果如下:

比我开始时要好,但仍然没有我希望的那么好。谁能打败这个?我怀疑添加更多的凹槽以消除剩余的峰值可能会有一些好处。

编辑 2

我已经联系了作者。这是他们的回应:

问题是使用的图像 实验是浮点数, 而书中显示的那个(和 中提供的原件 下载)为 8 位。这是 打印等所需的。

为了重复实验, 你必须从无噪音开始 图像,然后添加自己的噪音 它。

【问题讨论】:

  • +1 以获得一个完整的解释清楚的问题
  • 为什么不显示过滤后图像的dft?
  • @highBandWidth 因为从过滤器和输入图像的 DFT(通过乘法)确定它很简单。

标签: python image-processing opencv


【解决方案1】:

我记得几年前在图像处理课程中玩过这张图片,我得到了和你一样的结果。

我不知道教科书的作者是如何得到他们在书中显示的图像的,但他们肯定做了更多的事情,然后应用了巴特沃斯过滤器。正如你提到的,有更多的峰值,所以他们可能应用了更多的巴特沃斯过滤器来去除这些。

但是,图像的平均值对我来说确实保持不变。您是否尝试过计算两张图像的平均值并进行比较?可能只是显示时的缩放导致图像变暗。

【讨论】:

  • 感谢您的意见。我开始怀疑是否完成了一些额外的处理。听到有人遇到同样的问题是令人放心的。就图像的平均值而言,请参阅我编辑的帖子。
【解决方案2】:

我尝试过使用这种修改过的过滤器:
我得到的是这个 ->

我无法完全解释结果,但我最好的猜测是正弦噪声通过与主图像信号交互以某种方式产生次要,第三,...谐波噪声波。 结果也远非理想,似乎仍然存在一些噪声谐波...... 顺便说一句,感谢您提出有趣的问题。

编辑:

我第二次尝试改进过滤器。过滤器:
过滤结果:

这次似乎看不到清晰的正弦噪声模式。

【讨论】:

  • 感谢您尝试并制作出更好的过滤器!请参阅我的更新答案。
【解决方案3】:

我认为你让它有点复杂。 如果你愿意,就在 Matlab 上做吧。

它会给你很好的结果。

%  Question: Filtration in Frequency Domain

im = imread('applo_noisy.tif');
FT = fft2(double(im));
FT1 = fftshift(FT);%finding spectrum
%imtool(abs(FT1),[]);

m = size(im,1);
n = size(im,2);

t = 0:pi/15:2*pi;
xc=(m+150)/2; % point around which we filter image
yc=(n-150)/2;

r=200;   
r1 = 40;

xcc = r*cos(t)+xc;
ycc =  r*sin(t)+yc;
xcc1 = r1*cos(t)+xc;
ycc1 =  r1*sin(t)+yc;

mask = poly2mask(double(xcc),double(ycc), m,n); % Convert region-of-interest polygon to mask
mask1 = poly2mask(double(xcc1),double(ycc1), m,n); % generating mask for filtering

% a=51;
% b=5;
% a(b) = 0; % 51 0 0 0 0

mask(mask1)=0;

FT2=FT1;
FT2(mask)=0;%cropping area or bandreject filtering

output = ifft2(ifftshift(FT2));
imtool(output,[]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-09
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    相关资源
    最近更新 更多