Jak rozpoznać sześciokątne kafelki w grze planszowej?

16

Chciałbym rozpoznać granice sześciokątnej płytki na zdjęciu, jak na zdjęciu poniżej:

wprowadź opis zdjęcia tutaj

Wydaje mi się, że standardowym podejściem do kwadratowej siatki jest najpierw wykrycie narożników (np. Sprytnych), a następnie wyodrębnienie najdłuższych linii za pomocą transformaty Hougha lub czegoś podobnego.

Nie wydaje się to optymalnym rozwiązaniem z kafelkami sześciokątnymi, ponieważ długość linii zewnętrznych jest krótsza i trudno jest oddzielić je od innych linii.

Czy istnieje algorytm pozwalający rozwiązać ten problem? Szczególnie fajnie byłoby mieć rozwiązanie w opencv, ale interesują mnie również ogólne pomysły.

aktualizacja:

Dzięki pythonowi i opencv mogłem otrzymać ten wynik: kontury

Oto mój kod:

import cv2
import numpy as np

imgOrig = "test1";
img = cv2.imread(imgOrig+".jpg");  
lap = cv2.Laplacian(img, cv2.IPL_DEPTH_32F, ksize = 3)  
imgray = cv2.cvtColor(lap,cv2.COLOR_BGR2GRAY)  
ret,thresh = cv2.threshold(imgray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
size = img.shape
m = np.zeros(size, dtype=np.uint8)
for i, cnt in enumerate(contours):
    if cv2.contourArea(cnt) >= 1:
        color = (255,255,255)
        cv2.drawContours(m, cnt, -1, color, -1)
cv2.imwrite(str(imgOrig)+"contours.jpg", m);

Laplacian obrazu wygląda następująco: Laplacian

Spróbuję zoptymalizować parametry tego podejścia, a następnie spróbuję interpolować granice czterech sekcji.

snalx
źródło
5
Przetwarzanie sygnału spotyka się z grą w euro; mrugają moje zmysły maniaka!
nispio
1
Jeśli zawsze używasz planszy o tym samym rozmiarze i zawsze będziesz mieć mniej więcej taki sam widok tablicy na obrazie, możesz być w stanie rozwiązać problem tak samo, jak rozpoznanie obrysu planszy w celu ustalenia rozmiaru i rejestracji. Umieszczanie i wymiarowanie płytek jest stałe w odniesieniu do krawędzi planszy, więc kiedy wiesz, gdzie są wszystkie krawędzie, powinieneś być w stanie dokładnie określić położenie płytek wewnętrznych.
nispio
Dziękuję za twoją sugestię, @nispio. Rozmiar planszy jest cały czas taki sam, podczas gdy widok planszy może się nieco zmienić. Kolor tła jest również inny na innych zdjęciach, co prowadzi do znacznie niższego kontrastu. Jeśli na przykład tło jest beżowe, położenie konturu jest trudne do ustalenia.
snalx
1
Jeśli nie otrzymujesz żadnych innych odpowiedzi, myślę, że dobrym pomysłem jest opublikowanie zmian jako odpowiedzi na własne pytanie. Nie jestem jednak pewien, jak to wpływa na nagrodę!
lmjohns3
1
@snalx: Jeśli opublikujesz swoje odkrycia jako odpowiedź, przyznam ci nagrodę. Jednak należy to zrobić w ciągu najbliższych 12 godzin.
sty

Odpowiedzi:

6

1. podejście:

Skorzystaj z metod haartrainingowych OpenCV zgodnie z tym samouczkiem http://note.sonots.com/SciSoftware/haartraining.html - to powinno dać najlepsze wyniki, ale do tej pory nie pracowałem z haartrainingiem ...

Drugie podejście:

Sugerowałbym użycie metod „bezmarkerowego śledzenia” poszczególnych płytek planszy. Możesz to zaimplementować również za pomocą OpenCV ..

Przygotowanie

  1. W tym celu potrzebujesz kilku zdjęć każdego rodzaju kafelka. Zrób zdjęcie wszystkich rodzajów kafelków (każdy jako jedno zdjęcie), z jednorodnym tłem z kafelka z widokiem z góry na środku obrazu.

  2. Następnie użyj detektora cech (OpenCV ma do tego wiele algorytmów, ale SIFT / SURF są niewolnymi algorytmami; sugerowałbym użycie „SZYBKIEGO”), aby znaleźć wyraźne punkty na obrazach.

  3. Użyj deskryptora funkcji, aby opisać funkcję znalezioną na obrazie (użyj np. „KRÓTKI”).

Wykrycie

Teraz możesz wykryć kafelki na obrazie, stosując te same algorytmy detektora / deskryptora funkcji do tego obrazu. Po nabyciu funkcji / deskryptorów możesz zastosować FlannBasedMatcher, aby znaleźć kafelki.

Oto przykład kodu / samouczek OpenCV: http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html#feature-homography

Notatki

Metoda Matchera da ci tylko jedno dopasowanie i może mieć problemy, jeśli na planszy znajduje się więcej niż jeden kafelek tego typu. Możesz obejść ten problem, maskując tylko niektóre części obrazu wejściowego. Sugeruję to zrobić, używając współrzędnych pikseli wykrytych funkcji. Jeśli - w jakiś sposób - najpierw wykryjesz kontur i rozmiar kafelków, możesz z grubsza oszacować położenie i rozmiar kafelków na obrazie. Filtruj wykrytą listę funkcji (np. Tylko funkcje w promieniu x pikseli od oczekiwanego punktu środkowego płytki) przed dopasowaniem, a następnie użyj najsilniejszego dopasowania. W rezultacie otrzymasz dokładną pozycję kafelka na obrazie (w tym jego orientację). Jeśli wykrycie konturu mapy jest zbyt skomplikowane, możesz pozwolić użytkownikowi „wskazać” kafelki narożne, aby oznaczyć kontur ręcznie ...

Alternatywne podejście

Możesz także użyć tej metody, aby znaleźć tylko dowolny kafelek według jego obrysu. Narysuj przykładowy „schematyczny” obraz szarości płytki (sześciokąta) bez żadnego obrazu. Zauważ, że obszary „ciemne” i „jasne” na tym obrazie muszą być poprawne na schemacie, a nie tylko niektóre „linie”. Prawdopodobnie będziesz musiał z tym eksperymentować. Możesz spróbować uśrednić wiele zdjęć różnych kafelków, aby wygenerować „średni” obraz kafelka. Upewnij się, że narożniki są w tej samej pozycji (odpowiednio przesuń / skaluj obrazy) i wyostrz obraz po zakończeniu (wyraźne rogi / krawędzie powinny być widoczne) i w razie potrzeby dostosuj nieco kontrast.

SDwarfs
źródło
Dzięki za sugestię @StefanK. Martwię się trochę, czy pierwsze i drugie podejście nadal działa, jeśli elementy (domy) do gry leżą na kafelkach. Twoje alternatywne podejście wygląda obiecująco, spróbuję tego (może po trochę wstępnego przetwarzania).
snalx
W większości przypadków wydaje się, że wykrycie linii zewnętrznych jest możliwe. Ostatnio próbowałem tego z Hough transfom na zdjęciach podobnych do końcowego wyniku w moim pytaniu. Zaktualizuję moje pytanie, kiedy znajdę stabilne rozwiązanie.
snalx
Domy i inne elementy gry na kafelkach nie powinny stanowić problemu. Powoduje to objęcie niektórych „funkcji”, ale niektóre z nich nadal zostaną wykryte. Co najmniej 4 muszą być wykrywalne. Możesz wypróbować dema OpenCV z wykrywaniem funkcji i sprawdzić, ile funkcji jest wykrywanych na każdym kafelku ...
SDwarfs
3

Opiszę moje obecne podejście, które polega na wykorzystaniu zasad gry, przetwarzania obrazu i wykrywania funkcji.

Odpowiednie zasady gry

Realizacja

Najpierw używam transformacji Hougha, aby wyodrębnić pozycję planszy. Obraz źródłowy wygląda podobnie do ostatecznego obrazu, o którym mowa, ale z grubszymi liniami i przefiltrowałem mniejsze granice. Używam tylko wykrywania bardzo długich linii (rząd wielkości: około 60 procent szerokości / wysokości obrazu) i bardzo małego progu dla dopasowania linii. Patrzę też na linie na zewnętrznym 40 procentach obrazu i biorę medianę wykrytych linii na górze, dole, lewej i prawej stronie. Wynik pokazano na obrazku poniżej: Przekształcenie Hougha

Potrzebuję tylko przybliżonego przybliżenia, więc jest w porządku. Odtąd badam tylko obraz wewnątrz linii Hougha, a także dodatkowe miejsce ze względu na niepewność transformacji Hougha.

Następnie używam wykrywania funkcji, jak zaproponował Stefan K. w swojej odpowiedzi, aby wykryć cechy obrazu, których gracze nie mogą zabrać, tj. Zamki, płytki lokalizacji i góry. Używam do tego algorytmu ORB w opencv-python i BruteForce-Hamming-Matcher (nie byłem jeszcze w stanie uruchomić FlannBased Matchera). ORB jest niezmienną skalą i rotacją. Aby wykryć wiele wystąpień tych samych funkcji (np. Zamków), podzieliłem obraz na części, które się pokrywają. Działa to dobrze, ponieważ rozdzielczość obrazu jest wystarczająco duża, a zdjęcie jest robione bezpośrednio z góry (nadal wymaga testów). To także trochę powolne. Wykrywanie kafelka lokalizacji (tawerny) pokazano jako przykład na obrazku poniżej wykrywanie funkcji zamku

W tej chwili próbuję znaleźć transformację homografii, aby wyodrębnić dokładną pozycję i orientację wykrytych funkcji.

Mam nadzieję, że uda mi się zrekonstruować siatkę na podstawie tych informacji (położenie gór, zamku, kafelków lokalizacji, a w większości przypadków wody). Eksperymenty z prądami wyglądają obiecująco, choć trzeba dokładnie dopracować i odpowiednio przygotować obrazy obiektów.

snalx
źródło
Zrobiłem coś podobnego z Catanem, ale zamiast hoomografii używam średniej wartości koloru dla dowolnej płytki. Zidentyfikuj kafelek jako 6-licowy kontur poli z obróbką wstępną, aby pomóc odizolować krawędzie, a następnie przekonwertuj ten ROI na maskę, a następnie nałóż maskę bitowo_i na obraz źródłowy. Następnie możesz uzyskać średni kolor, który może wystarczyć do zidentyfikowania większości płytek, a następnie możesz wykonać dodatkowe dopasowanie wzoru. Właśnie to zacząłem: youtube.com/watch?v=0ezfyWkio6c
Rex Hardin