簡體   English   中英

用Butterworth濾波器去除正弦噪聲

[英]Removing sinusoidal noise with Butterworth filter

我試圖去除此圖像中的正弦噪聲:

在此輸入圖像描述

這是它的DFT光譜(應用對數和任意強度縮放后):

在此輸入圖像描述

我已經有一個巴特沃斯濾鏡應用於此圖像。 它將淘汰中頻峰值。 加載后我正在注意將它從[0..255]縮放到[0..1.0]。 這是過濾器:

在此輸入圖像描述

結果不是很好:

在此輸入圖像描述

我的問題:

  • 為什么圖像中仍然存在大量噪音?
  • 為什么結果比原始圖像更暗? 過濾器顯然沒有觸及DC項,所以我希望平均強度是相同的。
  • 為什么過濾器只取出一些峰值? 它來自一本教科書,所以我傾向於認為它是正確的,但在頻譜中還有其他峰值 - 它們也是噪聲的一部分嗎? 我嘗試使用同心濾鏡去除它們,但它沒有做太多好事,並使圖像變暗無法識別。

我拍攝了圖像(裁剪)並從Gonzalez和Woods的數字圖像處理書中過濾。 在它們的示例中,通過濾波完全去除周期性噪聲,並且圖像的平均強度保持相同。

我的加載圖像和過濾器,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位。 這是打印等所必需的。

為了復制實驗,您必須從無噪聲圖像開始,然后添加自己的噪聲。

我試過使用這樣的修改過濾器: 在此輸入圖像描述
我得到的是這個 - >
在此輸入圖像描述
我不能完全解釋結果,但我最好的猜測是通過與主圖像信號交互產生的正弦噪聲會以某種方式產生二次,三次......諧波噪聲波。 結果也遠非理想,似乎仍然有一些噪音諧波仍在這里......順便說一句,感謝有趣的問題。

編輯:

我的第二次嘗試過濾器改進。 過濾:
在此輸入圖像描述 過濾結果:
在此輸入圖像描述
似乎這次沒有明顯的正弦噪聲模式可見。

我記得幾年前在圖像處理過程中玩這個圖像,我得到了和你一樣的結果。

我不知道教科書的作者如何得到他們在書中顯示的圖像,但他們必須做更多的事情,然后應用Butterworth過濾器。 正如您所提到的,有更多的峰值,因此他們可能會應用更多Butterworth濾波器來移除這些峰值。

但是,圖像的平均值確實對我來說保持不變。 您是否嘗試過計算兩幅圖像的平均值並進行比較? 它可能只是在顯示時縮放導致較暗的圖像。

我覺得你有點復雜。 如果你願意,可以在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,[]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM