2

Ich lese ein Bild und versuche Parallelogramm im Bild zu erkennen. Ich habe ein Array erstellt, das Kantenpunkte (lokale Peaks) unter Verwendung von Hough-Transformation (p = x cos (Theta) + y sin (Theta)) enthält. Ich habe ungefähr 2300 Kantenpunkte (X, Y) und ich bin mir nicht sicher, wie man daraus Parallelogramme bekommt/extrahiert. Von 2300 Kantenpunkten sind einige der Kantenpunkte kreisförmig, die Dreiecksform einschließlich Parallelogramm.So erkennen Sie Parallelogramme von den erkannten Kantenpunkten in Python

Wenn ich anfange, Randpunkte (X, Y) zu betrachten, wie es ist, dann wird es nicht funktionieren, da sie nicht nur Eckpunkte des Parallelogramms sind und Randpunkte in großer Anzahl sind (2300 Punkte).

[EDIT1]

Ich habe den Kantenpunkt in test_img gespeichert, und es enthält den Pixelwert. test_img [point.getX(), point.getY()] = 255

test_img.size = 2343

Nach Plotten über test_image "plt.imshow (test_img, cmap =" grau "):" Ich bin Bild unten erhalten

Jede Hilfe würde sehr geschätzt werden.

enter image description here

+0

Wir würden wirklich etwas Code und Format/Form Ihres Ein-/Ausgänge müssen auch darüber nachgedacht starten. Bitte lesen Sie [fragen] und [mcve] –

+0

Danke für Feedback und ich habe aktualisiert – Pradhuman

Antwort

0

UPDATE: Dieser Code wurde geschrieben, bevor OP kein Beispiel gab. Es sollte mit einer Punktwolke arbeiten. Es kann jedoch keine "Fast-Parallelogramme" finden.

Ein naive Ansatz wäre, für jedes Punktepaar (dx, dy) zu berechnen und sie in einem Diktat zu speichern. Die Werte des Diktats sind eine Liste von Punktepaaren. Wenn es mehr als ein Paar gibt, bildet jede Kombination von Paaren ein Parallelogramm.

Es ist nicht effizient (O(n**2)), aber immer noch mit 2300 Punkten machbar. Es ist auch viel effizienter als nur jedes 4-Punkte-Tupel zu testen.

Hier ist eine schnelle und schmutzige Umsetzung:

from random import randint, random 
from collections import defaultdict 
import matplotlib.pyplot as plt 
import matplotlib.patches as patches 

# N = 2300 
# width = 3000 
# height = 2000 
N = 180 
width = 3000 
height = 2000 
points = [(randint(0, width), randint(0, height)) for _ in range(N)] 
points = list(set(points)) # unique points 
n = len(points) 

plt.scatter(*zip(*points), linewidth=0.001) 

vectors = defaultdict(list) 

for i in range(n): 
    x1, y1 = points[i] 
    for j in range(i + 1, n): 
     x2, y2 = points[j] 
     vectors[(x2 - x1, y2 - y1)].append((i, j)) 

ax = plt.gca() 
for vector, pairs in vectors.items(): 
    if len(pairs) > 1: 
     # TODO: Consider every combination if len(pairs) > 2 
     a, b, c, d = points[pairs[0][0]], points[pairs[0][1]], points[pairs[1][1]], points[pairs[1][0]] 
     ax.add_patch(patches.Polygon(xy=[a, b, c, d], fill=False, color=[random(), random(), random()])) 

plt.show() 

Hier ist die Ausgabe mit 180 Punkten in einem 3000 * 2000 Raster:

enter image description here

Mit 2300 Punkten, können Sie eine Menge finden Parallelogramme.

+0

Vielen Dank für Ihre Antwort. Ich versuche, parallelogramm im obigen Bild zu erhalten/extrahieren. – Pradhuman

0

Da Sie bereits ordentlich Kanten haben, könnten Sie versuchen linear regression anwenden gerade Linie zu extrahieren Kanten:

  1. einen zufälligen Punkt Auswahl zu einem Rand gehören, plus seine N Nachbarn und legte ihn in eine Liste L. Passe das Verfahren zum Finden von Nachbarn an, um mit kleinen Lücken fertig zu werden.
  2. Berechnen Sie eine Zeile, die die Daten in L passt. Verfolgen Sie die Linienparameter (Winkel, Offset und MSE).
  3. Fügen Sie weiterhin Chargen von Nachbarn hinzu und berechnen Sie das lineare Modell neu, bis MSE anzusteigen beginnt.
  4. Sie haben wahrscheinlich ein Liniensegment gefunden!Hat es MSE nahe Null, ist es lang genug? Wenn ja, speichern Sie die geschätzten Parameter der Linie irgendwo.
  5. Pixel aus L aus dem Bild ausschließen.
  6. Gehen Sie zu # 1.

Nachdem Sie die Segmente gesammelt haben, sollte es ziemlich trivial sein, etwas zu finden, das Parallelogrammen ähnelt.

0

Sie haben Glück, ziemlich saubere und kontinuierliche Kanten zu bekommen.

Sie können sie in Liniensegmenten nach dem Douglas-Peucker-Verfahren mit einer geeigneten Geradheitstoleranz segmentieren. Behalte die Segmente, die lang genug sind *.

Sie können auch versuchen, die Lücke zwischen nahe und gut ausgerichteten Segmenten zu füllen, sowie die gebrochenen Ecken zu rekonstruieren (* dann filtern Sie die Länge erst nach der Rekonstruktion).

Wenn alles gut geht, sollten Sie in der Lage sein, eine Beschreibung wie unten zu erhalten, und daraus die Vierecke durch Analyse der Kanten-/Eckkurve ableiten. (Beachten Sie die parasitären Ecken an der Überlappung der Formen.)

enter image description here

+0

Vielen Dank für Ihre Antwort. Ich versuche, ein Parallelogramm wie dieses zu finden – Pradhuman

Verwandte Themen