5.14. Wygładzanie gaussowskie i krawędzie¶
Dwa zadania dominują w tym, do czego okna sąsiedztwa są wykorzystywane w klasycznej wizji maszynowej: czyste wygładzanie zmienności piksel-do-piksela oraz znajdowanie krawędzi, w których obraz zmienia się gwałtownie. Filtr Gaussa jest standardowym narzędziem do pierwszego z nich, a detektory oparte na laplasjanie standardowym narzędziem do drugiego – i oba się ze sobą komponują, ponieważ każdy detektor krawędzi działa lepiej na lekko wygładzonym wejściu.
5.14.1. Filtr Gaussa¶
gaussian() to wyśrodkowanie ważony kuzyn mean(). Oba obliczają średnią z sąsiedztwa każdego piksela, ale wagi w filtrze Gaussa nie są jednorodne: piksele bliżej środka sąsiedztwa liczą się bardziej, piksele na brzegu sąsiedztwa liczą się mniej, przy czym wagi podążają za znaną krzywą dzwonową, która dała filtrowi jego nazwę.
Ważenie w kształcie dzwonu sprawia, że filtr Gaussa jest gładszy niż średnia pudełkowa. Filtrowanie średnią może wytwarzać widoczne artefakty na krawędziach obiektów – ostre odcięcie w ważeniu wprowadza drobne wzory dzwonienia przy gwałtownych przejściach. Gładko opadające wagi filtra Gaussa unikają tego dzwonienia i dają wynik bliższy temu, jak „rozmycie” powinno wyglądać. Kosztem jest większe obliczenie na piksel niż w filtrze średniej, ale nie dramatycznie – koszt na piksel jest wciąż znacznie niższy niż w filtrze bilateralnym.
img.gaussian(1) # 3x3 Gaussian -- a clean light blur
img.gaussian(2) # 5x5 Gaussian -- stronger smoothing
Wygładzanie gaussowskie to standardowy pierwszy etap niemal każdego potoku wykrywania krawędzi. Wszystkie poniższe detektory krawędzi wzmacniają treść o wysokiej częstotliwości, w tym szum sensora, którego algorytm tak naprawdę nie chce wykrywać. Uruchomienie najpierw lekkiego filtra Gaussa tłumi ten szum bez znaczącego zmiękczania prawdziwych krawędzi, pozostawiając detektorowi krawędzi znajdowanie prawdziwych krawędzi zamiast szumu.
5.14.2. Maskowanie nieostrości (unsharp masking)¶
Rozmyta gaussowsko kopia obrazu to surowiec, z którego korzysta technika maski nieostrości (unsharp mask) przy klasycznym wyostrzaniu. Ustawienie unsharp=True w filtrze przełącza go z trybu „wytwórz rozmyty obraz” na „odejmij rozmyty obraz od oryginału i dodaj różnicę z powrotem do oryginału” – efekt jest taki, że krawędzie o wysokiej częstotliwości zostają wzmocnione względem gładkich wnętrz.
img.gaussian(1, unsharp=True)
Opcjonalne parametry mul i add skalują siłę efektu maski nieostrości; wartości domyślne (mul=1.0, add=0.0) dają umiarkowane wyostrzenie, które nie wyolbrzymia szumu sensora.
5.14.3. Filtr laplasjanu¶
laplacian() uruchamia dyskretne przybliżenie drugiej pochodnej przestrzennej obrazu. Wynik jest duży tam, gdzie wartości pikseli zmieniają się szybko, a bliski zeru tam, gdzie są stałe lub zmieniają się liniowo. Naturalnym odczytem wyniku jest odpowiedź krawędziowa: piksele, w których obraz zmienia się gwałtownie, rozjaśniają się, a piksele w gładkich wnętrzach pozostają ciemne.
img.laplacian(1) # 3x3 Laplacian -- edge response
Dostępne są te same parametry co dla gaussian. sharpen=True wytwarza wyostrzony obraz (laplasjan dodany z powrotem do oryginału, zamiast zwracany samodzielnie). mul i add skalują odpowiedź.
Praktycznym zastosowaniem wykraczającym poza wykrywanie krawędzi jest pomiar ostrości. Odpowiedź laplasjanu uśredniona po obszarze daje przybliżoną miarę tego, ile treści o wysokiej częstotliwości niesie ten obszar; na dobrze zogniskowanej klatce ta średnia jest wysoka, na rozmytej klatce spada. Porównywanie odpowiedzi laplasjanu między klatkami to tani sposób, by zapytać „czy obiektyw jest zogniskowany?” bez potrzeby kosztowniejszej metryki kontrastu.
5.14.4. Metoda find_edges¶
find_edges() uruchamia kompletny potok wykrywania krawędzi, a nie tylko filtr odpowiedzi krawędziowej. Działa na obrazach w skali szarości, a wynikiem jest obraz binarny, którego niezerowe piksele oznaczają pozycje, w których wejście ma taką zmianę jasności, która powinna liczyć się jako krawędź.
Metoda przyjmuje parametr edge_type, który wybiera spośród dwóch algorytmów:
EDGE_SIMPLE uruchamia filtr górnoprzepustowy, stosuje próg i zwraca wynik. Szybko, ale wynik zawiera każdą zmianę jasności powyżej progu, w tym szum i teksturę, na których aplikacji prawdopodobnie nie zależy. Rozsądne dla czystych obrazów oraz dla przypadków, w których szum zostanie usunięty przez późniejszy przebieg morfologiczny.
EDGE_CANNY uruchamia detektor krawędzi Canny’ego – klasyczny wieloetapowy algorytm. Oblicza gradient jasności, tłumi każdą odpowiedź niemaksymalną wzdłuż kierunku gradientu (tak że każda krawędź ma szerokość jednego piksela) i stosuje próg histerezy (tak że krawędź silna w jednym miejscu zostaje śledzona nawet tam, gdzie zanika pomiędzy). Wynikiem jest czysty, cienki, spójny zbiór pikseli krawędzi tego rodzaju, jakiego pragnie każdy klasyczny algorytm oparty na krawędziach.
Parametr threshold to dwuelementowa krotka (low, high). Dla EDGE_CANNY wartość high to próg odcięcia, powyżej którego piksel jest na pewno krawędzią, a wartość low to próg odcięcia, powyżej którego piksel jest krawędzią tylko wtedy, gdy jest połączony z pewną krawędzią. Dla EDGE_SIMPLE znaczenie ma tylko wartość high; jest to jedyny próg odcięcia, powyżej którego piksel liczy się jako krawędź. Domyślne (100, 200) to punkt wyjścia warty dostrojenia do konkretnej sceny.
img.gaussian(1) # pre-smooth
img.find_edges(image.EDGE_CANNY, threshold=(50, 100))
Detektor Canny’ego to lepszy wybór dla niemal każdej aplikacji, w której krawędzie mają znaczenie. Szybszy EDGE_SIMPLE warto pamiętać dla przypadków, w których koszt Canny’ego jest problemem, a odrzucanie szumu przez jego histerezę nie jest faktycznie potrzebne.
5.14.5. Progowanie adaptacyjne na filtrze Gaussa¶
Podobnie jak filtry statystyczne, gaussian() akceptuje parę słów kluczowych threshold=True / offset=N do progowania adaptacyjnego. Zachowanie jest takie samo jak w przypadku mean(): statystyka Gaussa w każdej pozycji staje się lokalnym progiem odcięcia, a piksel źródłowy jest porównywany ze statystyką powiększoną o offset, by wytworzyć wynik binarny.
Wariant gaussowski jest zwykle najczystszym wyborem do progowania adaptacyjnego, gdy wejście jest w miarę wolne od szumu. Średnia ważona daje gładszy próg odcięcia niż filtr średniej, z mniejszą liczbą artefaktów przy gwałtownych przejściach oświetlenia.