Seguimiento de etiquetas AprilTag
Tutorial en video 11 - Seguimiento AprilTag: https://singtown.com/learn/49590/
Tutorial en video 21 - Un coche persiguiendo otros objetos: https://singtown.com/learn/50041/
Introducción a AprilTag
Recursos: https://april.eecs.umich.edu/software/apriltag.html
AprilTag es un sistema de referencia visual que se puede usar para una variedad de tareas, incluyendo AR, robótica y calibración de cámaras. Esta etiqueta se puede imprimir directamente con una impresora, y el programa de detección de AprilTag puede calcular la posición 3D precisa, la orientación y el id relativos a la cámara. ¡Esto es particularmente útil para OpenMV! Se ve así:

En pocas palabras, con solo colocar esta etiqueta en el objetivo, se puede identificar la posición 3D y el id de esta etiqueta en OpenMV.
Tipos de AprilTag
Los tipos de AprilTag se denominan familias, y existen los siguientes tipos:
TAG16H5 → 0 a 29\ TAG25H7 → 0 a 241\ TAG25H9 → 0 a 34\ TAG36H10 → 0 a 2319\ TAG36H11 → 0 a 586\ ARTOOLKIT → 0 a 511\ Es decir, hay 30 familias de TAG16H5, cada una con un id correspondiente, del 0 al 29.
Entonces, ¿cuáles son las diferencias entre las distintas familias?
Por ejemplo, el área efectiva de TAG16H5 es de 4 x 4 bloques, por lo que puede detectarse a mayor distancia que TAG36H11 (porque este tiene 6 x 6 bloques). Sin embargo, la tasa de error de TAG16H5 es mucho mayor que la de TAG36H11, porque TAG36H11 tiene más información de verificación, por lo que, si no hay otra razón, se recomienda usar TAG36H11.
Creación de AprilTag
Es muy sencillo. Puedes descargarlo de internet o generarlo directamente desde OpenMV IDE. Selecciona la familia en Herramientas - Visión artificial - Generar AprilTag. Se recomienda TAG36H11.

Luego, indica la cantidad que necesitas generar; por ejemplo, si necesitas 10, se generarán imágenes con los id del 0 al 9.

Luego selecciona la carpeta donde se guardará la imagen, y listo.

Luego, la imagen se generará en la carpeta.

Finalmente, imprime la imagen con una impresora (por supuesto, también puedes usar directamente la pantalla, pero puede reflejar luz).
Programa
# AprilTags Example
#
# This example shows the power of the OpenMV Cam to detect April Tags
# on the OpenMV Cam M7. The M4 versions cannot detect April Tags.
import csi, image, time, math
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QQVGA) # we run out of memory if the resolution is much bigger...
csi0.snapshot(frames=30)
csi0.auto_gain(False) # must turn this off to prevent image washout...
csi0.auto_whitebal(False) # must turn this off to prevent image washout...
clock = time.clock()
while(True):
clock.tick()
img = csi0.snapshot()
for tag in img.find_apriltags(): # defaults to TAG36H11 without "families".
img.draw_rectangle(tag.rect, color = (255, 0, 0))
img.draw_cross((tag.cx, tag.cy), color = (0, 255, 0))
degress = 180 * tag.rotation / math.pi
print(tag.id,degress)

Como puedes ver, puedes identificar el id 0, el ángulo de rotación y la posición\

Posicionamiento 3D
Lo más sorprendente de AprilTag es la función de posicionamiento 3D, que permite conocer la posición espacial de la etiqueta, con un total de 6 grados de libertad: tres posiciones y tres ángulos.
# AprilTags Example
#
# This example shows the power of the OpenMV Cam to detect April Tags
# on the OpenMV Cam M7. The M4 versions cannot detect April Tags.
import csi, image, time, math
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QQVGA) # we run out of memory if the resolution is much bigger...
csi0.snapshot(frames=30)
csi0.auto_gain(False) # must turn this off to prevent image washout...
csi0.auto_whitebal(False) # must turn this off to prevent image washout...
clock = time.clock()
# ¡Atención! A diferencia de find_qrcodes, find_apriltags no necesita corrección de distorsión por software para funcionar.
# Ten en cuenta que la unidad de la orientación de salida es radianes, que se puede convertir a grados, pero la unidad de la posición depende de tu escala y requiere una conversión proporcional
# f_x es la distancia focal en píxeles en el eje x. Para un OpenMV estándar, debería ser igual a 2.8/3.984*656; este valor es la distancia focal en milímetros dividida entre la longitud del sensor en la dirección x, multiplicada por los píxeles del sensor en la dirección x (OV7725)
# f_y es la distancia focal en píxeles en el eje y. Para un OpenMV estándar, debería ser igual a 2.8/2.952*488; este valor es la distancia focal en milímetros dividida entre la longitud del sensor en la dirección y, multiplicada por los píxeles del sensor en la dirección y (OV7725)
# c_x es la posición del centro de la imagen en x
# c_y es la posición del centro de la imagen en y
f_x = (2.8 / 3.984) * 160 # valor por defecto
f_y = (2.8 / 2.952) * 120 # valor por defecto
c_x = 160 * 0.5 # valor por defecto (image.w * 0.5)
c_y = 120 * 0.5 # valor por defecto (image.h * 0.5)
def degrees(radians):
return (180 * radians) / math.pi
while(True):
clock.tick()
img = csi0.snapshot()
for tag in img.find_apriltags(fx=f_x, fy=f_y, cx=c_x, cy=c_y): # por defecto es TAG36H11
img.draw_rectangle(tag.rect, color = (255, 0, 0))
img.draw_cross((tag.cx, tag.cy), color = (0, 255, 0))
print_args = (tag.x_translation, tag.y_translation, tag.z_translation, \
degrees(tag.x_rotation), degrees(tag.y_rotation), degrees(tag.z_rotation))
# La unidad de la posición es desconocida; la unidad de rotación es grados
print("Tx: %f, Ty %f, Tz %f, Rx %f, Ry %f, Rz %f" % print_args)
print(clock.fps())

El puerto serie muestra 6 variables: Tx, Ty, Tz son las 3 cantidades de posición en el espacio, y Rx, Ry, Rz son las tres cantidades de rotación.
Lecturas adicionales:
- De la app Singtown Lab: ¿Cómo localizar/medir la distancia en el reconocimiento de Apriltag? ¿Cuál es la unidad de salida de tx ty tz? ¿Cómo obtener la distancia real? https://forum.singtown.com/topic/52