Mam binarne obrazy 160 x 120, takie jak:
Chciałbym wykryć rogi tych białych plam. Są one wcześniej zamknięte przez morfologię matematyczną, więc nie powinny mieć żadnych wewnętrznych narożników. W tym konkretnym przypadku chciałbym 16 narożników, takich jak:
Moja pierwsza próba polegała na użyciu niektórych funkcji OpenCV, takich jak goodFeaturesToTrack lub FAST, ale są one szczególnie wolne (plus FAST jest bardzo niestabilny). Moim pomysłem byłoby wykonanie takiego obliczenia na GPU, ponieważ pochodzi z niego mój obraz źródłowy. Szukałem w Internecie pomysłów na pisanie takich shaderów (używam OpenGL ES 2.0), ale nie znalazłem nic konkretnego. Masz pomysł, jak mogę uruchomić taki algorytm?
image-processing
computer-vision
Stéphane Péchard
źródło
źródło
Odpowiedzi:
Na jakich rozmiarach pracujesz? Przy jakiej liczbie klatek? Na jakim sprzęcie? Z mojego doświadczenia wynika, że FAST jest ładna, eee, szybka.
Widziałem też FAST używany jako wykrywacz ROI z goodFeaturesToTrack działający na zidentyfikowanych ROI, aby zapewnić lepszą stabilność bez uruchamiania kary gFTT na całym obrazie.
„Harris” detektor rogu jest również potencjalnie bardzo szybki, ponieważ składa się z bardzo prostych operacji (nr sqrt () na piksel na przykład!) - nie tak stabilny jak gFTT, ale być może bardziej, niż szybko.
(Pod względem implementacji GPU Googling
gpu corner
wydaje się prezentować całkiem sporo linków, ale nie mam pojęcia, jak mogą być odpowiednie - zazwyczaj wdrażam w FPGA.)źródło
Właśnie zdarzyło mi się implementować coś takiego w OpenGL ES 2.0 przy użyciu wykrywania narożników Harrisa i chociaż nie jestem całkowicie ukończony, pomyślałem, że podzielę się implementacją opartą na modułach cieniujących, którą do tej pory miałem. Zrobiłem to jako część platformy open source opartej na iOS , więc możesz sprawdzić kod, jeśli jesteś ciekawy, jak działa jakiś konkretny krok.
Aby to zrobić, wykonuję następujące kroki:
Oblicz pochodne X i Y, odejmując wartości kanału czerwonego od pikseli po lewej i prawej oraz powyżej i poniżej bieżącego piksela. Następnie przechowuję pochodną x podniesioną do kwadratu w kanale czerwonym, pochodną Y podniesioną do kwadratu w kanale zielonym, a iloczyn pochodnych X i Y w kanale niebieskim. Moduł cieniujący fragmenty wygląda następująco:
gdzie różnice są tylko przesuniętymi współrzędnymi tekstury w każdym kierunku. Obliczam je wstępnie w module cieniującym wierzchołki, aby wyeliminować zależne odczyty tekstur, które są bardzo powolne na tych mobilnych GPU.
Zastosuj rozmycie gaussowskie do tego obrazu pochodnego. Użyłem oddzielnego rozmycia poziomego i pionowego i skorzystałem ze sprzętowego filtrowania tekstur, aby uzyskać rozmycie dziewięciokrotnie z tylko pięcioma odczytami tekstury przy każdym przejściu. Opisuję ten moduł cieniujący w tej odpowiedzi Przepełnienie stosu .
Uruchom rzeczywiste obliczenie detekcji narożnika Harrisa, używając niewyraźnych wartości pochodnych wejściowych. W tym przypadku faktycznie używam obliczeń opisanych przez Alison Noble w jej doktoracie. rozprawa „Opisy powierzchni obrazu”. Moduł cieniujący, który to obsługuje, wygląda następująco:
Wykonuj lokalne nie maksymalne tłumienie i zastosuj próg, aby podświetlić piksele, które przechodzą. Używam następującego modułu cieniującego fragmenty do próbkowania ośmiu pikseli w sąsiedztwie centralnego piksela i stwierdzam, czy jest to maksimum w tej grupie:
Ten proces generuje mapę pustkowia z twoich obiektów, która wygląda następująco:
Następujące punkty są identyfikowane jako rogi na podstawie nie-maksymalnego tłumienia i progowania:
Po ustawieniu odpowiednich progów dla tego filtra może on zidentyfikować wszystkie 16 narożników na tym obrazie, chociaż zwykle umieszcza narożniki o jeden piksel wewnątrz rzeczywistych krawędzi obiektu.
Na iPhonie 4 to wykrywanie narożników można uruchomić przy 20 klatkach na sekundę na klatkach 640 x 480 wideo pochodzących z kamery, a iPhone 4S może z łatwością przetwarzać wideo o tym rozmiarze przy 60+ klatkach na sekundę. Powinno to być o wiele szybsze niż przetwarzanie związane z procesorem w przypadku takiego zadania, chociaż w tej chwili proces odczytywania punktów jest związany z procesorem i nieco wolniejszy niż powinien.
Jeśli chcesz zobaczyć to w akcji, możesz pobrać kod dla mojego frameworka i uruchomić dołączony do niego przykład FilterShowcase. Przykład wykrywania narożników Harrisa działa na wideo na żywo z kamery urządzenia, chociaż jak wspomniałem, odczyt punktów narożnych odbywa się obecnie na procesorze, co naprawdę spowalnia to. W tym celu przechodzę również do procesu opartego na GPU.
źródło
„Solidne” detektory narożne, takie jak Shi-Tomasi i Moravec, są niezwykle powolne. sprawdź je tutaj - http://en.wikipedia.org/wiki/Corner_detection SZYBKO prawdopodobnie jest jedynym wystarczająco dobrym lekkim detektorem narożnym. Możesz poprawić FAST, wykonując nie maksymalne tłumienie - wybierz wynik FAST z najlepszym wynikiem „cornerness” (istnieje kilka intuicyjnych sposobów jego obliczenia, w tym Shi-Tomasi i Moravec jako score cornerness). Masz również wybór spośród kilku detektorów FAST - od FAST-5 do FAST-12 i FAST_ER (ostatni jest prawdopodobnie zbyt duży dla urządzeń mobilnych) Innym sposobem jest wygenerowanie FAST - pobierz generator kodu FAST ze strony autora i wytrenuj go na zbiorze prawdopodobnych obrazów. http://www.edwardrosten.com/work/fast.html
źródło
Niezbyt specyficzny dla GPU, ale algorytm SUSAN Steve'a Smitha jest dobry do wykrywania zakrętów.
Algorytm jest dość prosty, jak pokazuje kod źródłowy w C.
źródło