Są dwa sposoby podejścia do tego, w zależności od preferencji.
Sposób nr 1 - Korzystanie bwareaopen
tani sposób to zrobić byłoby, aby odwrócić obraz tak, że obiekt piksele są białe zamiast czarnego, następnie wykonywanie morfologii zamykanie na obrazie i usunięcie tych obszarów, które spaść poniżej pewnej kwoty. Zamknięcie łączyłoby razem rozłączone regiony i korzystało z tego, że przyłączenie się do "struktury" wygenerowałoby region o dużym obszarze, można uzyskać próg według obszaru każdego regionu i wyeliminować te regiony, które spadną poniżej pewnej kwoty.
Następnie można przywrócić oryginalny obraz, po prostu wykonując logiczny AND
z odwróconym obrazem i zamkniętym wynikiem, a następnie ponownie odwracając ten wynik pośredni. Efektem tego będzie zatrzymanie pikseli, które należą do oryginalnego obrazu, z powodu operacji zamykania sztucznie tworzących piksele obiektów. Konkretnie, połączenie sąsiednich regionów struktury tworzy nowe piksele obiektów, a więc wykonanie AND
zapewni usunięcie tych pikseli, które nie są wspólne z oryginałem. Ponieważ jest to wykonywane na odwrocie oryginalnego wyniku, ponowne wprowadzenie powoduje powrót do pierwotnej domeny pikseli obiektów, które są czarne zamiast białe.
coś takiego:
%// Read in image from StackOverflow
im = imread('http://i.stack.imgur.com/A7iT7.png');
%// Invert image
im = ~im;
%// Define 50 x 50 structuring element and close the image
se = strel('square', 50);
out = imclose(im, se);
%// Remove regions whose areas fall below 10000 pixels
out = bwareaopen(out, 10000);
%// Remove out extraneous closing areas by ANDing with inverted image
%// then reinvert to bring back to original label scheme
out = ~(im & out);
%// Show the image
imshow(out);
Dostajemy to zdjęcie:
Uwagi
- Funkcja
imclose
wykona morfologicznej zamknięcie dla ciebie z elementem wpływającym zdefiniowane przez strel
. Użyłem kwadratu 50 x 50, aby upewnić się, że mamy wystarczająco duże okno, aby połączyć razem sąsiednie piksele obiektów.
- Funkcja
bwareaopen
przyjmuje obraz binarny i usuwa regiony, których obszary pikseli spadają poniżej pewnej ilości. Po zamknięciu będziesz miał dwa połączone obszary - górną część obrazu ze strukturą i dolną z tekstem. Przez eksperymentowanie 10000 pikseli usunęło region na dole.
Metoda # 2 - Korzystanie regionprops
Podobne do Sposób nr 1, alternatywna metoda aby to zrobić i jest próg agnostycznego jest pójść z oryginalnego pomysłu. Wykonaj operację zamykania, a następnie oceń obszary każdego z połączonych regionów i wybierz obszar o największym obszarze. To, co polecam, to użycie w tym przypadku regionprops
, która jest specjalnie zaprojektowana do analizy charakterystyk różnych obszarów obrazu. Wyjście będzie strukturą elementów N
, gdzie N
jest całkowitą liczbą unikalnych i połączonych obiektów znalezionych w obrazie, a każda struktura zawiera pola właściwości, które chcesz zmierzyć na obrazie. W twoim przypadku określ atrybuty 'Area'
i 'PixelIdxList'
, które zawierają obszary i lokalizacje głównych pikseli dla każdego regionu.
Znajdowałbyś maksymalny obszar ogólny i korzystałeś z odpowiednich lokalizacji pikseli i ustawiłeś mapę wyjściową, z którą logicznie logowałbyś się AND
.
coś takiego:
%// Read in image from StackOverflow
im = imread('http://i.stack.imgur.com/A7iT7.png');
%// Invert image
im = ~im;
%// Define 50 x 50 structuring element and close the image
se = strel('square', 50);
out = imclose(im, se);
s = regionprops(out, 'Area', 'PixelIdxList'); %// Apply regionprops
%// Find the region with the max area
[~,id] = max([s.Area]);
%// Create an output mask with the largest area
%// Make logical
out = false(size(im));
%// Set pixels from largest area
out(s(id).PixelIdxList) = true;
%// Rest of the logic from before
%// Remove out extraneous closing areas by ANDing with inverted image
%// then reinvert to bring back to original label scheme
out = ~(im & out);
%// Show the image
imshow(out);
Należy uzyskać dokładnie takie same wyniki jak w pierwszej metodzie.
Pytanie może brzmieć głupio, ale jaka jest różnica między częściami, których potrzebujesz, a częściami, których nie chcesz? Obie są liniami i znakami. Może wykryć pionową lukę (użyć sumy rzędu) i podzielić tam? Może użyć imerode do połączenia obu czarnych obszarów, a następnie podzielić na bwlabel? – Daniel