Temat: Splot obrazu

Splot obrazu (ang. image convolution) sprowadza się do przetworzenia obrazu w następujący sposób:

1. Przygotowujemy sobie tzw. jądro splotu (ang. kernel) o wielkości 3x3 piksele (stosowane są również większe, np. 5x5).
2. Poszczególne piksele obrazu przeliczamy w ten sposób, że dla każdego piksela przemnażamy każdą wartość z kernela przez każdą wartość odpowiadającego temu pikselowi fragmentu obrazu o wielkości takiej jak kernel.
3. Następnie sumujemy poszczególne wyniki, a jeżeli suma elementów jądra jest większa od 1, dzielimy sumę naszych mnożeń przez sumę elementów jądra i zaokrąglamy do wartości całkowitej.
4. Jeżeli otrzymany w ten sposób wynik przekracza dopuszczalną skalę szarości, przycinamy go odpowiednio do jej dolnej lub górnej wartości granicznej - czyli jak jest ujemny to do 0, jak za duży to do maksymalnego poziomu szarości obrazu (można również stosować bardziej złożone sposoby normalizacji wyników wyjściowych).
5. Ostateczny wynik umieszczamy w wynikowej tablicy pikseli (nie można wpisać go od razu do tablicy źródłowej, ponieważ w kolejnej iteracji zostałby wzięty do obliczeń, z uwagi na to, że po obrazie przemieszczamy się okienkiem wielkości 3x3).

Najlepiej taką operację przedstawić obrazowo:
https://developer.apple.com/library/mac/documentation/Performance/Conceptual/vImage/Art/kernel_convolution.jpg
(wynik otrzymany na powyższym obrazku powinien jeszcze zostać dopasowany do skali szarości)

Inny przykład (w wersji interaktywnej powinno być jeszcze dzielenie przez sumę z kernela):
http://www.olympusmicro.com/primer/java … index.html

Wynik tak przeprowadzonej filtracji obrazu zależy od tego, jakie wartości umieścimy w jądrze splotu.

W ten sposób możemy zrealizować np. rozmycie, wyostrzenie, wykrycie krawędzi, uwypuklenie itp.

Przy tego typu przetwarzaniu pojawia się pytanie: co zrobić na krawędzi obrazu?

Najlepszym rozwiązaniem jest tymczasowe powiększenie tablicy o 1 piksel w każdą stronę i przepisanie do tak powstałej krawędzi wartości sąsiednich pikseli. Rozmiar tego powiększenia zależy od tego, jakiej wielkości filtrami chcemy się przemieszczać po obrazie, przykład dla filtrów 5x5:
http://zone.ni.com/reference/en-XX/help … e_borders/

Ponieważ do splotu stosować możemy różne filtry, dobrym rozwiązaniem może być napisanie funkcji realizującej splot, która tablicę z jądrem splotu przyjmuje jako argument wywołania, np:

splot(struct Obraz* o, int[3][3] jadro);