2012-06-18 26 views

Odpowiedz

4

Problem polega na odróżnieniu dziur od cyfr. Możliwym rozwiązaniem ad hoc jest filtrowanie ich przez obszar pikseli wewnątrz.

function SolveSoProblem() 

    I = imread('http://i.stack.imgur.com/SUvif.png'); 

    %Fill all the holes 
    F = imfill(I,'holes'); 

    %Find all the small ones,and mark their edges in the image 
    bw = bwlabel(I); 
    rp = regionprops(bw,'FilledArea','PixelIdxList'); 
    indexesOfHoles = [rp.FilledArea]<150; 
    pixelsNotToFill = vertcat(rp(indexesOfHoles).PixelIdxList); 
    F(pixelsNotToFill) = 0; 
    figure;imshow(F); 

    %Remove the inner area 
    bw1 = bwlabel(F,4); 
    rp = regionprops(bw1,'FilledArea','PixelIdxList'); 
    indexesOfHoles1 = [rp.FilledArea]<150; 
    pixelListToRemove = vertcat(rp(indexesOfHoles1).PixelIdxList); 
    F(pixelListToRemove) = 0; 

    figure;imshow(F); 
end 

Po etapie (1):

enter image description here

Po etap (2):

enter image description here

+0

roztwór wywołujący. Wielkie dzięki! Jedyną małą rzeczą, którą zmieniłem, było usunięcie obiektów, których przestrzeń jest mniejsza niż 2 proc. Obrazu i działa świetnie! – user1240792

0

Zakładając lewym górnym piksel jest zawsze poza regiony do wypełnienia:

Praca w poprzek górnej linii, kopiowanie pikseli w obrazie wyjściowym

Kiedy dojdziesz do białego piksela następnie czarnego piksela obrazu wejściowego, rozpocząć ustawianie białych pikseli w obrazie wyjściowym, aż dojdziesz do czarny piksel, a następnie biały piksel.

+3

Nie będzie działać dla "hałaśliwego obrazu" ... –

+0

@EitanT: Prawda - podałem próbkę. –

+1

@MartinThompson obrazy są binarne, więc otrzymany komentarz jest nieistotny. – mmgp

6

Inną możliwością jest użycie funkcji BWBOUNDARIES, który:

ślady zewnętrznych granic obiektów, jak również granice otworami wewnątrz tych obiektów

Ta informacja jest zawarta w czwarte wyjście A, macierz sąsiedztwa, która reprezentuje zależności między rodzicem a dzieckiem.

%# read binary image 
bw = imread('SUvif.png'); 

%# find all boundaries 
[B,L,N,A] = bwboundaries(bw, 8, 'holes'); 

%# exclude inner holes 
[r,~] = find(A(:,N+1:end));  %# find inner boundaries that enclose stuff 
[rr,~] = find(A(:,r));      %# stuff they enclose 
idx = setdiff(1:numel(B), [r(:);rr(:)]); %# exclude both 
bw2 = ismember(L,idx);      %# filled image 

%# compare results 
subplot(311), imshow(bw), title('original') 
subplot(312), imshow(imfill(bw,'holes')), title('imfill') 
subplot(313), imshow(bw2), title('bwboundaries') 

enter image description here

+0

Nice! Miałem wrażenie, że musi istnieć funkcja Matlab, która to robi, ale jej nie znała –