2016-04-13 25 views
12

Ich muss Straße Spur von einem Video erkennen. Hier ist meine Art es zu tun.Python und OpenCV - Verbesserung meiner Spur Erkennung Algorithmus

  1. die Region of Interest Bestimmen (ROI) durch das Bild Slicing (Schwerpunkt des mittleren Teils)
  2. Graustufen des ROI
  3. Equalized die Graustufen ROI mit cv2.equalizeHist
  4. Nehmen Gaußsche Unschärfe (3)
  5. Threshold (4) durch cv2.adaptiveThreshold
  6. skeletonize (5) unter Verwendung von skimage.morphology.skeletonize Verwendung
  7. Nehmen, um die 012.on (6)

Für die cv2.HoughLines, habe ich, so dass:

  1. Wenn rho positiv ist (was bedeutet, dass die gerade Linie auf der rechten Seite (von unten nach oben) geneigt ist, wird es Zeichnen Sie nur die Linie, wenn es in bestimmten Winkeln ist (Ich habe den Bereich des Winkels eingestellt))
  2. Wenn rho negativ ist (gerade Linie ist nach links geneigt (von unten nach oben), wird es nur die Linie zeichnen, wenn es ist in bestimmten Winkeln)

Dies ist mein Code, um die Linien zu zeichnen:

lines = cv2.HoughLines(image_bin, 1, np.pi/180, 50) 
    try: 
     range = lines.shape[0] 
    except AttributeError: 
     range = 0 

    for i in xrange(range): 
     for rho, theta in lines[i]: 
      if rho > 0 and (np.pi*1/10 < theta < np.pi*4/10): 
       a = np.cos(theta) 
       b = np.sin(theta) 
       x0 = a * rho 
       y0 = b * rho 
       x1 = int(x0 + 1000 * (-b)) 
       y1 = int(y0 + 1000 * (a)) 
       x2 = int(x0 - 1000 * (-b)) 
       y2 = int(y0 - 1000 * (a)) 

       cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0)) 

      if rho < 0 and (np.pi*7/10 < theta < np.pi*9/10): 
       a = np.cos(theta) 
       b = np.sin(theta) 
       x0 = a * rho 
       y0 = b * rho 
       x1 = int(x0 + 1000 * (-b)) 
       y1 = int(y0 + 1000 * (a)) 
       x2 = int(x0 - 1000 * (-b)) 
       y2 = int(y0 - 1000 * (a)) 

       cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0)) 

Wenn ich es nicht tun, was ich für die cv2.HoughLines Funktion tat oben nur, ich glaube, es wird gezeichnet viele unnötige Linien sein.

Nach dem Einstellen der Parameter und so, habe ich ein ziemlich gutes Ergebnis, aber das ist nur für ein Bild. Ich denke nicht, dass es für ein Video, das sich ständig ändert, so gut ist. Was mich am meisten stört, ist mein Algorithmus zum Zeichnen der benötigten Linien (das ist die Fahrbahn). Gibt es einen besseren Weg? Zumindest besser als meiner.

Das ist mein Ergebnis:

Das Originalbild: The original image

Equalized Histogramm, Schwellwertbildung und skelettierten Bild des ROI: Equalized Histogram, thresholded, and skeletonized

Endergebnis: Final result

Antwort

6

Ich würde empfehlen, die probabilistische Hough Line Transformation für Ihre Anwendung zu verwenden auf. In OpenCVs Python-API ist es in der Funktion cv2.HoughLinesP implementiert. Dadurch erhalten Sie tatsächlich Liniensegmente, sodass Sie die Endpunkte nicht berechnen müssen. Es ist auch viel schneller als die Standard Hough Line Transformation.

Es gibt jedoch ein paar Kompromisse. Beispielsweise müssen Sie möglicherweise Logik zu Stichliniensegmenten zusammen hinzufügen. Auf der anderen Seite habe ich festgestellt, dass das nicht wirklich schlecht ist. Eines meiner Spielzeugprojekte (ein selbstfahrender Miniaturbus) nutzte diesen Ansatz, und separate Liniensegmente zum Zusammennähen erleichterten den Umgang mit Kurvenstraßen, bei denen die Standard-Hough-Linien-Transformation keine Linien mehr ergibt .

Hoffe, dass hilft.

EDIT: In Bezug auf die Details des Liniensegments „Stitching“, es hängt davon ab, was Sie suchen zu erreichen. Wenn Sie nur die Straße angezeigt werden soll, und Sie sind zufrieden mit es einige Lücken zwischen den Liniensegmenten zu sein, können Sie keine Nähte tun müssen - nur die Linie alle Segmente angezeigt werden soll. In meiner Anwendung, brauchte ich die Krümmung der Fahrspur zu bestimmen, so habe ich einige die Naht ein Modell jeder Fahrbahn aufzubauen, die die durchschnittliche Steigung der Spur umfassen würden - das als Eingabe für ein Modul einer verantwortlichen verwendete zur Steuerung Servo, um die Räder entsprechend zu bewegen.

Mit „Nähen“ meine ich nicht etwas besonders anspruchsvoll, aber ich bin von irgendwelchen besonderen OpenCV Funktionen nicht bewusst, dass es zu erreichen. Ich brauchte nur einen Weg der zugehörigen Liniensegmente, die Teil derselben Spur waren. So verarbeitet ich die Linie zurück Segmente aus HoughLinesP von der Oberseite des Bildes nach unten arbeiten, und verwendet, um jede Neigung des Liniensegments und y-Achsenabschnitt, um zu bestimmen, wo die Liniensegmente schneiden würden.

+0

Wie kann ich nähen "die Linien? Entschuldigung, immer noch ein Anfänger sowohl in der Programmierung als auch in der Bildverarbeitung. – Hilman

+0

Ich habe ein paar Notizen hinzugefügt. Entschuldigung, dass Sie keinen Code zur Verfügung gestellt haben. Es ist in C++ und die spezielle Implementierung unterscheidet sich sehr von Ihrer - im Grunde habe ich einfach nicht genug Zeit, um es für Ihre Anwendung anzupassen. – Aenimated1