Filtr Gaussa w dziedzinie przestrzennej

0

Wie ktos jak w prosty sposob napisac filtr Gaussa (rozmycie Gaussa) w dziedzinie przestrzennej? Do tego filtru nie potrzeba przechodzic do czestotliwosci ale mam problem z algorytmem...

0

Najprościej to tak sobie oknem zasuwasz po tablicy. Trochę lepsze rozwiązanie to zrobienie tego najpierw w jednym kierunku a potem w drugim. (W sensie pionowo i poziomo)

http://en.wikipedia.org/wiki/Gaussian_blur#Implementation

0

Rzecz w tym, ze juz jakis kod mam napisany. Jednak on nie za bardzo dziala. Moze wstawie to co napisalem. Otoz tak, na samym poczatku do metody/funkcji/etc/ przesylam parametr sigma i licze maske. Tutaj liczona maska 3x3:

for (row=-1; row<=1; row++) {
            for (col=-1; col<=1; col++) {
                midCalkulation = -((pow(col, 2) + pow(row, 2))/(2*pow(sigma, 2)));
                kernel3x3[row+1][col+1] = (1/(2*M_PI*pow(sigma, 2)))*exp(midCalkulation);
                
            }
        }

Pozniej, majac wyliczona maske licze splot obrazu z maska:

for(row=1; row<height-1; row++) {
            for(col=1; col<width-1; col++) {
                midSum=0;
                for(int i=-1; i<=1; i++) {
                    for(int j=-1; j<=1; j++) {
                        midSum += pixels[(row+i)*width + (col+j)]*kernel3x3[i+1][j+1];
                    }
                }
                filteredPixels[row*width + col] = midSum;
            }
        }

rzecz w tym, ze to nie dziala... Jedyne co ten kawalek kodu robi to zmniejszanie jasnosci obrazu. im wiekszy jest przekazywany parametr sigma, tym bardziej obraz robi sie ciemniejszy.

0

Maska nie jest znormalizowana. Podziel każdy element przez sumę wszystkich elementów w masce.

0

Tzn. po wyliczeniu maski mam wyliczyc sume wszystkich elementow maski 3x3. Potem dopiero wyliczyc nowa wartosc obrazu?

Zeby bylo ciekwaiej to przyjalem maske standardowa:

kernel3x3[0][0]=1;    kernel3x3[0][1]=2;     kernel3x3[0][2]=1;
kernel3x3[1][0]=2;    kernel3x3[1][1]=4;     kernel3x3[1][2]=2;
kernel3x3[2][0]=1;    kernel3x3[2][1]=2;     kernel3x3[2][2]=1;

i nastepnie splatam:

        for(row=1; row<height-1; row++) {
            for(col=1; col<width-1; col++) {
                midSum=0;
                for(int i=-1; i<=1; i++) {
                    for(int j=-1; j<=1; j++) {
                        midSum += pixels[(row+i)*width + (col+j)]*(kernel3x3[i+1][j+1]/16);
                    }
                }
                filteredPixels[row*width + col] = midSum;
            }
        }

Dla tej maski wszystko dziala dobrze... Ale nie jesli wylicze maske:

        for (row=-1; row<=1; row++) {
            for (col=-1; col<=1; col++) {
                midCalkulation = -((pow(col, 2) + pow(row, 2))/(2*pow(sigma, 2)));
                kernel3x3[row+1][col+1] = (1/(2*M_PI*pow(sigma, 2)))*exp(midCalkulation);

                kernelSum += kernel3x3[row+1][col+1];
            }
        }

i taka maske splote z obrazem:

        for(row=1; row<height-1; row++) {
            for(col=1; col<width-1; col++) {
                midSum=0;
                for(int i=-1; i<=1; i++) {
                    for(int j=-1; j<=1; j++) {
                        midSum += pixels[(row+i)*width + (col+j)]*(kernel3x3[i+1][j+1]/kernelSum);
                    }
                }
                filteredPixels[row*width + col] = midSum;
            }
        }

to wynik jest oplakany, czyt. pojawia sie jakis szum nieznanego pochodzenia.

0
  1. wiesz, że cicho zakładasz, że masz do czynienia z obrazem w skali szarości! Jeśli masz kolorowy obraz, każdą barwę musisz potraktować osobno.
  2. nie powinieneś dzielić przez 16 tylko przez sumę wszystkich elementów maski (to jest normalizacja maski)
  3. jeśli posługujesz się sigmą to wtedy rozmiar maski musi zależeć od sigmy! rozmiar maski musi być większy od sigmy (co najmniej 3 razy), w przeciwnym razie weźmiesz pod uwagę tylko czubek rozkładu Gaussa.
0

ad. 1 Tak, tego nie dopowiedzialem, ale rozpatruje wylacznie obrazy w odcieniach szarosci.
ad. 2 Wiem, ze nie powinienem dzielic przez 16. Ale dla standardowej maski z ksiazki tak nalezy zrobic. Jest to ksiazkowy przyklad i chodzilo mi o sprawdzenie dzialania algorytmu.
ad. 3 Problematyczne staje się w takim razie liczenie maski dla roznych wartosci sigma. Problemem zaczyna byc brzeg obrazu, ktory tez trzeba uwzglednic, nie wiem, interpolowac? Czytalem o tym filtrze w ksiazce Gonzaleza i Woodsa "digital image processing" ale nie bylo tam wspomniane o dobieraniu maski w locie.

0

Zrób ramkę dookoła obrazu. Wypełnić ją możesz na różne sposoby: czernią, odbijając brzegi obrazu, klonując brzegi obrazu albo jak sobie wymyślisz. Maska 3x3 jest na pewno za mała.

1 użytkowników online, w tym zalogowanych: 0, gości: 1