Rozmycie gaussowskie - odchylenie standardowe, promień i rozmiar jądra

19

Zaimplementowałem gaussowski shader fragmentu rozmycia w GLSL. Rozumiem główne koncepcje tego wszystkiego: splot, separacja xiy przy użyciu liniowości, wielokrotne przejścia w celu zwiększenia promienia ...

Nadal jednak mam kilka pytań:

  • Jaki jest związek między sigmą a promieniem?

    Czytałem, że sigma jest równoważne z promieniem, nie widzę, jak sigma jest wyrażana w pikselach. Czy też „promień” to tylko nazwa sigma, niezwiązana z pikselami?

  • Jak wybrać sigma?

    Biorąc pod uwagę, że używam wielu przejść w celu zwiększenia sigmy, jak wybrać dobrą sigmę, aby uzyskać sigmę, którą chcę przy danym przejściu? Jeśli wynikowa sigma jest równa pierwiastkowi kwadratowemu sumy kwadratów sigm i sigma jest równoważna z promieniem, jaki jest łatwy sposób na uzyskanie pożądanego promienia?

  • Jaki jest dobry rozmiar jądra i jaki ma to związek z sigmą?

    Widziałem, że większość implementacji używa jądra 5x5. Jest to prawdopodobnie dobry wybór dla szybkiej implementacji o przyzwoitej jakości, ale czy istnieje jeszcze jeden powód, aby wybrać inny rozmiar jądra? Jak sigma odnosi się do wielkości jądra? Czy powinienem znaleźć najlepszą sigmę, aby współczynniki poza moim jądrem były znikome i po prostu normalizowały się?

LodeRunner
źródło

Odpowiedzi:

21

Jaki jest związek między sigmą a promieniem? Czytałem, że sigma jest równoważna z promieniem, nie widzę, jak sigma jest wyrażana w pikselach. Czy też „promień” to tylko nazwa sigma, niezwiązana z pikselami?

W grze są trzy rzeczy. Wariancja ( σ2) ), promień i liczba pikseli. Ponieważ jest to dwuwymiarowa funkcja gaussa, warto zamiast tego mówić o macierzy kowariancji Σ . Tak czy inaczej, te trzy pojęcia są słabo powiązane.

Po pierwsze, gaussowski 2-D podaje równanie:

sol(z)=1(2)π)2)|Σ|mi-12)(z-μ)T.Σ-1 (z-μ)

