Znajdowanie kwadratów w obrazie

34

Muszę znaleźć kwadraty na obrazie przy użyciu OpenCV (bez problemu w Matlabie lub innym, ogólnie rzecz biorąc, oczekuję kilku pomysłów).

Rozważ poniższy obraz testowy:

wprowadź opis zdjęcia tutaj

Muszę dokładnie znaleźć te kolorowe kwadraty na powyższym obrazku (nie białe długie paski).

Co zrobiłem:

  • Zastosowałem wspólną metodę (która jest dostarczana z próbkami OpenCV), tj. Znajdź kontury we wszystkich płaszczyznach kolorów, przybliż ją i sprawdź liczbę elementów = 4. Działa do pewnego stopnia, że ​​wykryto kilka kwadratów, szczególnie ciemnych.

  • Następnym krokiem było przewidywanie . tzn. to ustawienie jest ustalone . Jeśli więc niektóre zostaną uzyskane, mogę przewidzieć pozostałe. Działa również w pewnym stopniu. Ale dokładność była bardzo zła.

Ale wydaje mi się, że przewidywanie nie jest tutaj dobrą metodą i nie zawsze zapewnia dokładne odpowiedzi podane w pierwszym kroku.

Czego potrzebuję :

1) Czy istnieją inne lepsze metody dokładniejszego wykrywania tych kwadratów? Lub wiele metod?

Ważną kwestią jest to, że czas nie jest tutaj problemem . Algorytm może być powolny, to nie ma znaczenia. Ale dokładność jest głównym kryterium.

Czasami obrazy mogą być znacznie bardziej rozmyte.

Jednym z głównych problemów, z którymi się spotkałem, jest to, że niektóre kwadraty mają prawie podobny kolor jak tło (sprawdź kolumnę 3 pierwszy i drugi kwadrat).

Poszukuję pomysłów, z góry dziękuję

AKTUALIZACJA :

Poniżej znajduje się maksymalny dokładny wynik, jaki otrzymałem:

wprowadź opis zdjęcia tutaj

Oczywiście obraz wynikowy jest nieco przeskalowany.

AKTUALIZACJA 2:

W mojej odpowiedzi podałem znacznie lepsze rozwiązanie: https://dsp.stackexchange.com/a/7526/818

