Najlepszy sposób dzielenia żył na liście?

47

Przeprowadziłem wiele badań i odkryłem metody, takie jak próg adaptacyjny, zlewnia itp., Które można wykorzystać do wykrywania żył w liściach. Jednak progowanie nie jest dobre, ponieważ wprowadza dużo hałasu

Wszystkie moje obrazy są szare, proszę, czy ktoś mógłby zasugerować, jakie podejście zastosować, biorąc pod uwagę ten problem w pilnej potrzebie pomocy

EDYCJA: Mój oryginalny obraz

wprowadź opis zdjęcia tutaj

Po progowaniu

wprowadź opis zdjęcia tutaj

Jak sugeruje odpowiedź, próbowałem następującego wykrywania krawędzi

  1. Sprytny

Zbyt duży hałas i niepożądane zakłócenia

wprowadź opis zdjęcia tutaj

  1. Sobel

wprowadź opis zdjęcia tutaj

  1. Roberts

wprowadź opis zdjęcia tutaj

EDYCJA: Wypróbowałem jeszcze jedną operację, otrzymuję następujący wynik, jest lepszy niż to, co próbowałem z canny i adaptacyjnym Co czujesz?

wprowadź opis zdjęcia tutaj

vini
źródło
Czy możesz nam pokazać kilka zdjęć?
Jonas
Dodałem zdjęcia
vini
@vini Czy robisz to obecnie jako etap wstępnego przetwarzania, aby później uzyskać dobre dopasowanie szablonu? A także, w jaki sposób uzyskałeś drugi obraz poprzez proste progowanie?
Spacey,
Moim celem jest uzyskanie najlepszego możliwego wyniku w segmentacji żył, tak aby moje wyjście nie zawierało zbłąkanych artefaktów, użyłem Adaptacyjnego progowania, aby uzyskać drugi obraz
vini
Z podanych przez ciebie zdjęć wygląda to tak, jakbyś używał (różnych) filtrów na obrazie progowym. To da bardzo złe wyniki. Powinieneś użyć filtrów na oryginalnym obrazie, a następnie ustawić próg wyjściowy.
Benjohn

Odpowiedzi:

56

Nie szukasz krawędzi (= granic między rozszerzonymi obszarami o wysokiej i niskiej wartości szarości), szukasz grzbietów (cienkie linie ciemniejsze lub jaśniejsze niż ich sąsiedztwo), więc filtry krawędziowe mogą nie być idealne: Filtr krawędziowy będzie daje dwie flanki (po jednej z każdej strony linii) i niską odpowiedź na środku linii:

filtruj próbki

DODAJ : Jeśli poproszono Cię o wyjaśnienie różnicy między detektorem krawędzi a detektorem grzbietu. Z góry przepraszam, jeśli ta odpowiedź będzie bardzo długa.

Detektor krawędzi jest (zwykle) pierwszym operatorem pochodnym: jeśli wyobrażasz sobie obraz wejściowy jako krajobraz 3D, detektor krawędzi mierzy nachylenie zbocza w każdym punkcie tego krajobrazu:

wprowadź opis zdjęcia tutaj

Jeśli chcesz wykryć granicę rozszerzonego jasnego lub ciemnego regionu, jest to w porządku. Ale dla żył na obrazie OP da ci to samo: kontury po lewej i prawej stronie każdej żyły:

wprowadź opis zdjęcia tutaj

To wyjaśnia również „wzór podwójnej linii” w wynikach detektora krawędzi Canny:

wprowadź opis zdjęcia tutaj

Jak zatem rozpoznajesz te cienkie linie (np. Grzbiety)? Chodzi o to, że wartości pikseli może być (lokalnie) aproksymować 2nd rzędu wielomianu, czyli wtedy, gdy funkcja jest obraz , wówczas dla małych wartości i :gxy

g(x,y)12x22gx2+xy2gxy+12y22gy2+xgx+ygy+g(0,0)

lub w formie matrycy:

g(x,y)12(xy).(2gx22gxy2gxy2gy2).(xy)+(xy).(gxgy)+g(0,0)

Macierz pochodna drugiego rzędu nazywany jest „ Matryca Hesji ”. Opisuje interesującą nas strukturę drugiego rzędu.(2gx22gxy2gxy2gy2)

Część tej funkcji drugiego rzędu można przekształcić w sumę dwóch paraboli obróconych o pewien kąt, poprzez rozkład powyższej macierzy Hesji na czasy obrotu diagonalnej macierzy jej wartości własnych ( Rozkład macierzy ). Nie dbamy o rotację (chcemy wykrywać grzbiety w dowolnej orientacji), więc interesują nas tylko iλ1x2+λ2y2λ1λ2

