6

Mam problemy z uzyskanie prawidłowej segmentacji obrazu w skali szarości:Segmentacja obrazu w skali szarości

Image to be segmented

Prawda gruntowych, czyli to, co chciałbym segmentacji wyglądać, to:

Ground truth

Jestem najbardziej zainteresowany trzema komponentami w kręgu. Tak więc, jak widać, chciałbym podzielić górny obraz na trzy komponenty: dwa półokręgi i prostokąt między nimi.

Próbowałem różnych kombinacji dylatacji, erozji i rekonstrukcji, a także różnych algorytmów grupowania, w tym k-średnich, izodatek i mieszaniny gaussów - wszystkie z różnym stopniem sukcesu.

Wszelkie sugestie będą mile widziane.

Edytuj: oto najlepszy wynik, jaki udało mi się uzyskać. Osiągnięto to za pomocą aktywnego konturu segmencie kołowym ROI, a następnie stosując Isodata klastrów:

Clusters

Istnieją dwa problemy:

  • białą obwódką klastra prawym dolnym , należące do lewego górnego klastra
  • Szara aureola wokół górnej i prawej i dolnej lewej gromady, należącej do centralnego klastra.
+0

Wygląda na to, ze masz tri-modal histogram. Sprawdź moją odpowiedź na stronie dsp.stackexchange.com -> http://dsp.stackexchange.com/questions/3643/image-segmentation-issue-of-different-materials/3650#3650. W każdym razie Twoje pytanie powinno zostać przeniesione na tę stronę. –

+0

Próbowałem segmentacji opartej na histogramie. Problem z tym podejściem polega na tym, że wartości pikseli otaczających najbardziej prawy klaster są najbardziej podobne do pikseli w lewym skrajnym skupieniu, co powoduje powstanie "halo" wokół prawostronnego skupienia. – Richard

+0

Czy próbowałeś bwboundaries, lub bwlabel? Mogą ci pomóc. Ale jeśli efekt halo jest zbyt duży, możesz nie uzyskać pożądanych rezultatów. Mimo to, z pewną manipulacją i czyszczeniem przed i po, możesz dostać to, czego chcesz. Może również pomóc użyć czegoś w rodzaju [kręgu hough] (http://www.mathworks.com/matlabcentral/fileexchange/26978-hough-transform-for-circles/content/html/circle_houghdemo.html) lub innych metod takich jak [ten] (http: //blogs.mathworks.com/pick/2008/05/23/detecting-circles-in-an-image /), dzięki czemu znasz granice swojego kręgu. – Bill

Odpowiedz

7

Oto rozrusznik ... użyj circular Hough transform, aby znaleźć okrągłą część. Do tego początkowo threshold the image locally.

im=rgb2gray(imread('Ly7C8.png')); 
imbw = thresholdLocally(im,[2 2]); % thresold localy with a 2x2 window 
% preparing to find the circle 
props = regionprops(imbw,'Area','PixelIdxList','MajorAxisLength','MinorAxisLength'); 
[~,indexOfMax] = max([props.Area]); 
approximateRadius = props(indexOfMax).MajorAxisLength/2; 
radius=round(approximateRadius);%-1:approximateRadius+1); 
%find the circle using Hough trans. 
h = circle_hough(edge(imbw), radius,'same'); 
[~,maxIndex] = max(h(:)); 
[i,j,k] = ind2sub(size(h), maxIndex); 
center.x = j;  center.y = i; 

figure;imagesc(im);imellipse(gca,[center.x-radius center.y-radius 2*radius 2*radius]); 
title('Finding the circle using Hough Trans.'); 

enter image description here

wybrać tylko to, co znajduje się wewnątrz okręgu:

[y,x] = meshgrid(1:size(im,2),1:size(im,1)); 
z = (x-j).^2+(y-i).^2; 
f = (z<=radius^2); 
im=im.*uint8(f); 

EDIT:

szukać miejsca do rozpoczęcia progu obrazu do segmentu go patrząc na histogram, znajdowanie pierwszych lokalnych maksimów i iterowanie stamtąd aż do znalezienia 2 oddzielnych segmentów, używając bwlabel:

p=hist(im(im>0),1:255); 
    p=smooth(p,5); 
    [pks,locs] = findpeaks(p); 

    bw=bwlabel(im>locs(1)); 
    i=0; 
    while numel(unique(bw))<3 
    bw=bwlabel(im>locs(1)+i); 
    i=i+1; 
    end 


imagesc(bw); 

enter image description here

środkowa część może teraz zostać pobrane poprzez zaciągnięcie dwóch oznakowanych części z okręgu, a to co pozostanie będzie środkowa część (+ niektóre halo)

bw2=(bw<1.*f); 

ale po pewnym mediana filtrowanie możemy dostać coś więcej reasonble

bw2= medfilt2(medfilt2(bw2)); 

i razem otrzymujemy:

imagesc(bw+3*bw2); 

enter image description here

Ostatnia część jest prawdziwa „quick and dirty” Jestem pewien, że z narzędziami już używany dostaniesz lepsze wyniki ...

+0

Bardzo ładne, dziękuję za poświęcenie czasu, aby wymyślić to. Jednak wynik zależy w dużej mierze od wartości progowej, w tym przypadku 186. Na przykład wartość 183 znacząco zniekształca wynik. Zdaję sobie sprawę, że nie określiłem tego w moim pytaniu, ale jest to tylko typowy przykład problemu; istnieje wiele innych obrazów, które wymagają podobnej segmentacji. Dlatego miałem nadzieję wymyślić zautomatyzowane, ogólne rozwiązanie. Być może jest jakiś sposób na "odgadnięcie" parametru progowego. – Richard

+0

Istnieje kilka sposobów, aby to zrobić, zobacz moją edycję na szybki, brudny sposób automatycznego ustawiania progu, który nie jest daleko od tego, co miałem wcześniej ... – bla

1

Można również uzyskać przybliżony wynik za pomocą watershed transformation. Jest to przełom w odwrócony obraz -> przełom (255 I) Oto przykład wynik:

enter image description here

inny prosty sposób jest przeprowadzenie morfologiczne zamykającą na oryginalnym obrazie z elementem strukturę płyty (można wykonać zamknięcie wieloskalowe dla granulometrii), a następnie uzyskać pełne koło. Po tym ekstrakcji koło jest łatwiejsze, a komponenty są łatwiejsze.

se = strel('disk',3); 
Iclo = imclose(I, se);% This closes open circular cells. 
Ithresh = Iclo>170;% one can locate this threshold automatically by histogram modes (if you know apriori your cell structure.) 
Icircle = bwareaopen(Ithresh, 50); %to remove small noise components in the bg 

enter image description here

Ithresh2 = I>185; % This again needs a simple histogram. 

enter image description here

Powiązane problemy