black_grayscale_line_following.py

# Dieses Werk ist unter der MIT-Lizenz lizenziert.
# Copyright (c) 2013-2023 OpenMV LLC. Alle Rechte vorbehalten.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Beispiel für Linienverfolgung mit schwarzer Graustufenlinie
#
# Der Bau eines linienfolgenden Roboters erfordert erheblichen Aufwand. Dieses Beispielskript
# zeigt, wie der Bildverarbeitungsteil des linienfolgenden Roboters umgesetzt wird. Sie
# können die Ausgabe dieses Skripts verwenden, um einen Roboter mit Differentialantrieb dazu zu bringen,
# einer Linie zu folgen. Dieses Skript erzeugt lediglich einen einzelnen Lenkwert, der
# Ihrem Roboter mitteilt, nach links oder rechts zu fahren.
#
# Damit dieses Skript ordnungsgemäß funktioniert, sollten Sie die Kamera in einem
# Winkel von etwa 45 Grad auf eine Linie richten. Bitte stellen Sie sicher, dass sich nur die Linie im
# Sichtfeld der Kamera befindet.

import csi
import time
import math

# Verfolgt eine schwarze Linie. Verwenden Sie [(128, 255)] zum Verfolgen einer weißen Linie.
GRAYSCALE_THRESHOLD = [(0, 64)]

# Jede ROI ist (x, y, w, h). Der Linienerkennungsalgorithmus versucht, den
# Schwerpunkt des größten Blobs in jeder ROI zu finden. Die x-Position der Schwerpunkte
# wird dann mit unterschiedlichen Gewichtungen gemittelt, wobei der größte Gewichtungswert
# der ROI nahe dem unteren Bildrand zugewiesen wird und ein geringerer der nächsten ROI usw.
ROIS = [  # [ROI, Gewichtung]
    (0, 100, 160, 20, 0.7),  # Sie müssen die Gewichtungen für Ihre Anwendung anpassen
    (0, 50, 160, 20, 0.3),  # je nachdem, wie Ihr Roboter aufgebaut ist.
    (0, 0, 160, 20, 0.1),
]

# Den Gewichtungsdivisor berechnen (damit die Gewichtungen nicht manuell zu 1 addiert werden müssen).
weight_sum = 0
for r in ROIS:
    weight_sum += r[4]  # r[4] ist die ROI-Gewichtung.

# Kamera-Einrichtung...
csi0 = csi.CSI()
csi0.reset()  # Kamerasensor initialisieren.
csi0.pixformat(csi.GRAYSCALE)  # Graustufen verwenden.
csi0.framesize(csi.QQVGA)  # QQVGA für Geschwindigkeit verwenden.
csi0.snapshot(time=2000)  # Neue Einstellungen wirksam werden lassen.
csi0.auto_gain(False)  # muss für das Farb-Tracking deaktiviert werden
csi0.auto_whitebal(False)  # muss für das Farb-Tracking deaktiviert werden
clock = time.clock()  # Verfolgt die FPS.

while True:
    clock.tick()  # Erfasst die vergangenen Millisekunden zwischen den Aufrufen von snapshots().
    img = csi0.snapshot()  # Nimmt ein Bild auf und gibt es zurück.

    centroid_sum = 0

    for r in ROIS:
        blobs = img.find_blobs(
            GRAYSCALE_THRESHOLD, roi=r[0:4], merge=True
        )  # r[0:4] ist das ROI-Tupel.

        if blobs:
            # Den Blob mit den meisten Pixeln finden.
            largest_blob = max(blobs, key=lambda b: b.pixels)

            # Ein Rechteck um den Blob zeichnen.
            img.draw_detection(largest_blob)

            centroid_sum += largest_blob.cx * r[4]  # r[4] ist die ROI-Gewichtung.

    center_pos = centroid_sum / weight_sum  # Den Mittelpunkt der Linie bestimmen.

    # Die center_pos in einen Ablenkwinkel umwandeln. Wir verwenden eine nichtlineare
    # Operation, damit die Reaktion umso stärker wird, je weiter wir von der Linie
    # entfernt sind. Nichtlineare Operationen eignen sich gut, um bei der Ausgabe solcher Algorithmen
    # einen „Trigger“-artigen Reaktionseffekt zu erzeugen.
    deflection_angle = 0

    # Die 80 stammt von der halben X-Auflösung, die 60 von der halben Y-Auflösung. Die
    # folgende Gleichung berechnet lediglich den Winkel eines Dreiecks, bei dem
    # die Gegenkathete des Dreiecks die Abweichung der Mittelposition
    # von der Mitte ist und die Ankathete der halben Y-Auflösung entspricht. Dies begrenzt
    # die Winkelausgabe auf etwa -45 bis 45. (Es ist nicht ganz -45 und 45).
    deflection_angle = -math.atan((center_pos - 80) / 60)

    # Winkel von Radiant in Grad umrechnen.
    deflection_angle = math.degrees(deflection_angle)

    # Jetzt haben Sie einen Winkel, der angibt, wie stark der Roboter gelenkt werden soll, der
    # den Teil der Linie in Roboternähe sowie Teile
    # der weiter entfernten Linie für eine bessere Vorhersage einbezieht.
    print("Turn Angle: %f" % deflection_angle)

    print(clock.fps())  # Hinweis: Ihre OpenMV Cam läuft etwa halb so schnell, während
    # sie mit Ihrem Computer verbunden ist. Die FPS sollten sich erhöhen, sobald die Verbindung getrennt wird.

results matching ""

    No results matching ""