Seguimiento
Seguir línea negra en escala de grises¶
# Ejemplo de seguimiento de línea negra en escala de grises
#
# Crear un robot de seguimiento de línea requiere mucho esfuerzo. Este script de ejemplo muestra
# cómo realizar la parte de visión artificial del robot de seguimiento de línea. Puedes utilizar
# el resultado de este script para controlar un robot de tracción diferencial y que siga una línea.
# Este script solo genera un único valor de giro que indica al robot que gire a la izquierda o a la
# derecha.
#
# Para que este script funcione correctamente, debes apuntar la cámara hacia una línea en un ángulo
# de aproximadamente 45 grados. Asegúrate de que solo la línea se encuentre dentro del campo de visión
# de la cámara.
import sensor, image, time, math
# Traza una línea negra
GRAYSCALE_THRESHOLD = [(0, 64)]
# Cada región de interés (ROI) es (x, y, w, h). El algoritmo de detección de líneas intentará
# encontrar el centro del bloque más grande en cada ROI. A continuación, se promediará la
# posición x de los centros con diferentes pesos, asignando el mayor peso a la ROI situada cerca
# de la parte inferior de la imagen y menos peso a la siguiente ROI, y así sucesivamente
ROIS = [ # [ROI, pesos]
(0, 100, 160, 20, 0.7), # Tendrás que ajustar los pesos de tu aplicación
(0, 50, 160, 20, 0.3), # en función de la configuración de tu robot
(0, 0, 160, 20, 0.1)
]
# Calcula el divisor de peso (lo calculamos para que no tengas que sumar los pesos hasta llegar a 1).
weight_sum = 0
for r in ROIS: weight_sum += r[4] # r[4] es el peso del ROI
# Configuración de la cámara...
sensor.reset() # Inicializa el sensor
sensor.set_pixformat(sensor.GRAYSCALE) # usa escala de grises
sensor.set_framesize(sensor.QQVGA) # usa QQVGA para mayor velocidad
sensor.skip_frames(time = 2000) # Hace que los nuevos ajustes surtan efecto
sensor.set_auto_gain(False) # Debe estar desactivado para el seguimiento del color
sensor.set_auto_whitebal(False) # Debe estar desactivado para el seguimiento del color
clock = time.clock() # Rastrea los FPS
while(True):
clock.tick() # Sigue los milisegundos transcurridos entre instantáneas (snapshots).
img = sensor.snapshot() # Toma una foto y devuelve la imagen
centroid_sum = 0
for r in ROIS:
blobs = img.find_blobs(GRAYSCALE_THRESHOLD, roi=r[0:4], merge=True)
if blobs:
# Encuentra la mancha con más píxeles
largest_blob = max(blobs, key=lambda b: b.pixels())
# Dibuja un rectángulo alrededor de la mancha
img.draw_rectangle(largest_blob.rect())
img.draw_cross(largest_blob.cx(),
largest_blob.cy())
centroid_sum += largest_blob.cx() * r[4]
center_pos = (centroid_sum / weight_sum) # Determinar el centro de la línea
# Convierte center_pos en un ángulo de desviación. Estamos utilizando una operación no lineal
# para que la respuesta sea más fuerte cuanto más nos alejemos de la línea. Las operaciones no
# lineales son útiles en la salida de algoritmos como este para provocar un "desencadenante"
# de respuesta.
deflection_angle = 0
# El 80 proviene de la mitad de la resolución X, el 60 proviene de la mitad de la resolución Y.
# La ecuación siguiente solo calcula el ángulo de un triángulo en el que el lado opuesto del
# triángulo es la desviación de la posición central con respecto al centro y el lado adyacente
# es la mitad de la resolución Y. Esto limita el ángulo resultante a entre -45 y 45 aproximadamente
# (no es exactamente -45 y 45).
deflection_angle = -math.atan((center_pos-80)/60)
# Convierte el ángulo en radianes a grados
deflection_angle = math.degrees(deflection_angle)
# Ahora tienes un ángulo que te indica cuánto girar el robot, el cual incorpora la parte de la
# línea más cercana al robot y las partes de la línea más alejadas del robot para obtener una
# mejor predicción.
print("Ángulo de giro: %f" % deflection_angle)
print(clock.fps())
Descargar el programa Seguir_linea_negra_escala_grises.py
Ecua¶
# Ejemplo de información del histograma de la imagen
#
# Este script calcula el histograma de la imagen y lo imprime.
import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE) # o RGB565.
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # Debe estar desactivado para el seguimiento del color
sensor.set_auto_whitebal(False) # Debe estar desactivado para el seguimiento del color
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
# Obtiene el histograma en escala de grises de la imagen en 8 intervalos.
# El valor predeterminado de los intervalos es 256 y puede estar entre 2 y 256.
print(img.get_histogram(bins=8))
print(clock.fps())
Descargar el programa info_histograma_imagen.py
Reconocimiento de combinaciones multicolores¶
# Reconocimiento de combinaciones multicolores
#
# Este ejemplo muestra el seguimiento de códigos multicolores utilizando el sensor IA
#
# Un código de color es una mancha compuesta por dos o más colores. El ejemplo siguiente solo
# rastreará objetos de color que contengan dos o más de los colores que se indican a continuación.
import sensor, image, time
# Umbrales de seguimiento del color (L mín., L máx., A mín., A máx., B mín., B máx.)
# Los siguientes umbrales realizan un seguimiento general de los elementos rojos/verdes.
# Es posible que desees ajustarlos...
thresholds = [(30, 100, 15, 127, 15, 127), # generic_red_thresholds -> el índice es 0, por lo que el código es == (1 << 0)
(30, 100, -64, -8, -32, 32), # generic_green_thresholds -> el índice es 1, por lo que el código es == (1 << 1)
(0, 15, 0, 40, -80, -20)] # generic_blue_thresholds -> el índice es 2, por lo que el código es == (1 << 2)
# Los códigos se combinan con la operación OR cuando 'merge=True' para 'find_blobs'
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # Debe estar desactivado para el seguimiento del color
sensor.set_auto_whitebal(False) # Debe estar desactivado para el seguimiento del color
clock = time.clock()
# Solo las manchas que tienen más píxeles que 'pixel_threshold' y más área que 'area_threshold'
# son devueltas por 'find_blobs'.
# Cambia 'pixels_threshold' y 'area_threshold' si cambias la resolución de la cámara.
# Se debe establecer 'merge=True' para fusionar las manchas de color superpuestas para los
# códigos de color.
while(True):
clock.tick()
img = sensor.snapshot()
for blob in img.find_blobs(thresholds, pixels_threshold=100, area_threshold=100, merge=True):
if blob.code() == 3: # r/g code
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
img.draw_string(blob.x() + 2, blob.y() + 2, "r/g")
if blob.code() == 5: # r/b code
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
img.draw_string(blob.x() + 2, blob.y() + 2, "r/b")
if blob.code() == 6: # g/b code
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
img.draw_string(blob.x() + 2, blob.y() + 2, "g/b")
if blob.code() == 7: # r/g/b code
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
img.draw_string(blob.x() + 2, blob.y() + 2, "r/g/b")
print(clock.fps())
Descargar el programa reconocimiento_multicolor.py
Reconocimiento de un solo color¶
# Reconocimiento de un solo color
#
# Este ejemplo muestra el seguimiento de códigos de un solo color el sensor IA
#
# Un código de color es una mancha compuesta por dos o más colores. El ejemplo siguiente solo
# rastreará objetos de color que contengan los dos colores siguientes.
import sensor, image, time, math
# Umbrales de seguimiento del color (L mín., L máx., A mín., A máx., B mín., B máx.)
# Los siguientes umbrales realizan un seguimiento general de los elementos rojos/verdes.
# Es posible que desees ajustarlos...
thresholds = [(30, 100, 15, 127, 15, 127), # generic_red_thresholds -> el índice es 0, por lo que el código es == (1 << 0)
(30, 100, -64, -8, -32, 32)] # generic_green_thresholds -> el índice es 1, por lo que el código es == (1 << 1)
# Los códigos se combinan con la operación OR cuando 'merge=True' para 'find_blobs'
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # Debe estar desactivado para el seguimiento del color
sensor.set_auto_whitebal(False) # Debe estar desactivado para el seguimiento del color
clock = time.clock()
# Solo las manchas que tienen más píxeles que 'pixel_threshold' y más área que 'area_threshold'
# son devueltas por 'find_blobs'.
# Cambia 'pixels_threshold' y 'area_threshold' si cambias la resolución de la cámara.
# Se debe establecer 'merge=True' para fusionar las manchas de color superpuestas para los
# códigos de color.
while(True):
clock.tick()
img = sensor.snapshot()
for blob in img.find_blobs(thresholds, pixels_threshold=100, area_threshold=100, merge=True):
if blob.code() == 3: # r/g codigo == (1 << 1) | (1 << 0)
# Estos valores dependen de que la mancha no sea circular; de lo contrario, serán inestables.
# if blob.elongation() > 0.5:
# img.draw_edges(blob.min_corners(), color=(255,0,0))
# img.draw_line(blob.major_axis_line(), color=(0,255,0))
# img.draw_line(blob.minor_axis_line(), color=(0,0,255))
# Estos valores son estables en todo momento
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
# Nota: la rotación del blob es única solo para 0-180.
img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)
print(clock.fps())