2016-08-03 20 views
2

Ich habe zwei Bilder, das zweite ist das erste nach der Änderung. Ich finde Konturen von zwei Bildern und überprüfe dann, ob es dieselben Konturen gibt. Das Problem ist, dass trotz Konturen die gleichen Konturen (Zeichnung Konturen eines Bildes und eine andere gibt völlig gleiche Ergebnisse) nach der Überprüfung, dass es nie wahr, dass eine Kontur gleich einem anderen ist.Wie überprüft man, ob Konturen gleich sind?

Der Code: Finding die Konturen:

List<MatOfPoint> contours1 = new ArrayList<>(); 
List<MatOfPoint> contours2 = new ArrayList<>(); 
Imgproc.findContours(contours1mat, contours1, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); 
Imgproc.findContours(contours2mat, contours2, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); 

Überprüfung der Konturen (es macht nie Anpaßvariable true):

for(int i = 0; i < contours1.size(); i++) 
{ 
    boolean match = false; 

    for (int j = 0; j < contours2.size(); j++) 
    { 
     if (contours1.get(i) == contours2.get(j)) 
     { 
      //never hits that place, despite passing through all contours 
      match = true; 
      break; 
     } 
    } 

    if (!match) 
    { 
     contours1.remove(i); 
     i--; 
    } 
} 

Was mache ich falsch? Ist diese Art der Überprüfung der Ähnlichkeit der Konturen falsch? Wenn ja, wie kann ich prüfen, ob zwei Konturen gleich sind? Wie würden Sie die Konturenübereinstimmung überprüfen, wenn Sie dies tun müssten?

erstes Bild:

enter image description here

zweites Bild:

enter image description here

Die Logik hinter dem zweiten Bild ist, dass es das erste Bild ist, aber mit Lochungen in es. Ich überprüfe, ob diese Löcher die Seite der weißen Zone kreuzen, wenn nicht, sollte es zwei gleiche Konturen im ersten und zweiten Bild geben. Ich finde nur die äußeren Konturen, so dass die Konturgröße in beiden Bildern gleich ist.

...

UPDATE !!! Dieser Code gibt mir das gewünschte Ergebnis, aber das Problem ist, dass es wirklich zeitaufwendig ist, und offensichtlich gibt es einen großen Raum für die Verbesserung in der Algorithmus selbst (wahrscheinlich könnte eine gewisse Annäherung der Konturen vor der Überprüfung erfolgen) oder die Methode, die ich verwende. Ich hoffe wirklich, dass es ein leichtes, direktes Ergebnis gibt, um mein Problem zu lösen. Code:

for(int i = 0; i < contours1.size(); i++) 
{ 
    boolean match = true; 

    for (int j = 0; j < contours2.size(); j++) 
    { 
     if (contours1.get(i).toArray().length == contours2.get(j).toArray().length) 
     { 
      boolean match2 = true; 
      for (int k = 0; k < contours1.get(i).toArray().length; k++) 
      { 
       if ((contours1.get(i).toArray()[k].x != contours2.get(j).toArray()[k].x) || 
        (contours1.get(i).toArray()[k].y != contours2.get(j).toArray()[k].y)) 
       { 
        match2 = false; 
       } 
      } 
      if (match2) 
      { 
       match = true; 
       break; 
      } 
     } 
     else 
      match = false; 
    } 

    if (!match) 
    { 
     contours1.remove(i); 
     i--; 
    } 
} 

Antwort

2

Der Gleichheitsoperator == funktioniert nicht für Objekte, wie es für Primitive funktioniert.

Für int s, char s, boolean s usw. mit == Kontrollen zu vergleichen, wenn ihre Werte gleich sind. Bei Objekten prüft es, ob sich die beiden Variablen auf dasselbe Objekt beziehen, nicht wenn die Felder innerhalb der Objekte gleich sind. Um zu überprüfen, gleichwertige Objekte zu sein, gibt es die Methode .equals(), die wie folgt verwendet werden würde:

if (contours1.get(i).equals(contours2.get(i))) 

Dies ist jedoch auf das gleiche Verhalten wie == ausfällt, überprüft, ob die beiden Variablen auf die gleiche beziehen Objekt. In Ihrer Klasse MatOfPoint müssen Sie die Methode .equals() überschreiben, um festzulegen, wie zwei Objekte auf "gleich" überprüft werden sollen.

1

Vor langer Zeit hatte ich ein ähnliches Problem und ich habe diesen Algorithmus verwendet: Eine Multi-Scale-Kurvenglättung für die generalisierte Mustererkennung (MSGPR). Siehe link1 und link2.

Dies funktioniert wirklich für enge Muster, aber in Ihrem Fall könnten Sie zuerst die Muster füllen und dann die Kontur extrahieren.

+0

Der Artikel, den Sie mir gaben, ist sehr interessant und nützlich, aber es ist für die Überprüfung zwischen zwei ähnlichen, nicht die gleichen Konturen. In meiner Situation habe ich völlig ähnliche Konturen zu finden. Trotzdem, nochmals vielen Dank für diesen Artikel, wirklich faszinierend. –

+0

Aus Erfahrung sind Konturen wegen der Diskretisierung nie exakt. Es wird also immer einige Pixel geben, die unterschiedlich sein können oder nicht genau die gleiche Reihenfolge haben. In diesem Fall macht dieses Papier Sinn. – FiReTiTi

+0

Ich verstehe Ihren Punkt, aber in meiner Situation sind sie völlig gleich, denn das zweite Bild ist nur das modifizierte erste, es hat Löcher in seinen weißen Zonen. Meine Aufgabe ist es zu finden, ob diese Löcher die Grenzen der weißen Zonen überschreiten und die äußeren Konturen ändern und ich löste dieses Problem (ich bearbeitete die Frage), aber meine Methode ist ziemlich zeitaufwendig (obwohl jede Fehlerfähigkeit beseitigt wird), also bin ich Denken Sie an eine direktere und schnellere Möglichkeit, diese Konturanpassung zu überprüfen, oder optimieren Sie nur den Code, den ich gegeben habe. Wenn meine Konturen nicht zu 100% gleich wären, wäre Ihr gegebener Artikel eine Antwort. –

Verwandte Themen