Ich habe binäre 160x120 Bilder wie:
Ich möchte Ecken dieser weißen Flecken erkennen. Sie wurden zuvor durch mathematische Morphologie geschlossen, sodass keine inneren Ecken vorhanden sein sollten. In diesem speziellen Fall würde ich 16 Ecken wünschen, wie:
Mein erster Versuch war die Verwendung einiger OpenCV-Funktionen wie goodFeaturesToTrack oder FAST, aber diese sind besonders langsam (und FAST ist sehr instabil). Meine Idee wäre, eine solche Berechnung auf der GPU durchzuführen, da mein Quellbild davon stammt. Ich habe im Internet nach Ideen zum Schreiben solcher Shader gesucht (ich verwende OpenGL ES 2.0), aber nichts Konkretes gefunden. Irgendeine Idee, wie ich einen solchen Algorithmus starten könnte?
image-processing
computer-vision
Stéphane Péchard
quelle
quelle
Antworten:
Mit welcher Bildgröße arbeiten Sie? Mit welcher Bildrate? Auf welcher Hardware? SCHNELL ist meiner Erfahrung nach hübsch, ähm, schnell.
Ich habe auch gesehen, wie FAST als ROI-Detektor mit goodFeaturesToTrack für die identifizierten ROIs verwendet wurde, um eine bessere Stabilität zu erzielen, ohne dass der gFTT-Nachteil für das gesamte Bild auftritt.
Der "Harris" -Eckendetektor ist möglicherweise auch sehr schnell, da er aus sehr einfachen Operationen besteht (zum Beispiel kein sqrt () pro Pixel!) - nicht so stabil wie gFTT, aber möglicherweise noch stabiler als FAST.
(In Bezug auf die GPU-Implementierung
gpu corner
scheint Googeln eine Menge Links zu bieten , aber ich habe keine Ahnung, wie geeignet sie sein könnten - ich tendiere dazu, sie in FPGA zu implementieren.)quelle
Ich habe gerade so etwas auf OpenGL ES 2.0 mithilfe der Harris-Eckenerkennung implementiert, und obwohl ich noch nicht vollständig fertig bin, dachte ich, ich würde die bisherige Shaderbasierte Implementierung teilen. Ich habe dies als Teil eines iOS-basierten Open-Source-Frameworks durchgeführt , sodass Sie den Code überprüfen können, wenn Sie neugierig sind, wie ein bestimmter Schritt funktioniert.
Dazu benutze ich die folgenden Schritte:
Berechnen Sie die X- und Y-Ableitungen, indem Sie die Rotkanalwerte von den Pixeln links und rechts sowie über und unter dem aktuellen Pixel subtrahieren. Ich speichere dann das Quadrat der x-Ableitung im roten Kanal, das Quadrat der Y-Ableitung im grünen Kanal und das Produkt der X- und Y-Ableitungen im blauen Kanal. Der Fragment-Shader dafür sieht folgendermaßen aus:
wobei die Abweichungen nur die versetzten Texturkoordinaten in jeder Richtung sind. Ich berechne diese im Vertex-Shader vor, um abhängige Textur-Lesevorgänge zu eliminieren, die auf diesen mobilen GPUs notorisch langsam sind.
Wenden Sie eine Gaußsche Unschärfe auf dieses abgeleitete Bild an. Ich habe eine getrennte horizontale und vertikale Unschärfe verwendet und die Hardware-Texturfilterung genutzt, um eine Unschärfe mit neun Treffern mit nur fünf Texturlesevorgängen bei jedem Durchgang zu erzielen. Ich beschreibe diesen Shader in dieser Stack Overflow-Antwort .
Führen Sie die tatsächliche Harris-Eckenerkennungsberechnung mit den Werten der unscharfen Eingabeableitung aus. In diesem Fall verwende ich die Berechnung, die Alison Noble in ihrer Doktorarbeit beschrieben hat. Dissertation "Beschreibungen von Bildoberflächen". Der Shader, der dies erledigt, sieht folgendermaßen aus:
Führen Sie eine lokale Unterdrückung ohne Maximalwert durch, und wenden Sie einen Schwellenwert an, um die durchlaufenden Pixel hervorzuheben. Ich benutze den folgenden Fragment-Shader, um die acht Pixel in der Nachbarschaft eines zentralen Pixels abzutasten und festzustellen, ob es das Maximum in dieser Gruppierung ist oder nicht:
Bei diesem Vorgang wird aus Ihren Objekten eine Kornniveaukarte erstellt, die wie folgt aussieht:
Die folgenden Punkte werden als Ecken basierend auf der nicht maximalen Unterdrückung und Schwellenwertbildung identifiziert:
Wenn die richtigen Schwellenwerte für diesen Filter festgelegt sind, können alle 16 Ecken in diesem Bild identifiziert werden, obwohl die Ecken in der Regel um etwa ein Pixel innerhalb der tatsächlichen Kanten des Objekts platziert werden.
Auf einem iPhone 4 kann diese Eckenerkennung mit 20 FPS auf 640 x 480 Videoframes ausgeführt werden, die von der Kamera stammen, und ein iPhone 4S kann problemlos Videos dieser Größe mit mehr als 60 FPS verarbeiten. Dies sollte für eine Aufgabe wie diese viel schneller als die CPU-gebundene Verarbeitung sein, obwohl der Prozess des Zurücklesens der Punkte derzeit CPU-gebunden und etwas langsamer ist, als er sein sollte.
Wenn Sie dies in Aktion sehen möchten, können Sie den Code für mein Framework abrufen und das dazugehörige FilterShowcase-Beispiel ausführen. Das Harris-Eckenerkennungsbeispiel läuft dort mit Live-Video von der Gerätekamera, obwohl, wie ich bereits erwähnte, das Zurücklesen von Eckpunkten derzeit auf der CPU erfolgt, was dies wirklich verlangsamt. Auch dafür bin ich auf einen GPU-basierten Prozess umgestiegen.
quelle
"Robuste" Eckendetektoren wie Shi-Tomasi und Moravec sind notorisch langsam. Überprüfen Sie sie hier - http://en.wikipedia.org/wiki/Corner_detection FAST ist wahrscheinlich der einzige leichte Eckendetektor, der gut genug ist. Sie können FAST verbessern, indem Sie die Unterdrückung auf ein Minimum beschränken. Wählen Sie FAST-Ausgabe mit dem besten "Cornerness" -Wert. von FAST-5 bis FAST-12 und FAST_ER (letzteres ist wahrscheinlich zu umfangreich für Mobilgeräte) Eine andere Möglichkeit ist, FAST zu generieren - holen Sie sich den FAST-Code-Generator von der Autorenseite und trainieren Sie ihn auf der Menge der wahrscheinlichen Bilder. http://www.edwardrosten.com/work/fast.html
quelle
Nicht wirklich GPU-spezifisch, aber der SUSAN-Algorithmus von Steve Smith ist gut für die Eckenerkennung .
Der Algorithmus ist ziemlich einfach, wie der Quellcode in C zeigt.
quelle