C# Filtr Sobela operowanie na wskaźnikach (unsafe)


(Bercik14 15) #1

Witam wszystkich. Piszę program z analizy obrazów do wykrywania krawędzi za pomocą filtrów. Udało mi się zaprogramować filtr Sobela jednak prędkość działania programu nie jest satysfakcjonująca. Doczytałem że poprzez działanie na wskaźnikach (unsafe) można uzyskać lepsze rezultaty. Poniżej wrzucam kod mojego programu i proszę o pomoc w przeróbce kodu na wskaźniki. Z góry dziękuje i pozdrawiam.

http://wklej.org/id/1081231/


(Beniamin Gajecki) #2

Prawdę mówiąc nie wiem gdzie znajduje się twój problem ale dam ci linki dotyczące wskaźników :

http://msdn.microsoft.com/pl-pl/library/28k1s2k6.aspx

http://msdn.microsoft.com/pl-pl/library/ct597kb0.aspx


(kostek135) #3

Na moje to nie problem czy to są wskaźniki czy referencje, tylko 4 zagnieżdżone pętle. Weźmy np. obrazek 1280x800px. Dwie pierwsze zagnieżdżenia pętli wyłuskują każdy piksel, czyli 1280*800, a następnie dla każdego piksela przeglądasz macierz 3x3 czyli łącznie obrotów masz 1280*800*9 czyli coś koło 10 milionów. Czy naprawdę konieczne jest przeglądanie tego w taki sposób, a nie na przykład co przysłowiowy trzeci piksel i założenie, że jeśli piksel j oraz j+3 należą do krawędzi poziomej i są w tej samej linii to piksele pomiędzy leżą na krawędzi? Dodatkowo wszystko co robisz, robisz jednowątkowo inne procesory nie biorą w liczeniu udziału, a przecież pętlę wierszy możesz rozbić na liczbę procesorów i liczyć każdym z osobna.


(Brightophidia) #4

Niestety nie znam C# więc tu Ci nie pomogę ale na tyle co rozumiem kod to liczysz filtr bezpośrednio z definicji :). Trochę teorii :slight_smile: :

Filtracja tego typu filtrem jest operacją splotu.

y = I * f

I jest to twój obraz, f to maska filtru a * oznacza splot!

Filtr Sobela jest tzw filtrem separowalnym więc można go zapisać jako:

f = [ -1 0 1

      -2 0 2

      -1 0 1]

v = [ 1

      2

      1]

h = [-1 0 1]

f = v * h

Czyli maska filtru to wynik mnożenia! (tu gwiazdka oznacza mnożenie) dwóch wektorów v i h. Taka operacja to też splot pomiędzy tymi wektorami. Z właściwości spotu wynika że jest on łączny tzn.

I * ( v*h) = (I * v) * h

gwiazdka oznacza splot.

Ostatecznie najpierw robisz filtrację tylko przy użyciu wektora v a następnie dla wynikowego obrazu ponownie go filtrujesz tym razem maską h.