Удаление синусоидального шума с помощью фильтра Баттерворта - PullRequest
14 голосов
/ 02 марта 2011

Я пытаюсь удалить синусоидальный шум на этом изображении:

enter image description here

Вот его спектр ДПФ (после применения журнала и произвольного масштабирования интенсивности):

enter image description here

У меня уже есть фильтр Баттерворта для применения к этому изображению.Это выбьет среднечастотные пики.Я стараюсь масштабировать его с [0..255] до [0..1.0] после загрузки.Вот фильтр:

enter image description here

Результаты невелики:

enter image description here

Мои вопросы:

  • Почему на изображении все еще остается значительное количество шума?
  • Почему результат темнее, чем исходное изображение?Фильтр явно не касается члена постоянного тока, поэтому я ожидаю, что средняя интенсивность будет такой же.
  • Почему фильтр отбирает некоторые пиков?Он взят из учебника, поэтому я склонен полагать, что это правильно, но есть и другие пики в спектре - они тоже являются частью шума?Я попытался удалить их, используя концентрические фильтры, но это не принесло много пользы и затемнил изображение до неузнаваемости.

Я взял изображение (обрезано) и отфильтровал из книги DigitalОбработка изображений Гонсалес и Вудс.В их примере периодический шум полностью удаляется фильтрацией, а средняя интенсивность изображения остается неизменной.

Мой исходный код для загрузки изображения и фильтра, 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)

EDIT

В исходном источнике произошла ошибка, когда мнимые компоненты фильтра были загружены как ноль.Это то, что заставило полученное изображение выглядеть темнее, чем оно было на самом деле.Я исправил это и прокомментировал соответствующую строку.

Используя фиксированный источник и фильтр, предоставленный @ 0x69 (да, я знаю, что это не совсем фильтр Баттерворта, но на этом этапе я счастлив попробоватьчто угодно), вот результат:

enter image description here

Лучше, чем то, с чего мне пришлось начинать, но все же не так хорошо, как я надеюсь.Кто-нибудь может победить это?Я подозреваю, что использование большего количества надрезов для удаления оставшихся пиков может быть полезным.

РЕДАКТИРОВАТЬ 2

Я связался с автором.Вот их ответ:

Проблема в том, что изображение, использованное в эксперименте, имело плавающую точку, тогда как изображение, показанное в книге (и оригинал, предоставленный в загрузках), составляет 8 бит.Это необходимо для печати и т. Д.

Чтобы дублировать эксперимент, необходимо начать с бесшумного изображения, а затем добавить к нему собственный шум.

Ответы [ 3 ]

5 голосов
/ 03 марта 2011

Я пытался использовать такой модифицированный фильтр: enter image description here
и вот что у меня есть ->
enter image description here
Я не могу полностью объяснить результаты, но мое лучшее предположение состоит в том, что синусоидальный шум, взаимодействуя с сигналом основного изображения, каким-то образом генерирует волны вторичного, третьего, ... гармонического шума. Результат также далек от идеального, кажется, здесь остаются некоторые шумовые гармоники ... Кстати, спасибо за интересный вопрос.

EDIT:

Моя вторая попытка улучшения фильтра. Фильтр:
enter image description here Отфильтрованный результат:
enter image description here
Кажется, на этот раз четких синусоидальных шумов не видно.

3 голосов
/ 03 марта 2011

Я помню, как играл с этим изображением во время курса обработки изображений пару лет назад, и я получил те же результаты, что и вы.

Я не знаю, как авторы учебника получили изображение, которое они отображают в книге, но они должны были сделать что-то большее, чем применить этот фильтр Баттерворта. Как вы упомянули, пиков больше, поэтому возможно, что для их удаления было применено больше фильтров Баттерворта.

Однако среднее значение изображения для меня не изменилось. Вы пытались вычислить среднее значение двух изображений и сравнить? Возможно, именно масштабирование при отображении вызывает более темное изображение.

0 голосов
/ 17 декабря 2018

Я думаю, вы делаете это немного сложным. Просто сделай это на 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,[]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...