Abid Rahman K.
źródło
czy twoje tło jest zawsze białawe?
1
moim pomysłem było obliczenie „nasycenia” i przekroczenie progu nasycenia, ale na twoim przykładzie nie działa ono zbyt dobrze (obliczanie nasycenia jako maksimum (RG, RB, GB). Fakt, że niektóre kwadraty wyglądają prawie jak tło, sprawia, że rzecz jest dość trudna. Jeśli wszystkie twoje obrazy mają ten sam wzór (długie białe paski z kwadratami obok nich), powinieneś rozważyć znalezienie najłatwiejszych fragmentów (takich jak naprawdę kolorowe kwadraty lub białe paski), aby ustalić możliwą lokalizację dla innych kwadraty i ... znajdź sposób, aby sprawdzić, czy naprawdę tam są, czy nie. Trudne, ale interesujące! Czy możesz podać więcej zdjęć?
Cóż, myślę, że to nie powinno było zostać przeniesione.
Junuxx,
1
Czy możesz podać więcej zdjęć? Co to jest?
Andrey Rubshtein
2
OP musi odpowiedzieć na kilka pytań. Może białe tło nie jest konieczne. A co słychać ze światłem? Czy będzie tak źle? Wyglądają mi na niepotrzebną złożoność.
Tae-Sung Shin

Odpowiedzi:

9

Pierwsza próba użycia Matlaba:

im = imread('squares.jpg');
im2 = rgb2gray(im);

se = strel('disk', 15);

for i = 1:16;
    t = 60+i*5; % try out a range of bw thresholds to see what works best
    labelled = bwlabel(im2>t); % label regions in the BW image
    closed = imclose(labelled, se); % close small regions
    cleared = imclearborder(~closed,4); % clear regions touching the border
    subplot(4,4,i); 
    imshow(cleared); 
    title(['T = ' num2str(t)]);
end

Wyniki w następujących regionach:

regiony oznaczone

Jak widać, wybranie progu, który daje największą liczbę regionów (T = 120), dałoby już 7 poprawnych lokalizacji, niektóre scalone lokalizacje, jeden fałszywie dodatni i dwa fałszywie ujemne.

To była dość prosta próba, ale myślę, że pokazuje, że to podejście działa. Dodanie pewnych elementów w celu rozbicia podłużnych regionów lub zrobienie tego dla każdego kanału koloru osobno to tylko kilka rzeczy, które możesz zrobić, aby to poprawić.

Byłoby to również pomocne, jeśli podałeś jeszcze kilka zdjęć testowych.

Junuxx
źródło
8

Próbowałem czegoś innego, aby poprawić mój wynik. Poniżej znajduje się założenie, że pierwszy krok (pomarańczowy) jest zawsze wykrywany w kroku 1. I jest to praktyczne ze względu na jego wysoki kontrast koloru w porównaniu do tła. Nawet pokazany przeze mnie wynik poprawnie go wykrył

Krok 1: Znajdź jak najwięcej kwadratów

Podzieliłem obraz na płaszczyzny R, G, B, H, S, V i ustawiłem próg obrazu dla różnych wartości progowych, takich jak wielokrotności 25. Dla każdego obrazu znalazłem w nim kwadraty i umieściłem je na „obrazie maski” . Znalazłem też średnią wysokość i szerokość kwadratu.

obraz maski (Wykryto ogółem 7/12 kwadratów):

obraz maski

Krok 2: Utwórz siatkę kwadratów

Następnie znalazłem centroidy tych kwadratów na obrazku maski. Posortowałem je i znalazłem środek ciężkości pierwszego kwadratu (pomarańczowy). Z dokładnej analizy wynika, że ​​odstęp między dwoma kwadratami jest kwadratem zarówno w kierunku poziomym, jak i pionowym. W ten sposób utworzyłem siatkę kwadratów jak poniżej i nazwałem ją ideal_squares (to tylko nazwa, to nie znaczy, że to wynik, którego potrzebuję):

ideal_squares:

idealny obraz

Krok 3: Przypisz idealny_ obraz

Teraz mamy centroidy ideal_squares i oryginalne centroidy. Znalazłem prawidłowe dopasowania dla każdego oryginalnego centroidu z ideal_centroidów (biorąc odległość euklidesową między nimi). Następnie użyłem Scipy interpolate.griddata do interpolacji i odwzorowałem ideal_image zgodnie z wartościami centroidów (jest to prawie to samo, co wypaczenie wykonane w tych pytaniach i odpowiedziach: Jak usunąć defekty wypukłości w kwadracie sudoku i transformacji obrazu w OpenCV ). Więc poniżej mam wynik:

Wyjście:

Obraz wyjściowy

Krok 4: LUB działaj powyżej wyjścia z obrazem maski z pierwszego kroku

końcowy wynik

Teraz możesz zobaczyć, że wszystkie kwadraty zostały wykryte, ale z problemem wymienionym poniżej:

Problem:

Spójrz na wynik kroku 3, tj. Odwzorowany obraz kwadratowej siatki. Z wyjątkiem dwóch centralnych kwadratów, wszystkie pozostałe kwadraty są obcinane. Jest to problem związany z tym mapowaniem. Nie jestem pewien, gdzie jest problem z scipy.interpolate.griddata () lub cv2.remap (). Myślałem, że cały obraz będzie wypaczony, ale tak nie jest. Wypacza tylko obraz wewnątrz podanych przez nas centroidów. Jeśli mogę to naprawić, wynik będzie OK.

Jeśli więc ktoś zna dobry pomysł, zapraszamy!

Abid Rahman K.
źródło
5

Uwaga: Ta metoda będzie bardzo powolna.

Wygeneruj maskę, która wygląda jak kontury idealnego obiektu. Podobnie do tego:

maska ​​obiektu

następnie przesuń (pozycję, skalę, obrót) maskę nad obrazem i dopasuj ją do konturu obrazu rzeczywistego (być może nieco rozmazanego, aby uzyskać łagodniejszą reakcję), aby obliczyć, jak są one podobne (pozycja, skala, obrót) z najwyższą odpowiedzią na podobieństwo powinna być (pozycja, skala, obrót) rzeczywistego obiektu.

Metoda nie ma nic przeciwko wtapianiu się kwadratów w tło lub nawet częściowej okluzji obiektu, ponieważ uwzględnia cały obiekt.

Osobiście z powodzeniem zastosowałem tę metodę do śledzenia pyska myszy i wąsów, ale miałem pewne domniemania, że ​​była blisko ostatniej znanej pozycji itp. Ale myślę, że możesz zmniejszyć przestrzeń poszukiwań, stosując pewne założenia, takie jak: możliwe rozmiary obiektu w kamerze, jak daleko może być od środka, czy obrót <10 stopni itp.

SlimJim
źródło
5

Krok 1: Jakikolwiek końcowy obraz binarny otrzymujesz z analizy w płaszczyźnie B, G, R, H, S, V, na tym obrazie wykonaj algorytm zliczania kropel.

Krok 2: Znajdź największą kroplę na podstawie powierzchni lub długości konturu. Ponieważ twoje plamy będą głównie typami równoległoboków, czyli obszarami lub konturami, każdy to zrobi.

Krok 3: Z największą kroplą (ponieważ największa kropelka jest najlepszą kroplą przypominającą kwadraty z prawdziwego świata), spróbuj znaleźć orientację kropli ... możesz to uzyskać dopasowując najlepiej dopasowany prostokąt LUB możesz uzyskać punkty narożne ... uzyskaj nachylenie łączących je linii (zarówno w kierunku poziomym, jak i pionowym).

Krok 4: Po uzyskaniu dwóch stoków narysuj dwie linie przebiegające przez oś kropli. dla osi można uśrednić punkty narożne lub użyć środka ciężkości (środka masy) ... Wybrałbym średnią punktów narożnych ...

Krok 5: Ponieważ w każdym kierunku poziomym i pionowym odstępy są równe (idealnie poziome i pionowe odstępy są również równe, ponieważ pochodzi z idealnego kwadratu, ale nie zakładamy, że ..) wystarczy zlokalizować możliwe centroidy drugiego równoległoboki

LINIA DOLNA: Jeśli jakikolwiek kwadrat zostanie wykryty idealnie, możesz wykonać całą siatkę. Po prostu utrzymuj środki znakowania w odstępach 2H (H = pozioma szerokość największego obiektu blob) wzdłuż poziomej osi największego obiektu blob i w odstępie 2 V (V = wysokość pionowa największego obiektu blob) pionowo wzdłuż osi pionowej obiektu blob.

Niektóre zdjęcia do wsparcia wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

rotating_image
źródło
1
+1 - Byłoby wspaniale, gdybyś mógł go wdrożyć.
Abid Rahman K
2
@AbidRahmanK Nie po to jest StackExchange. Pytanie -> Odpowiedź. W przeciwnym razie skończyłoby się to targami pracy.
Jan Krüger
2

to ustawienie jest ustalone

Naprawdę nie wiem, jakie przewidywałeś wcześniej, ale czy próbowałeś skupić się na białych długich paskach jako korzeniu. Następnie (jeśli 3 kolumny kwadratów mają równe rozmiary), możesz wykryć wysokość kwadratu (odległość między dwoma paskami) i możesz wykryć maksymalny i minimalny obszar (wysokość i szerokość) na obrazie.

Następnie spróbuj wykryć najczęstszy kolor w całym kwadracie i ustawić go na obszarze „innym niż kwadrat”. Reszta to kwadraty, których szukasz.


źródło
Znalazłem 3-4 kwadraty metodą konturu. Potem dostałem wysokość i szerokość każdego kwadratu. Następnie sprawdzono lukę między wykrytymi kwadratami i zakładano, czy przerwa między nimi jest wystarczająco duża, aby pomieścić kolejny kwadrat. Taką prognozę zrobiłem.
Abid Rahman K
Niektóre kwadraty mają prawie podobny kolor jak tło. Obawiam się, że zgodnie z twoją metodą będą one również traktowane jako obszar nie kwadratowy.
Abid Rahman K
Być może mógłbyś spróbować pracy na każdej kolumnie, aby wykreślić krzywą, w której oś x byłaby wysokością (w pikselach) na obrazie, a oś y byłaby intensywnością. Następnie możesz spróbować znaleźć krawędzie tnące w formie pochodnej.
to jest samo wykrywanie krawędzi, prawda? Próbowałem, ale nie uzyskałem dobrego wyniku.
Abid Rahman K
1
Tak, ale możesz sam przekonać się, dlaczego zawodzi, i może wyizolować kilka interesujących regionów na fabule. Nawiasem mówiąc, jeśli znajdziesz przydatne wskazówki, które pomogą rozwiązać problem, opublikuj je. Powodzenia dla twoich badań
0

Sugerowałbym użycie transformaty Hougha, która jest bardzo solidnym algorytmem do znajdowania prostych kształtów parametrycznych, np. Linii, okręgów itp. Wykrywanie linii byłoby najlepsze w twoim przypadku. Można było znaleźć przynajmniej boki długich białych sripów; następnie za pomocą dowolnego algorytmu do wyodrębniania narożników (Harris, a może nawet SIFT lub SURF) można znaleźć rogi wzdłuż tych linii, nawet korzystając z faktu, że kwadraty są w przybliżeniu jednakowo rozmieszczone.

Canahari
źródło