Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Fortgeschrittene Kurven-Spurerkennung mit OpenCV

Hintergrund

Einführung

Fahrbahnmarkierungen sind das Rückgrat jedes autonomen Fahrsystems und leiten Fahrzeuge sicher durch den Verkehr. Aufbauend auf meinem früheren Gerade-Spur-Erkennungsprojekt habe ich eine robuste Kurven-Spurerkennungs-Pipeline entwickelt, die auch in komplexen Umgebungen wie Schatten, Verdeckungen und unebenen Straßenbelägen zuverlässig funktioniert.

Der vollständige Bildverarbeitungs-Workflow ist in Python mit OpenCV implementiert:

Beschränkungen des vorherigen Systems

Das frühere Modell war auf gerade Spuren beschränkt und hatte Probleme mit Kurven, Schatten und teilweisen Verdeckungen. Die neue Pipeline behebt diese Mängel durch kantengestütztes Filtern und einen dynamischen Sliding-Window-Ansatz.

Verzeichnungs-Korrektur

Kameraobjektive führen radiale Verzeichnung ein, die Messwerte verfälschen kann. Durch Kalibrierung der Kamera an einem bekannten Muster – typischerweise ein asymmetrisches Schachbrett – erzeugen wir ein Verzeichnungsmodell, das den gesamten Datensatz korrigiert.

Der Kalibrierungsprozess umfasst das Aufnehmen mehrerer Schachbrettbilder, Erkennen der Ecken mit cv2.findChessboardCorners() und Berechnen der Kameramatrix und Verzeichnungskoeffizienten mittels cv2.calibrateCamera(). Die korrigierten Bilder entstehen durch cv2.undistort().

Unten ein Seitenvergleich eines entzerrten Schachbrettbildes, der die subtile, aber kritische Verbesserung zeigt.

Hier der verwendete Kalibrierungscode:

def undistort_img():
    # Objektpunkte vorbereiten 0,0,0 … 8,5,0
    obj_pts = np.zeros((6*9,3), np.float32)
    obj_pts[:,:2] = np.mgrid[0:9, 0:6].T.reshape(-1,2)
    objpoints = []
    imgpoints = []
    images = glob.glob('camera_cal/*.jpg')
    for fname in images:
        img = cv2.imread(fname)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        ret, corners = cv2.findChessboardCorners(gray, (9,6), None)
        if ret:
            objpoints.append(obj_pts)
            imgpoints.append(corners)
    img_size = (img.shape[1], img.shape[0])
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size, None, None)
    dst = cv2.undistort(img, mtx, dist, None, mtx)
    dist_pickle = {'mtx': mtx, 'dist': dist}
    pickle.dump(dist_pickle, open('camera_cal/cal_pickle.p', 'wb'))
    return dst

def undistort(img, cal_dir='camera_cal/cal_pickle.p'):
    with open(cal_dir, 'rb') as f:
        file = pickle.load(f)
    mtx, dist = file['mtx'], file['dist']
    return cv2.undistort(img, mtx, dist, None, mtxx)

undistort_img()
img = cv2.imread('camera_cal/calibration1.jpg')
dst = undistort(img)

Die Funktionen sind auch im begleitenden Jupyter Notebook unter Code verfügbar.

Unten ein Beispiel für Verzeichnungskorrektur an einer Fahrszene. Auch wenn der visuelle Unterschied subtil ist, ist präzise Geometrie für nachgelagerte Verarbeitungsschritte kritisch.

Perspektiv-Transformation

Kurvige Spuren direkt im Kameraraum zu erkennen ist schwierig. Durch Transformation in eine Vogelperspektive können wir annehmen, dass die Spur in einer Ebene liegt und ein Polynom mit hoher Präzision anpassen.

Die Transformation erfolgt mit cv2.getPerspectiveTransform() und cv2.warpPerspective(). Quell- und Zielpunkte werden so gewählt, dass die Spurgergeometrie erhalten bleibt und die Sichtbarkeit maximiert wird.

def perspective_warp(img, dst_size=(1280,720), src=np.float32([(0.43,0.65),(0.58,0.65),(0.1,1),(1,1)]), dst=np.float32([(0,0),(1,0),(0,1),(1,1)])):
    img_size = np.float32([img.shape[1], img.shape[0]])
    src = src * img_size
    dst = dst * np.float32(dst_size)
    M = cv2.getPerspectiveTransform(src, dst)
    return cv2.warpPerspective(img, M, dst_size)

Sobel-Filterung

Reine Farbfilterung kann hellen Beton fälschlicherweise als Fahrbahnmarkierung klassifizieren. Stattdessen nutzen wir gradientenbasierte Kantenerkennung. Der Sobel-Operator berechnet horizontale Gradienten im HLS-Farbraum, hebt kontrastreiche Spurränder hervor und unterdrückt die Fahrbahnoberfläche.

Die resultierende Binärmaske ist robust gegen Beleuchtungsänderungen und dient als Eingabe für die Sliding-Window-Suche.

Histogramm-Peak-Erkennung

Vor Anwendung des Sliding Window identifizieren wir die ungefähren horizontalen Positionen der Fahrbahnlinien durch Berechnung eines Histogramms des Binärbildes entlang der X-Achse. Die höchsten Peaks auf jeder Seite entsprechen den Basis-Punkten der linken und rechten Spur.

Sliding Window Suche

Ausgehend von den Basispunkten sammelt der Sliding-Window-Algorithmus iterativ Pixel-Indizes, die zu jeder Spur gehören. Anschließend wird ein Polynom zweiten Grades an jede Spur angepasst, was präzise Krümmungsschätzung und Fahrzeugposition relativ zum Spurmittelpunkt ermöglicht.

Das finale Overlay zeigt den erkannten Spur-Bereich, Krümmung und Fahrzeugversatz in Echtzeit.

Weiterlesen: Curved Lane Detection

Herstellungsprozess

  1. 8051-basierter Ultraschall-Distanzsensor – Design, Schaltung und Anwendungen
  2. Intrusion Detection Systeme: Netzwerkschutz durch intelligente Alarme
  3. Omron E3AS-F Photoelektrische Sensoren erreichen 1,5 m Time-of-Flight-Detektion
  4. Hydra3D ToF Sensor liefert schnelle, akkurate 3D Detection für Industrial & Outdoor Applikationen
  5. AEye stellt Langstrecken-LiDAR vor: Erkennt Fahrzeuge bis 1.000 m für autonome Fahrzeuge
  6. Bewegungsmelder-Alarmsystem mit Java & Reactive Blocks – Auf Raspberry Pi deployen & SMS senden
  7. Farmaid: Autonomer Roboter für präzise Pflanzenkrankheitserkennung & Markierung
  8. Microsoft Kinect mit Raspberry Pi integrieren für Echtzeit-Menschenerkennung am Sonbi Roboter
  9. Einsatz von Mikroarray-Technologie zur Genexpressionsdetektion in der Klinischen Forschung
  10. Präzisions-CNC-Fräsen von Freiformflächen: Prozess, Werkzeuge & Tipps