Gdzie jest wektorem kolumnę zawierającą i współrzędnych obrazu. Więc , a jest wektorem kolumnowym kodyfikującym średnią twojej funkcji gaussowskiej w kierunkach i . x y z = [ x y ] μ x y μ = [ μ x μ yzxyz=[xy]μxyμ=[μxμy]

Przykład:

Powiedzmy teraz, że ustawiamy macierz kowariancji , a . Ustawię też liczbę pikseli na x . Co więcej, moja „siatka”, w której oceniam ten plik PDF, będzie miała wartość od do , zarówno w jak i . Oznacza to, że mam rozdzielczość siatki . Ale to jest całkowicie arbitralne. Przy tych ustawieniach otrzymam obraz funkcji gęstości prawdopodobieństwa po lewej stronie. Teraz, jeśli zmienię „wariancję” (tak naprawdę kowariancję), taką, że μ = [ 0 0 ] 100 100 - 10 10 x yΣ=[1001]μ=[00]100100-1010xyΣ=[ 9 0 0 910-(-10)100=0.2Σ=[9009] i zachowaj wszystko inne bez zmian, otrzymuję obraz po prawej stronie.

wprowadź opis zdjęcia tutaj

Liczba pikseli jest wciąż taka sama dla obu, x , ale zmieniliśmy wariancję. Załóżmy, że zamiast tego wykonujemy ten sam eksperyment, ale zamiast tego używamy x pikseli, ale nadal działałem od do . Następnie moja siatka ma rozdzielczość . Jeśli użyję tych samych kowariancji, co poprzednio, otrzymam to:1001002020-101010-(-10)20=1

wprowadź opis zdjęcia tutaj

Oto jak musisz zrozumieć wzajemne oddziaływanie tych zmiennych. Jeśli chcesz kod, mogę go również tutaj zamieścić.

Jak wybrać sigma?

Wybór macierzy wariancji / kowariancji twojego filtra gaussowskiego jest niezwykle zależny od aplikacji. Nie ma „właściwej” odpowiedzi. To jest jak pytanie o przepustowość, którą należy wybrać dla filtra. Znowu zależy to od twojej aplikacji. Zazwyczaj chcesz wybrać filtr gaussowski, tak aby wyeliminować znaczną liczbę komponentów wysokiej częstotliwości na obrazie. Jedną rzeczą, którą możesz zrobić, aby uzyskać dobry pomiar, jest obliczenie 2D DFT obrazu i nałożenie jego współczynników na obraz Gaussa 2D. Dzięki temu dowiesz się, jakie współczynniki są silnie karane.

Na przykład, jeśli twój obraz gaussowski ma tak szeroką kowariancję, że obejmuje wiele współczynników wysokiej częstotliwości twojego obrazu, musisz zmniejszyć jego elementy kowariancji.

Tarin Ziyaee
źródło
1
Te obrazy byłyby lepsze, gdyby użyły sekwencyjnej mapy kolorów. jet jest najgorszy.
endolith
@endolith „Better” zależy od aplikacji. Nie używam jet, gdy potrzebna jest wizualna dyskryminacja kontrastu. (Hot jest lepszy). Tutaj jednak wiadomość jest w rozmiarze gaussa, więc nie szkodzi wyrządzeniu odrzutowca. Dzięki za link.
Tarin Ziyaee
2
To ładnie przemyślana i bardzo dobrze wizualizowana odpowiedź! Weźmy na przykład ten lewy górny obraz. Oczywiste jest, że ta kombinacja wariancji i wielkości jądra byłaby marnotrawstwem, ponieważ jest to jądro 100 x 100, w którym tylko centrum 30 x 30 (~ 9%) jest niezerowe.
Adam Smith,
5

Parametr sigma wystarcza do zdefiniowania rozmycia gaussowskiego z ciągłego punktu widzenia. W praktyce jednak obrazy i jądra splotów są dyskretne. Jak wybrać optymalne dyskretne przybliżenie ciągłego jądra Gaussa?

Dyskretne przybliżenie będzie bliższe ciągłemu jądru Gaussa, gdy użyjesz większego promienia. Może to jednak kosztować dodatkowy czas trwania obliczeń.

Idealnie byłoby wybrać wartość sigma, a następnie obliczyć promień, który pozwala wiernie przedstawić odpowiednie ciągłe jądro Gaussa. Dla danego błędu aproksymacji im większa sigma, tym większy musi być promień.

Co ciekawe, może to być bardzo skomplikowane, aby zrobić to dobrze. Czy przy konstruowaniu macierzy gaussowskiej najlepszym rozwiązaniem jest próbkowanie ciągłego jądra, czy też istnieją lepsze przybliżenia? Jak znormalizować obliczone dyskretne jądro w celu uwzględnienia obcięcia? itp.

Jako odniesienie, w Mathematica funkcja GaussianMatrix oferuje kilka sposobów obliczania macierzy dyskretnej Gaussa, np. Przy użyciu dyskretnej aproksymacji Bessela. Domyślnie promień = 2 * sigma, co oznacza, że ​​przy sigma = 1 macierz będzie miała wymiary 5 x 5.

Matthias Odisio
źródło
To dość stare pytanie. Ale czy promień 2 * sigma nie dałby macierzy 9 x 9?
Logika urojeniowa
@DelusionalLogic z sigma = 1, promień = 2, więc macierz będzie miała rozmiar 4, ale potrzebuje nieparzystego rozmiaru, więc rozmiar 5x5. Przynajmniej tak to rozumiem ...
Micka
Jeśli promień wynosi 2, sąsiedztwo rozszerza środkowy piksel o 2 piksele w lewo, 2 w prawo itp. Jest to tylko konwencja stosowana przez Mathematica.
Matthias Odisio
2

Okazuje się, że rzędy trójkąta Pascala całkiem dobrze przybliżają Gaussa i mają praktyczną zaletę posiadania wartości całkowitych, których suma jest potęgą 2 (możemy przechowywać te wartości dokładnie jako liczby całkowite, wartości stałych lub zmiennoprzecinkowe). Powiedzmy na przykład, że chcemy zbudować jądro Gaussa 7x7, możemy to zrobić, używając siódmego rzędu trójkąta Pascala w następujący sposób:

wprowadź opis zdjęcia tutaj

Zauważ, że ten filtr ma minimalny wpływ w rogach, pozostając wartościami całkowitymi. Możesz użyć środkowej wartości 20/64, aby określić odpowiadającą sigmę odchylenia standardowego, która w tym przypadku wynosi 64 / (20 * sqrt (2 * pi)) = 1,276 dla przybliżonego Gaussa. Możesz wykreślić wykres Gaussa, aby zobaczyć, że jest to doskonałe dopasowanie.

Dobry punkt wyjścia do ustalenia rozsądnego odchylenia standardowego dla jądra Gaussa pochodzi z trójkąta Pascala (inaczej współczynników dwumianowych ) - dla filtra (N + 1) x (N + 1) odpowiadającego powyższemu zastosowaniu konstrukcyjnemu

wprowadź opis zdjęcia tutaj

GaussianMatrix [3] Wolframa Alpha po prostu używa r / 2 = 1,5. O dziwo, GaussianMatrix [{3,1.276}] nie daje tego samego filtra 2D co mój i nie jest następujący dla x, y między -3 a 3:

wprowadź opis zdjęcia tutaj

Nie jestem pewien dlaczego nie? Mój filtr 2D jest doskonale dopasowany.

wcochran
źródło