2011-09-14 13 views
10

Pracuję nad czarnym białym obrazem &, podobnie jak pierwszy z linku: http://imageshack.us/g/33/firstwm.png/ Ma dużo "szumu", więc zastosowałem nad nim filtr Median, aby go wygładzić, uzyskując w ten sposób drugie zdjęcie.Jak wygładzić krzywe (kontury) w OpenCV?

cvSmooth(TempImage, TempImage, CV_MEDIAN, 5, 0); 

Po tym otrzymuję kontury i rysuję je na innym obrazie, takim jak trzeci obraz z linku. Moim problemem jest to, że kontury są nadal trochę pikselizowane (ostre). Czy istnieje sposób na wygładzenie obrazu B & W, aby uzyskać lepsze kontury? A może coś z konturami. Próbowałem również Dilate i Erode z różnymi jądrami, ale problem pozostaje ten sam. Dziękuję za wszystko, co pomaga.

EDIT: próbował również:

cvSmooth(TempImage, TempImage, CV_GAUSSIAN, 9, 9, 3); 
cvThreshold(TempImage, TempImage, 127, 255, CV_THRESH_BINARY); 

same wyniki jak filtr mediana, ok, ale nadal pozostawia pewne piksele kontury.

+1

przepuszczenie go przez jądra Gaussa, a następnie wartości odcięcia należy wygładzić krawędzie. Być może jest to wynik, który chcesz? – swalog

+0

Przyjmuję założenie, że "szum", o którym mówisz, to elementy wysokiej częstotliwości, które wydawało się usunąć w twoim drugim przykładzie. Czy [this] (http://i.imgur.com/33GIT.png) jest pożądanym wyjściem? Jeśli pożądane jest tylko wyjście binarne, najbliższy będzie [twardy próg] (http://i.imgur.com/VelRg.png). – swalog

+0

Tak, pożądanym wyjściem jest usunięcie szumów, aby uzyskać jak najdelikatniejsze kontury, próbowałem progu Gaussa + również na twoją sugestię, ale otrzymałem takie same wyniki jak filtr medianowy. – Adrian

Odpowiedz

8

enter image description here

Jeśli jest to efektem wygładzania jesteś po, można go uzyskać, wykonując rozmycie Gaussa, a następnie przez Progowanie. To znaczy. przy użyciu cvSmooth z parametrem CV_GAUSSIAN jako parametrem. Po nim następuje cvThreshold.

Jeśli chcesz uzyskać płynniejsze przejście niż ustawianie progów (np. this), możesz to uzyskać, dostosowując poziomy (zmieniając zakres kolorów, aby zachować część zmiany krawędzi).

aktualizacjaAby wyjaśnić, jak uzyskać gładki (wygładzony) brzeg na progu, należy rozważyć, co robi próg. Zasadniczo przetwarza każdy piksel na obrazie, po jednym na raz. Jeśli wartość pikseli jest niższa niż wartość progowa, zostanie ustawiona na czarny (0), a jeśli nie, to na biały (255).

Operator progu jest zatem bardzo prosty, jednak można użyć dowolnej innej ogólnej funkcji odwzorowania. Zasadniczo jest to funkcja f(i), gdzie i jest wartością intensywności piksela (w zakresie 0-255) i f(i) jest zmapowaną wartością. Na progu tej funkcji jest prosta

f(i) = { 0, for i < threshold 
      255, for i >= threshold 

Co masz jest wygładzony obraz (przez cvSmooth użyciu Gaussa jądra, co daje się „płynne” wygładzanie, czy to ma sens). W ten sposób można uzyskać miękkie przejście wartości na krawędziach, w zakresie od 0 do 255. To, co chcesz zrobić, powoduje, że przejście jest o wiele mniejsze, aby uzyskać dobrą przewagę. Jeśli pójdziesz na niego balistycznie, przejdziesz bezpośrednio od 0 do 255, czyli tak samo jak progowanie binarne, które już wykonałeś.

Rozważmy teraz funkcję, która mapuje, może zakres 4 wartości intensywności (127 + - 4) do pełnego zakresu 0-255. To znaczy.

  f(i) = { 0, for i < 123 
        255, for i >= 131 
     linear mapping, for 123 <= i < 131 

Otrzymasz żądane wyjście. Rzucę okiem i zobaczę, czy jest już zaimplementowany w openCV. Nie powinno to jednak być zbyt trudne do samodzielnego zakodowania.

Aktualizacja 2 Wersja kontur byłoby coś takiego:

   f(i) = { 255, for  i < 122 
    linear mapping (255->0), for 122 <= i < 126 
         0, for 126 <= i < 127 
    linear mapping (0->255), for 127 <= i < 131 
         255, for 131 <= i 
+0

Och, rozumiem teraz co mówisz, dla tego mógłbym użyć cvLUT zamiast cvThreshold. Ale teraz, gdy pomyślę o tym po zastosowaniu cvFindContours, aby uzyskać kontury, wrócę do pikselowego konturu :(. Dzięki za odpowiedź i tak, jeśli za kilka dni nie pojawi się lepsza odpowiedź, zaznaczę twoją jako Popraw to: – Adrian

+0

Należy wziąć pod uwagę, że po operacji wygładzania masz gładką krawędź gradientu, ale nadal powinno być możliwe uzyskanie ładnie wyglądającego obrazu konturu przy użyciu cvLUT i prawidłowych wartości w tabeli. Krótko mówiąc, ma on trzy zakresy, od białego do czarnego (początek linii) od czarnego do czarnego (wewnątrz linii) i od czarnego do białego (koniec linii), podążając za tą samą strukturą co powyżej Wszystkie wartości poza tym są również odwzorowane na biały. kontur :) – swalog

+0

Zobacz aktualizację 2 w odpowiedzi. Po prostu zgaduję dobre wartości, więc możesz się z tym pobawić :) – swalog

Powiązane problemy