Segmentacja tekstur Grzegorz Szuba
Transkrypt
Segmentacja tekstur Grzegorz Szuba
Segmentacja tekstur Grzegorz Szuba ([email protected]) informatyka IV rok Metody Rozpoznawania Obrazów 2005/2006 Treść zadania: Celem zadania jest wyodrębnienie na obrazie będącym złożeniem kilku tekstur granic między poszczególnymi teksturami ze szczególnym uwzględnieniem tekstur, których uśredniona barwa jest taka sama, a różnią się tylko fakturą. Kod programu: (na podstawie http://www.mathworks.com/products/demos/image/ipextexturefilter/ipextexturefilter.html) %Read image I = imread('szary.bmp'); figure, imshow(I); %Create texture image E = entropyfilt(I); Eim = mat2gray(E); imshow(Eim); %Create rough mask for the bottom texture BW1 = im2bw(Eim, 0.8); imshow(BW1); figure, imshow(I); BWao = bwareaopen(BW1,20000); imshow(BWao); %BW1 = im2bw(Eim, 0.715); BWao = bwareaopen(BW1,2000); %BW1 = im2bw(Eim, 0.784); BWao = bwareaopen(BW1,2000); %BW1 = im2bw(Eim, 0.8); BWao = bwareaopen(BW1,20000); %BW1 = im2bw(Eim, 0.87); BWao = bwareaopen(BW1,2000); imshow(BWao); imshow(BWao); imshow(BWao); imshow(BWao); nhood = true(9); closeBWao = imclose(BWao,nhood); imshow(closeBWao) roughMask = imfill(closeBWao,'holes'); %Use rough mask to segment the top texture imshow(roughMask); %figure, imshow(I); I2 = I; roughMask3d = logical(zeros(size(I2,1),size(I2,2),size(I2,3))); roughMask3d(:,:,1)=roughMask; roughMask3d(:,:,2)=roughMask; roughMask3d(:,:,3)=roughMask; I2(roughMask3d) = 0; figure, imshow(I2); E2 = entropyfilt(I2); E2im = mat2gray(E2); %E2 = mat2gray(stdfilt(I,nhood)); %E2 = rangefilt(I, ones(5)); imshow(E2im); BW2 = im2bw(E2im,graythresh(E2im)); imshow(BW2) figure, imshow(I); mask2 = bwareaopen(BW2,1000); imshow(mask2); mask23d=logical(zeros(size(mask2,1),size(mask2,2),size(mask2,3))); mask23d(:,:,1)=mask2; mask23d(:,:,2)=mask2; mask23d(:,:,3)=mask2; %Display segmentation results texture1 = I; texture1(~mask23d) = 0; texture2 = I; texture2(mask23d) = 0; imshow(texture1); figure, imshow(texture2); boun = bwperim(mask2); boundary3d=logical(zeros(size(boun,1),size(boun,2),size(boun,3))); boundary3d(:,:,1)=boun; boundary3d(:,:,2)=boun; boundary3d(:,:,3)=boun; segmentResults = I; segmentResults(boundary3d) = 255; imshow(segmentResults); Przykładowe wyniki: Na początku przedstawię dwa obrazy, które zostały prawidłowo rozwiązane przez ww. program: 1. Przykład dołączony do kodu (nie obyło się jednak bez drobnych modyfikacji w algorytmie, gdyż przedstawiony program nie dawał takich wyników, jakie były przedstawione na rysunkach): a)obraz wzorcowy b) wyznaczona granica c) wizualizacja wyniku 2. Inny przykład, znaleziony w internecie: a)obraz wzorcowy b) wyznaczona granica c) wizualizacja wyniku Teraz przedstawię przypadki, które nie zostały rozwiązane w satysfakcjonujący sposób. Postaram się także znaleźć przyczynę, dlaczego tak się stało. 3. Obraz z pracy http://www-dbv.cs.uni-bonn.de/image/example a)obraz wzorcowy b) wyznaczona granica c) wizualizacja wyniku Dyskusja: Na początku uwaga: obraz składa się z 5 różnych tekstur a ponieważ użyty algorytm potrafi dokonać podziału tylko na dwie części, więc uzyskany wynik pochodzi ze złożenia wyników trzykrotnego uruchomienia programu z różnymi parametrami. Pojawia się tutaj pierwszy mankament metody – należy ręcznie dopasować wartość progu, aby uzyskać poszukiwany podział. Automatyczne wartości sprawdzają się tylko dla obszarów o wyraźnym zróżnicowaniu. Teraz omówię poszczególne podziały: Pierwszy podział, z najmniejszą wartością progową, który wyodrębnił dolny trójkąt. Jak widzimy, otoczył tylko jaśniejszą część tekstury, dosyć wiernie oddając granicę plam na drewnie. Zwiększanie wartości progowej powodowało dodawanie tylko elementów lewego trójkąta, jak widać algorytm większą wagę przykłada do zabarwienia niż do struktury. Niemożliwym okazało się rozdzielenie środkowego kółka od lewego trójkąta dlatego też ten podział został w wyniku pominięty. Kolejny podział także nie wyszedł zbyt dobrze. Wprawdzie mniej więcej udało się rozdzielić środek, lewy i dolny trójkąt od reszty, ale jak widzimy, dołączone zostały także elementy górnego trójkąta. W tym przypadku już nawet niewielkie zwiększenie wartości progowej powoduje dodawanie bardzo dużych obszarów górnego trójkąta a nadal nie dodaje brakujących części do środkowego koła i lewego trójkąta. Zdecydowanie najlepiej wyróżniony został obszar prawy, który osiągnąłem przy wyższej wartości progowej. Mając problemy z wyciągnięciem wniosków wpadłem na pomysł, aby pomniejszyć wejściowy rysunek dwukrotnie w programie graficznym. Rezultat przeszedł moje najśmielsze oczekiwania: a)obraz wzorcowy b) wyznaczona granica c) wizualizacja wyniku Dyskusja: Tym razem udało się wyznaczyć podziały niemal idealnie. Podział wyróżniający lewy trójkąt, jak też podział wyróżniający lewy i prawy trójkąt udało mi się dobrać niemal idealnie. Problemy pojawiły się przy innych podziałach. Trójkąt dolny udało się wyznaczyć razem z plamami, ale program zakwalifikował także kawałek górnego trójkąta. Jednak w porównaniu z poprzednim rezultatem, i tak podział jest dużo lepszy. Jedynym dużym mankamentem w tym przypadku okazała się niemożliwość rozdzielenia środkowego koła od górnego trójkąta. Co dziwne, poprzednio koło zostało utożsamione z lewym trójkątem, choć z drugiej strony oba te trójkąty poprzednia metoda zakwalifikowała jako bardzo podobne do siebie (podział był na niedokładny i występował tylko dla małego zakresu progu). Wnioski: Przed wyciągnięciem wniosków postanowiłem przetestować jeszcze jeden plik, aby upewnić się co do wniosków: a)obraz wzorcowy b) wyznaczona granica c) wizualizacja wyniku Dyskusja: Obraz został prawie idealnie (nie licząc drobnych artefaktów) podzielony na dwie części, z których jedna zawiera wyłącznie linie pionowe lub pod kątem 45 stopni. Druga zawiera pozostałe ukośne linie, na których w trakcie obracania w programie graficznym pojawił się anty-aliasing a więc różne odcienie szarości. Aby potwierdzić wyłaniającą się już hipotezę, usunąłem wszystkie odcienie i uczyniłem obraz binarnym. Oto rezultat: a)obraz wzorcowy b) wyznaczona granica c) wizualizacja wyniku Dyskusja: Jak widzimy, uczynienie obrazu całkowicie czarno-białym, mimo wyraźnie rozróżnianej przez człowieka struktury, spowodowało powstanie całkowicie losowych wyników. Wnioski: Analiza przykładu z 5 teksturami nasuwa nam wniosek, że ważniejsze od różnic w strukturze dla użytego algorytmu są różnice w barwie występujących pikseli. Jak widzieliśmy na ostatnim przykładzie, tekstury w których występowały odcienie szarości zostały pogrupowane osobno od tych, które były czarno-białe. Nie jest to do końca pełny wniosek, ale szczegółowe badanie wykracza poza zakres tego opracowania. Podsumowując, zastosowana metoda nadaje się do rozróżniania tekstur których średnia barwa jest różna a także do tekstur, których rozkład statystyczny występujących odcieni szarości jest różny. Jeśli tekstury różnią się tylko tym, że jedna została względem drugiej obrócona o pewien kąt, metoda całkowicie zawodzi.