Wie können Konvexitätsdefekte entfernt werden?

8

Ich versuche einige Objekte in Bildern aus Konturen zu finden und zu lokalisieren. Die Konturen, die ich bekomme, enthalten oft etwas Rauschen (vielleicht bilden sie den Hintergrund, ich weiß es nicht). Die Objekte sollten ähnlich wie Rechtecke oder Quadrate aussehen:

Ich bekomme sehr gute Ergebnisse mit der Formanpassung ( cv::matchShapes ), um Konturen mit diesen Objekten in ihnen zu erkennen, mit und ohne Rauschen, aber ich habe Probleme mit der Feinpositionierung im Falle von Rauschen.

Rauschen sieht folgendermaßen aus:

oder zum Beispiel.

Meine Idee war, Konvexitätsdefekte zu finden, und wenn sie zu stark werden, sollte man den Teil, der zur Konkavität führt, irgendwie wegschneiden. Das Erkennen der Defekte ist in Ordnung, normalerweise bekomme ich zwei Defekte pro "unerwünschter Struktur", aber ich bleibe bei der Entscheidung, was und wo ich Punkte aus den Konturen entfernen soll.

Hier sind einige Konturen, ihre Masken (damit Sie die Konturen leicht extrahieren können) und die konvexe Hülle einschließlich der Schwellwertfehler in der Schwellwertform:

< a href="https://i.stack.imgur.com/ErwpG.png">

< a href="https://i.stack.imgur.com/3Mx6w.png">

< a href="https://i.stack.imgur.com/58FoY.png">

< a href="https://i.stack.imgur.com/lFoa7.png">

< a href="https://i.stack.imgur.com/V6QHn.png">

< a href="https://i.stack.imgur.com/N6bpe.png">

>

< a href="https://i.stack.imgur.com/mIztA.png">

>

< a href="https://i.stack.imgur.com/Ic8z1.png">

< a href="https://i.stack.imgur.com/jbWSS.png">

>

Könnte ich einfach durch die Kontur gehen und lokal entscheiden, ob eine "Linkskurve" von der Kontur ausgeführt wird (wenn im Uhrzeigersinn gehend) und wenn ja, entferne Konturpunkte, bis die nächste Linkskurve gemacht wird? Vielleicht ausgehend von einem Konvexitätsdefekt?

Ich suche nach Algorithmen oder Code, Programmiersprache sollte nicht wichtig sein, Algorithmus ist wichtiger.

    
Micka 05.02.2016, 14:51
quelle

3 Antworten

9

Dieser Ansatz funktioniert nur punktuell. Sie müssen dafür keine Masken erstellen.

Die Hauptidee ist:

  1. Fehler in der Kontur finden
  2. Wenn ich mindestens zwei Defekte finde, finde die zwei nächsten Defekte
  3. Entfernen Sie die Punkte zwischen den beiden nächstgelegenen Defekten aus der Kontur
  4. Neustart von 1 auf der neuen Kontur

Ich bekomme folgende Ergebnisse. Wie Sie sehen können, hat es einige Nachteile für glatte Defekte (z. B. das siebte Bild), funktioniert aber ziemlich gut für deutlich sichtbare Defekte. Ich weiß nicht, ob das dein Problem lösen wird, aber kann ein Ausgangspunkt sein. In der Praxis sollte ziemlich schnell sein (Sie können sicherlich den untenstehenden Code optimieren, insbesondere die Funktion removeFromContour ). Außerdem ist der einzige Parameter dieses Ansatzes die Größe des Konvexitätsdefekts, so dass er sowohl mit kleinen als auch mit großen defekten Blobs gut funktioniert.

%Vor%

AKTUALISIEREN

Das Arbeiten mit einer angenäherten Kontur (z. B. mit CHAIN_APPROX_SIMPLE in findContours ) ist möglicherweise schneller, aber die Länge von Konturen muss mit arcLength() berechnet werden.

Dies ist das zu ersetzende Snippet im swapping Teil von removeFromContour :

%Vor%     
Miki 07.02.2016, 09:59
quelle
2

Ich habe die folgende Methode entwickelt, um die Grenzen des Rechtecks ​​/ Quadrats zu erkennen. Es basiert auf wenigen Annahmen: Form ist rechteckig oder quadratisch, es ist im Bild zentriert, es ist nicht geneigt.

  • Teilen Sie das maskierte (gefüllte) Bild entlang der X-Achse in zwei Hälften, so dass Sie zwei Regionen (eine obere Hälfte und eine untere Hälfte) erhalten
  • nimm die Projektion jeder Region auf die x-Achse
  • Nehme alle Nicht-Null-Einträge dieser Projektionen und nimm ihre Mediane. Diese Mediane geben Ihnen die y-Grenzen
  • Teilen Sie das Bild in ähnlicher Weise auf der y-Achse in der Mitte, nehmen Sie die Projektionen auf die y-Achse und berechnen Sie dann die Mittelwerte, um die x-Grenzen zu erhalten
  • Verwenden Sie die Grenzen, um die Region zu beschneiden

Mittlere Linie und die Projektion für eine obere Hälfte eines Beispielbildes wird unten gezeigt.

Resultierende Grenzen und zugeschnittene Regionen für zwei Samples:

Der Code ist in Octave / Matlab, und ich habe dies auf Octave getestet (Sie benötigen das Bildpaket, um das auszuführen).

%Vor%     
dhanushka 06.02.2016 07:26
quelle
1

Als Ausgangspunkt und unter der Annahme, dass die Defekte nie zu groß im Verhältnis zu dem Objekt sind, das Sie zu erkennen versuchen, können Sie eine einfache erode + dilate Strategie ausprobieren, bevor Sie cv::matchShapes verwenden, wie unten gezeigt.

%Vor%

    
zeFrenchy 05.02.2016 15:43
quelle