2012-01-18

Filtr Gauss'a

Filtr Gaussa ma właściwości rozmywające.

Kształt filtru wywodzi się z funkcji na rozkład normalny:

$f(x)=e^{\displaystyle -\alpha x^2}$

Dla x dążącego do nieskończoności wartość filtru dąży do zera. W naszym przypadku wartość filtra poza promieniem powinna wynosić zera i najlepiej dla eliminacji oscylacji jak x dąży do granicy promienia wartość filtra powinna dążyć do zera. Najprościej możemy to zrobić przesuwając odpowiednio wartości filtru:

$f(x)=e^{\displaystyle -\alpha x^2} - e^{\displaystyle -\alpha r^2}$

Ważną jego cechą jest to, że jest on transformatą Fouriera samego siebie - kształt jest taki sam w czasie jak i w częstotliwości.



Kod w Matlabie potrzebny do generacji wykresów:

function [] = plot_gaussian()

    x = linspace(-3, 3, 1000);

    ym1 = gaussian(x, 0.5, 2);
    ym2 = gaussian(x, 1/sqrt(2), 2);
    ym3 = gaussian(x, 1, 2);
    ym4 = gaussian(x, 0.5, 4);

    trapz(x, ym1)
    trapz(x, ym2)
    trapz(x, ym3)
    trapz(x, ym4)

    figure(fig_index);
    fig_index = fig_index + 1;
    hold on;
    title('gaussian - time');
    plot(x, ym1, 'r');
    plot(x, ym2, 'g');
    plot(x, ym3, 'b');
    plot(x, ym4, 'c');
    legend('alpha = 0.5, ray = 2', 'alpha = 0.7, ray = 2', ... 
        'alpha = 1, ray = 2', 'alpha = 0.5, ray = 4');

    YM1 = fft(ym1, 100000);
    YM1 = [YM1(1:1:1000),YM1(end-1000:1:end)];

    YM2 = fft(ym2, 100000);
    YM2 = [YM2(1:1:1000),YM2(end-1000:1:end)];

    YM3 = fft(ym3, 100000);
    YM3 = [YM3(1:1:1000),YM3(end-1000:1:end)];

    YM4 = fft(ym4, 100000);
    YM4 = [YM4(1:1:1000),YM4(end-1000:1:end)];

    figure(fig_index);
    fig_index = fig_index + 1;
    hold on;
    title('gaussian - freq');
    plot(fftshift(abs(YM1)), 'r');
    plot(fftshift(abs(YM2)), 'g');
    plot(fftshift(abs(YM3)), 'b');
    plot(fftshift(abs(YM4)), 'c');
    legend('alpha = 0.5, ray = 2', 'alpha = 0.7, ray = 2', ... 
        'alpha = 1, ray = 2', 'alpha = 0.5, ray = 4');

end

function [y] = gaussian(x, alpha, ray)

    y = zeros(1, size(x, 2));

    for i=1:size(y, 2)

        if (abs(x(i)) > ray)
            y(i) = 0;
        else
            y(i) = exp(-alpha * x(i) * x(i)) - exp(-alpha * ray * ray);
        end
    end
end

Przykładowy kod filtra w C#:

public class GaussianFilter : Filter
{
    private double m_exp;
    private double m_alpha = 0.5;

    [YAXNode]
    public double Alpha
    {
        get
        {
            return m_alpha;
        }
        set
        {
            m_alpha = value;
            m_exp = Math.Exp(-m_alpha * Ray * Ray);
        }
    }

    public override double Ray
    {
        get
        {
            return 2;
        }
    }

    public override double Evaluate(double a_value)
    {
        if (a_value >= 2)
            return 0;
        if (a_value < -2)
            return 0;

        return Math.Exp(-m_alpha * a_value * a_value) - m_exp;
    }
}

Dla naszych zastosowań używanie innego większego promienia nie ma sensu. Filtr taki tylko coraz bardziej rozmywa obraz.

Brak komentarzy:

Prześlij komentarz