Podczas zabawy ze znajdowaniem rzeczy na ekranie graficznym, nie mam pojęcia, jak znaleźć dany kształt w obrazie. Kształt na obrazku może mieć inną skalę i będzie oczywiście przy nieznanym przesunięciu x, y.Rozpoznawanie podobnych kształtów w losowej skali i tłumaczeniu
Oprócz artefaktów pikseli pochodzących z różnych skal, na obu zdjęciach występuje również niewielki hałas, więc potrzebuję nieco tolerancyjnego wyszukiwania.
Oto obraz, którego szukam.
Powinna pokazać się gdzieś w zrzucie ekranu mojego bufora (podwójna) ekranem, około 3300 x 1200 pikseli. Oczywiście spodziewam się, że znajdę go w oknie przeglądarki, ale ta informacja nie powinna być konieczna.
Celem tego ćwiczenia (do tej pory) jest wymyślić wyniku, który mówi:
- Tak, drewniana rama (tej przybliżonej kolorze i że ewentualnie lekko ścięty, kształt) została znaleziona na moim ekranie (lub nie); i
- obszar roboczy gry (czarny obszar wewnątrz ramki) zajmuje prostokąt od
(x1,y1)
do(x2,y2)
.
Chciałbym być odporny na skalowanie i hałas, który prawdopodobnie zostanie wprowadzony przez dithering. Z drugiej strony mogę wykluczyć niektóre zwykłe wyzwania związane z CV, takie jak rotacja czy brak sztywności. Ten kształt ramki jest łatwy do zrozumienia dla ludzkiego mózgu, jak trudny może być dla dedykowanego oprogramowania? Jest to aplikacja Adobe Flash i do niedawna uważałem, że postrzeganie obrazów z GUI gry powinno być łatwe jak ciasto.
Szukam algorytmu, który jest w stanie znaleźć translację x, y, przy której występuje największe możliwe nakładanie się igły i stogu siana, i jeśli to możliwe, bez konieczności przeprowadzania iteracji przez szereg możliwych współczynników skalowania. W idealnej sytuacji algorytm może wykluczyć "kształtowanie" obrazów w sposób niezależny od skali.
Przeczytałem kilka interesujących rzeczy o transformacjach Fouriera, aby osiągnąć coś podobnego: Biorąc pod uwagę obraz docelowy w tej samej skali, FFT i matematyka macierzowa oddały punkty w większym obrazie, który odpowiadał wzorcowi wyszukiwania. Ale nie mam podstaw teoretycznych, aby to zastosować, ani też nie wiem, czy to podejście z wdziękiem poradzi sobie z problemem skali. Pomoc byłaby doceniona!
Technologia: programuję w Clojure/Java, ale mogę dostosować algorytmy w innych językach. Myślę, że powinienem być w stanie łączyć się z bibliotekami, które stosują konwencje wywoływania C, ale wolałbym czyste rozwiązanie Javy.
Być może będziesz w stanie zrozumieć, dlaczego odrzuciłem prezentowanie rzeczywistego obrazu. To tylko głupia gra, ale zadanie jej czytania na ekranie okazuje się o wiele trudniejsze, niż myślałem.
Oczywiście jestem w stanie przeprowadzić wyczerpujące wyszukiwanie bufora ekranowego dla samych pikseli (z wyjątkiem czarnego), które tworzą mój obraz, a to nawet trwa poniżej minuty. Moją ambicją było jednak odnalezienie drewnianej ramy za pomocą techniki pasującej do kształtu, niezależnie od różnic, które mogą powstać w wyniku skalowania i ditheringu.
Roztrząsanie jest jedną z wielu frustracji związanych z tym projektem. Pracowałem nad wyodrębnianiem niektórych użytecznych wektorów przez ekstrakcję krawędzi, ale krawędzie są żałośnie nieuchwytne, ponieważ piksele z dowolnego obszaru mają bardzo niespójne kolory - tak więc trudno odróżnić prawdziwe krawędzie od lokalnych artefaktów ditheringu. Nie miałem pojęcia, że taka prosta gra będzie produkować grafiki, które są tak trudne do postrzegania przez oprogramowanie.
Czy powinienem zacząć od lokalnych uśredniania pikseli, zanim zacznę szukać funkcji? Czy powinienem zmniejszyć głębię kolorów, wyrzucając najmniej znaczące bity wartości kolorów pikseli?
jestem próbuje dla czystego roztworu Java (faktycznie Programowanie w mieszance Clojure/Java), więc nie jestem dzikie o OpenCV (który instaluje DLL lub .so-tych z kodem C). Proszę nie martwić się o mój wybór języka, doświadczenie uczenia się jest dla mnie o wiele bardziej interesujące niż wydajność.
Nie jest jasne, z jakiego rodzaju częstotliwości korzysta użytkownik. Moim zdaniem, biorąc pod uwagę problem, jest porównanie za pomocą deskryptorów Fouriera. Można je łatwo przekształcić w niezmienną rotację, tłumaczenie i skalę, co pomaga w rozwiązaniu problemu. Zaczynasz od wyodrębnienia każdego z konturów połączonych komponentów w obrazie binarnym, a następnie próbkowania każdego z nich i określenia deskryptorów Fouriera. To samo dotyczy obrazu "igłowego". Następnie możesz spróbować dopasować kształty za pomocą tych deskryptorów. Ale istnieje wiele innych metod tego zadania, w zależności od innych ukrytych (zapomnianych) wymagań. – mmgp
Sprawdź również SIFT i SURF, jeśli algorytmy te nie są ci znane; Książka Gary'ego Bradskiego Learning OpenCV może dostarczyć wskazówek. Kilka komercyjnych bibliotek wizji ($$) ma implementacje "solidnego dopasowania kształtu", które upraszczają konfigurację. http://en.wikipedia.org/wiki/SURF – Rethunk
Carl, czy mógłbyś zamieścić kilka oryginalnych przykładowych zdjęć (i/lub link do archiwum przykładowych obrazów)? Szukasz niezawodnego rozwiązania, łatwego rozwiązania, fajnego/złożonego rozwiązania do testowania lub "optymalnego" rozwiązania (dla jakiegoś problemu domeny/rynku)? Istnieją deskryptory statystyczne, deskryptory Fouriera, itp., Ale są też techniki, które mogą być nieco łatwiejsze do opanowania i mogą działać wystarczająco dobrze dla twojego celu. (Zmienilem też twoje pytanie, aby dodać "opencv" i "przetwarzanie obrazu", aby uzyskać nieco więcej uwagi.) – Rethunk