Jakie kształty może mieć to przybliżenie funkcji? Właściwie nie tak wiele:

wprowadź opis zdjęcia tutaj

Aby wykryć grzbiety, chcemy znaleźć obszary na obrazie, które wyglądają jak ostatnie z powyższych wykresów, dlatego szukamy obszarów, w których główna wartość własna Hesji jest duża (w porównaniu do mniejszej wartości własnej). Najprostszym sposobem na wykrycie tego jest obliczenie głównej wartości własnej dla każdego piksela - i to właśnie robi poniższy filtr kalenicowy.


Filtr grzbiet będzie prawdopodobnie dać lepsze wyniki. Wypróbowałem wbudowaną RidgeFilterfunkcję Mathematica (która oblicza główną wartość własną macierzy Hesji dla każdego piksela) na twoim obrazie:

filtr kalenicowy

Jak widać, na każdą cienką ciemną linię jest tylko jeden pik. Plony binaryzacji i szkieletowania:

wprowadź opis zdjęcia tutaj

Po przycięciu szkieletu i usunięciu małych elementów (szumów) z obrazu, otrzymuję ten ostateczny szkielet:

wprowadź opis zdjęcia tutaj

Pełny kod Mathematica:

ridges = RidgeFilter[ColorNegate@src];
skeleton = SkeletonTransform[Binarize[ridges, 0.007]];
DeleteSmallComponents[Pruning[skeleton, 50], 50]

DODAJ:

Nie jestem ekspertem Matlaba, nie wiem, czy ma on wbudowany filtr kalenicy, ale mogę pokazać, jak zaimplementować go „ręcznie” (ponownie, używając Matematiki). Jak powiedziałem, filtr kalenicowy jest główną wartością własną macierzy Hesji. Potrafię obliczyć tę wartość własną symbolicznie w Mathematica:

eigenvalue=Last[Eigenvalues[(HxxHxyHxyHyy)]]

=>12(Hxx+Hyy+Hxx2+4Hxy22HxxHyy+Hyy2)

Musisz więc obliczyć drugie pochodne , , (używając sobela lub pochodnej filtru gaussowskiego) i wstawić je do powyższego wyrażenia i masz swój filtr kalenicy. H xy H yyHxxHxyHyy

Niki Estner
źródło
Tak to jest to dokładnie to, co chcę, ale robię to w Matlab i znalezienie odpowiednika filtra kalenicy stało się trudne
vini
1
@nikie Bardzo ładna odpowiedź - pytanie - czy mógłbyś wyjaśnić różnicę między detektorem krawędzi a detektorem grzbietu dla nas osób nie przetwarzających obrazu? Jeszcze raz dziękuję
Spacey,
@Mohammad: Próbowałem, mam nadzieję, że uczyniłem to trochę jaśniejszym, pomimo matematyki
Niki Estner
próbowałem filtr kalenicy nie daje zadowalających wyników
vini
2
@vini: „nie daje zadowalających rezultatów” tak naprawdę niewiele mi mówi. Czy otrzymujesz taki sam obraz wyniku jak ten, który zamieściłem? Co jest „niezadowalające”?
Niki Estner
6

Kiedy korzystam z wykrywania krawędzi Canny'ego (w Halconie), gdzie alfa wynosi 1, a dolny próg 8 i górny próg 13 (w skali 1-255), otrzymuję następujący wynik:

Liść wykrywania krawędzi kanny

Dzięki dopracowaniu parametrów wynik uzyskany od Canny'ego można znacznie poprawić. Za pomocą tego obrazu możesz pominąć krótkie krawędzie, aby usunąć szum, i połączyć długie krawędzie, aby uzyskać końcowy efekt.

BTW: inny kolor oznacza inną krawędź.

Mogę uzyskać dość podobny wynik za pomocą tego internetowego wykrywacza krawędzi Canny :

  • Wybierz zdjęcie I9Pxl.png
  • Sigma 1.2
  • T-niskie 0,04
  • T-wysoki 0,07
  • Inne ustawienia domyślne
  • Kliknij aktualizuj widok dla wyniku
