Projekt 2: Filtracja w domenie przestrzeni 1. 2. Wstęp teoretyczny a. Filtracja w domenie przestrzeni b. Krótko o szumie c. Filtracja d. Usuwanie szumu typu Salt and Pepper filtrem medianowym e. Wnioski O programie a. Podstawowe informacje b. Opis ważniejszych funkcji i. void median(gray **input_image, gray **output_image, int width, int height, int size) ii. void average(gray **input_image, gray **output_image, int width, int height, int *mask, int size) iii. void saltandpepper(gray **input_image, gray **output_image, int width, int height, int max_value, float density) iv. void gaussian(gray **input_image, gray **output_image, int width, int height, int max_value, double var) c. Źródło (filter.c) w załączniku Filtracja w domenie przestrzeni Strona 1
1. Wstęp teoretyczny a. Filtracja w domenie przestrzeni Filtracja jest procesem splotu (inaczej konwolucji) obrazu z maską - w tym przypadku z filtrem. Konwolucja określona jest następującym wzorem: gg(xx) = (ff h)(xx) = ff(xx tt)h(tt)dddd gggggggggg: f,h splatane funkcje + Dla obrazów (funkcji dyskretnych, dwuwymiarowych) filtracja dana jest wzorem: LL2(mm, nn) = (ww LL1)(mm, nn) = LL1(mm pp, nn qq)ww(pp, qq) gggggggggg: ww(pp, qq) maska filtru MF pp,qq MMMM Rozróżniamy filtry: - dolnoprzepustowe uśredniające - górnoprzepustowe wyostrzające, gradientowe Ważną grupą filtrów górnoprzepustowych są filtry służące do wykrywania krawędzi i naroży. Najczęściej stosowane maski filtrów górnoprzepustowych służące do wykrywania krawędzi: 1 1 1 0 0 0 Prewitt 1 1 1 1 2 1 0 0 0 Sobel 1 2 1 0 0 0 1 0 0 Roberts 0 1 1 Laplasjany (kombinacja drugich pochodnych cząstkowych funkcji I(m,n) ): LL(mm, nn) = δδ2 II(mm. nn) δδmm 2 + δδ2 II(mm. nn) δδnn 2 0 1 0 1 5 1 0 1 0 1 1 1 1 9 1 1 1 1 Do wykrywania naroży służy zbiór 8 masek obracanych o 45 o : 1 1 1 1 2 1 1 1 1 Filtracja w domenie przestrzeni Strona 2
b. Krótko o szumie Jak łatwo się domyślić szum jest czymś niepożądanym. Najprościej mówiąc są to błędy/zakłócenia powstałe podczas akwizycji obrazów. Rodzaje szumu: - szum o rozkładzie Gaussa z średnią m i wariancją σ 2 - szum o rozkładzie Poissona - szum typu Salt and Pepper losowe piksele przyjmują wartość minimalna lub maksymalną dostępnej skali Szum o rozkładzie Gaussa Szum o typu Salt and Pepper Filtracja w domenie przestrzeni Strona 3
c. Filtracja Filtracja to operacja mająca na celu uwypuklenie wymaganych przez nas cech, polega na modyfikacji całości lub części obrazu. Filtracja jest operacją kontekstową inaczej blokową tzn. wartość piksela znajdującego się w centrum bloku jest liczona na podstawie pozostałych pikseli danego bloku. Cele filtracji: - pozbycie się (w mniejszym lub większym stopniu szumu) - wzmocnienie elementów obrazu zgodnie ze wzorcem - usunięcie wad obrazu - rekonstrukcje obrazu Jak wielkość maski filtru wpływa na otrzymany obraz [na przykładzie filtra medianowego]: maska 3x3 maska 7x7 Filtracja w domenie przestrzeni Strona 4
d. Usuwanie szumu typu Salt and Pepper filtrem medianowym Obraz oryginalny Obraz zaszumiony Salt and Pepper Obraz po zastosowaniu filtra medianowego o rozmiarach maski 3x3 e. Wnioski Odpowiednio dobrane filtry, jak w powyższym przypadku, mogą znacząco poprawić jakość zdjęcia można powiedzieć, że mogą je uratować. Niestety nie istnieje sposób aby z uszkodzonego zdjęcia otrzymać zdjęcie bez żadnych wad. Filtracja w domenie przestrzeni Strona 5
2. O programie a. Podstawowe informacje Program został napisany w języku C z użyciem bibliotek NetPBM. Składnia wywołania programu: filter operacja parametr plik_wejsciowy.pgm plik_wyjsciowy.pgm gdzie operacja: - gauss dodanie szumu o rozkładzie gaussa - sap dodanie szumu Salt and Pepper - average filtracja filtrem uśredniającym - median filtracja filtrem medianowym Parametr: - dla gauss - wariancja - dla sap gęstość - dla median / average maska- dostępne maski 3x3, 5x5, 7x7 b. Opis ważniejszych funkcji i. void median(gray **input_image, gray **output_image, int width, int height, int size) int i, j, vertical, horizontal; int *pixel_value = (int *)malloc(size*size*sizeof(int)); for (i=size/2; i<height-size/2; i++) for (j=size/2; j<width-size/2; j++) for (vertical=0; vertical<size; vertical++) for (horizontal=0; horizontal<size; horizontal++) pixel_value[horizontal+size*vertical] = input_image[i-size/2+vertical][j-size/2+horizontal]; sort(pixel_value, size*size); output_image[i][j] = pixel_value[(size*size)/2+horizontal]; free(pixel_value); Filtracja w domenie przestrzeni Strona 6
ii. void average(gray **input_image, gray **output_image, int width, int height, int *mask, int size) Funkcja licząca filtr uśredniający z zadaną wcześniej maską. int i, j, vertical, horizontal; int image_count, mask_count=0; for (i=0; i<size*size; i++) mask_count += mask[i]; for (i=size/2; i<height-size/2; i++) for (j=size/2; j<width-size/2; j++) image_count = 0; for (vertical=0; vertical<size; vertical++) for (horizontal=0; horizontal<size; horizontal++) image_count = image_count + input_image[i-size/2+vertical][j-size/2+horizontal] * mask[horizontal+size*vertical]; if (image_count < 0) image_count = 0; output_image[i][j] = image_count / mask_count; Filtracja w domenie przestrzeni Strona 7
iii. void saltandpepper(gray **input_image, gray **output_image, int width, int height, int max_value, float density) int i; int j; float pixnoise; int numnoise; pixnoise = density*width*height; numnoise = (int)pixnoise; int inoise[numnoise]; int jnoise[numnoise]; printf("ilosc pixli do zmiany: %d\n", numnoise); for (i=0; i<height; i++) for (j=0; j<width; j++) output_image[i][j] = input_image[i][j]; iv. void gaussian(gray **input_image, gray **output_image, int width, int height, int max_value, double var) int i; int j; double avg; double sigma; sigma = sqrt(var); printf("\nsigma: %lf\n", sigma); avg = 0.0; time_t t; srand((unsigned)time(&t)); for (i = 0; i<height; i++) for(j = 0; j<width; j++) output_image[i][j] = input_image[i][j] + sigma*(rand()%255) + avg; Filtracja w domenie przestrzeni Strona 8