black_grayscale_line_following.py

# Questo lavoro è concesso in licenza MIT.
# Copyright (c) 2013-2023 OpenMV LLC. Tutti i diritti riservati.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Esempio di inseguimento di linea nera in scala di grigi
#
# Realizzare un robot che segue linee richiede molto impegno. Questo script di esempio
# mostra come realizzare la parte di visione artificiale del robot che segue linee. È
# possibile usare l'output di questo script per guidare un robot a trazione differenziale a
# seguire una linea. Questo script genera semplicemente un singolo valore di svolta che indica
# al robot di andare a sinistra o a destra.
#
# Perché questo script funzioni correttamente, la fotocamera dovrebbe essere puntata su una linea con
# un'angolazione di circa 45 gradi. Assicurarsi che solo la linea sia all'interno del
# campo visivo della fotocamera.

import csi
import time
import math

# Traccia una linea nera. Usare [(128, 255)] per tracciare una linea bianca.
GRAYSCALE_THRESHOLD = [(0, 64)]

# Ogni roi è (x, y, w, h). L'algoritmo di rilevamento delle linee cercherà di trovare
# il centroide del blob più grande in ciascuna roi. La posizione x dei centroidi
# verrà quindi mediata con pesi diversi, dove il peso maggiore viene assegnato
# alla roi vicino alla parte inferiore dell'immagine e un peso minore alla roi successiva, e così via.
ROIS = [  # [ROI, weight]
    (0, 100, 160, 20, 0.7),  # Sarà necessario regolare i pesi per la propria applicazione
    (0, 50, 160, 20, 0.3),  # a seconda di come è configurato il robot.
    (0, 0, 160, 20, 0.1),
]

# Calcolare il divisore del peso (lo calcoliamo così non è necessario che i pesi sommino a 1).
weight_sum = 0
for r in ROIS:
    weight_sum += r[4]  # r[4] è il peso della roi.

# Configurazione della fotocamera...
csi0 = csi.CSI()
csi0.reset()  # Inizializza il sensore della fotocamera.
csi0.pixformat(csi.GRAYSCALE)  # usare la scala di grigi.
csi0.framesize(csi.QQVGA)  # usare QQVGA per la velocità.
csi0.snapshot(time=2000)  # Lasciare che le nuove impostazioni abbiano effetto.
csi0.auto_gain(False)  # deve essere disattivato per il tracciamento del colore
csi0.auto_whitebal(False)  # deve essere disattivato per il tracciamento del colore
clock = time.clock()  # Traccia gli FPS.

while True:
    clock.tick()  # Traccia i millisecondi trascorsi tra le chiamate a snapshot().
    img = csi0.snapshot()  # Scatta una foto e restituisce l'immagine.

    centroid_sum = 0

    for r in ROIS:
        blobs = img.find_blobs(
            GRAYSCALE_THRESHOLD, roi=r[0:4], merge=True
        )  # r[0:4] è la tupla della roi.

        if blobs:
            # Trovare il blob con il maggior numero di pixel.
            largest_blob = max(blobs, key=lambda b: b.pixels)

            # Disegnare un rettangolo intorno al blob.
            img.draw_detection(largest_blob)

            centroid_sum += largest_blob.cx * r[4]  # r[4] è il peso della roi.

    center_pos = centroid_sum / weight_sum  # Determinare il centro della linea.

    # Convertire center_pos in un angolo di deflessione. Stiamo usando un'operazione
    # non lineare in modo che la risposta diventi più forte quanto più ci si allontana dalla linea
    # in cui ci si trova. Le operazioni non lineari sono utili da applicare all'output di algoritmi
    # come questo per generare una risposta di "attivazione".
    deflection_angle = 0

    # L'80 deriva dalla metà della risoluzione X, il 60 dalla metà della risoluzione Y. Il
    # calcolo seguente non fa altro che determinare l'angolo di un triangolo in cui
    # il lato opposto del triangolo è la deviazione della posizione centrale
    # dal centro e il lato adiacente è metà della risoluzione Y. Questo limita
    # l'angolo di uscita a circa -45/45. (Non è esattamente -45 e 45).
    deflection_angle = -math.atan((center_pos - 80) / 60)

    # Convertire l'angolo da radianti a gradi.
    deflection_angle = math.degrees(deflection_angle)

    # Ora si ha un angolo che indica di quanto girare il robot, che
    # incorpora la parte della linea più vicina al robot e parti
    # della linea più lontane dal robot, per una previsione migliore.
    print("Turn Angle: %f" % deflection_angle)

    print(clock.fps())  # Nota: la tua OpenMV Cam funziona a circa metà velocità quando
    # è collegata al computer. Il framerate dovrebbe aumentare una volta scollegata.

results matching ""

    No results matching ""