Geerten
źródło
Dzięki :) Myślę, że Canny jest po prostu najlepszy;) Btw, zastosowanie Canny do twojego wyniku może dać jeszcze lepsze wyniki ..
Geerten
BTW: Jeśli nie zauważyłeś: Jakie są ograniczenia detektora krawędzi Canny? Tutaj możesz wyrazić swoje poglądy!
Dipan Mehta
Jeśli mi mówisz: już wyraziłem zdanie na twoje pytanie. Jeśli ogólnie komentujesz: usunę ten komentarz.
Geerten,
O tak, nie zdawałem sobie z tego sprawy!
Dipan Mehta
Dziękuję za odpowiedź, ale Canny nie zachowuje drobnych szczegółów żył w liściach, które nie zostały wykryte, jak pokazałeś ...
Vini
6

Zgodnie z powyższą doskonałą odpowiedzią, oto jak to zrobić w Pythonie za pomocą scikit funcitons.

from skimage.feature import hessian_matrix, hessian_matrix_eigvals

#assume you have an image img

hxx, hxy, hyy = hessian_matrix(img, sigma=3)
i1, i2 = hessian_matrix_eigvals(hxx, hxy, hyy)

#i2 is the variable you want.

#Visualise the result
import matplotlib.pyplot as plt
plt.imshow(i2)
Matthew Shun-Shin
źródło
Co imgpowinno być Mam pngplik i to nie działa.
Sigur
img powinien być tablicą liczb 2d.
Matthew Shun-Shin
W rzeczywistości i1jest to większa z wartości własnych, więc powinieneś jej użyć.
Rob
To najjaśniejsze wyjaśnienie, jakie kiedykolwiek widziałem!
Eureka
3

Zamiast progowania zastosowałem proste wykrywanie krawędzi.

Używany GIMP z różnicą Gaussa - Radious Zewnętrzny: 3.0 i Wewnętrzny: 1.0.

Oto jak to wygląda.

wprowadź opis zdjęcia tutaj

Możesz dodatkowo zastosować filtr środkowy lub erozję / dylatację, aby usunąć część ziarnistego hałasu.

Oto strona wyjaśniająca implementację gimpa.

Powinieneś odwoływać się do różnych technik, takich jak Laplacian Gaussa lub Difference of Gaussin itp. Zobacz: http://homepages.inf.ed.ac.uk/rbf/HIPR2/log.htm#7

I ta odpowiedź W jaki sposób Laplacian jest używany do Maski wyostrzającej?

Dipan Mehta
źródło
GIMP? jaki jest wykrywacz krawędzi?
vini
1
Nie - to pakiet do edycji obrazu. To była szybka kontrola - po prostu wysunąć punkt do przodu. - użyj wykrywania krawędzi zamiast progowania.
Dipan Mehta
Z jakiego wykrywacza krawędzi korzysta GIMP? przepraszam, mam bardzo małą wiedzę na ten temat
vini
@vini dodano odniesienie.
Dipan Mehta
3

Temat ten zawsze cieszył się dużym zainteresowaniem, a jednak nie istnieje prawdziwy konsensus w tej sprawie. Dlatego postanowiłem dodać kilka słów.

Moje odpowiedzi na wcześniej zadane podobne pytania na temat wymiany stosów ( Q1 i Q2 ) dotyczyły subpikselowego algorytmu ekstrakcji struktury krzywoliniowej autorstwa Stegera. Ta metoda działała dość dobrze w wielu przypadkach i na szczęście, w tym w tym. Dlatego zamieszczam obraz wyjściowy tutaj: wprowadź opis zdjęcia tutaj i tutaj z innym ustawieniem parametru i bez kolorowania połączonego: wprowadź opis zdjęcia tutaj Aby uzyskać szczegółowe informacje i odpowiednie odniesienia, zobacz posty wymiany stosów, o których mówiłem.

Tolga Birdal
źródło
0

W ramach mojego ostatniego roku badań inżynierskich musiałem studiować metody segmentacji naczyń krwionośnych na obrazach dna oka. Znalazłem tę metodę rekonstrukcji drzew (autorstwa Cohena, Laurenta D. i Mille'a, Juliena, szczególnie interesującą w użyciu wraz z metodami szybkiego marszu.

Inne dokumenty, które możesz zajrzeć:

  • Aktywne kontury geodezyjne
  • W sprawie wdrażania metod szybkiego marszu dla sieci 3D
  • Multistencils FMM: bardzo dokładne rozwiązanie równania Eikonal w domenach kartezjańskich

Przydatne linki: - Frontowa propagacja w 2D i 3D

Mam nadzieję, że to trochę pomoże, choć nie jest to najnowocześniejszy.

Nomaru
źródło