Saltar al contenido principal

Teoría Adicional

Objetivos de Visión

Los diseñadores del juego FRC a menudo colocan "objetivos de visión" reflectantes en el campo en ubicaciones estratégicas. Estos objetivos de visión generalmente están hechos de cinta retrorreflectante. Los elementos de puntuación principales generalmente tienen objetivos de visión que se pueden usar para apuntar automáticamente. A continuación, puedes ver dos ejemplos de algunos de los objetivos de visión de los juegos FRC de 2016 y 2017.

Ejemplos de Objetivos de Visión

Estos objetivos de visión retrorreflectantes tienen una propiedad muy útil: cuando se les ilumina, reflejan la luz directamente hacia la fuente de luz. Es por eso que Limelight tiene LEDs verdes brillantes alrededor de su lente de cámara. Al configurar la exposición de la cámara muy baja mientras se emite una luz verde brillante hacia el objetivo, podemos obtener una imagen que es mayormente negra con un objetivo de visión verde brillante. Esto hace que la tarea de adquirir el objetivo sea relativamente fácil.

Aquí puedes ver un ejemplo de la imagen ideal. Observa cómo casi todos los detalles en la imagen han desaparecido debido a la configuración de baja exposición, pero la cinta retrorreflectante se destaca brillantemente.

Ejemplo de Objetivo de Visión 2


Umbralización

La umbralización es el siguiente componente crítico de la mayoría de los algoritmos de seguimiento de visión FRC. Consiste en tomar una imagen y descartar cualquier píxel que no esté en un rango de color específico. El resultado de la umbralización es generalmente una imagen unidimensional en la que un píxel está "encendido" o "apagado". La umbralización funciona muy bien en imágenes que se capturan utilizando la estrategia anterior (baja exposición, imagen muy oscura con un objetivo de visión brillantemente iluminado).

Limelight realiza la umbralización en el espacio de color HSV (Tono-Saturación-Valor). Puede que estés acostumbrado a pensar en colores en el espacio de color RGB (Rojo-Verde-Azul). HSV es solo otra forma de representar el color, similar a la forma en que las coordenadas cartesianas o polares pueden usarse para describir posiciones. La razón por la que usamos el espacio de color HSV es que el Tono se puede usar para seleccionar muy estrechamente el color verde que emiten los LEDs de Limelight.

Imagen HSV

Es crítico ajustar tus configuraciones de umbralización para eliminar tanto como puedas de la imagen. Obtendrás los mejores resultados si optimizas cada etapa de tu pipeline de visión antes de pasar a la siguiente etapa. La siguiente imagen muestra la diferencia entre una umbralización inadecuada y una adecuada:

Ejemplo de Umbralización

A veces, cosas como las luces del techo o las ventanas en una arena pueden ser difíciles de eliminar de la imagen usando la umbralización, lo que nos lleva a la siguiente etapa.


Filtrado de Contornos

Después de la umbralización, el pipeline de visión de Limelight genera un conjunto de contornos para la imagen. Un contorno es una curva que rodea un conjunto contiguo de píxeles. A veces, cosas como las luces del techo, los marcadores de la arena, las ventanas y otras cosas pueden pasar la etapa de umbralización. Aquí es donde el filtrado de contornos se vuelve útil. El objetivo es eliminar cualquier contorno que sabemos que no es el objetivo que nos interesa.

El primer y más fácil filtro de contorno es ignorar cualquier contorno que sea más pequeño de lo que nuestro objetivo de visión parece desde nuestra distancia de puntuación. Cualquier cosa más pequeña que ese tamaño es obviamente algo más lejano y debe ignorarse. Esto se llama filtrado de área.

Los objetivos de visión FRC a menudo tienen alguna propiedad geométrica que puede ser explotada para ayudarnos a filtrar contornos. Por ejemplo, si el objetivo de visión tiene una relación de aspecto ancha, podemos filtrar cualquier contorno que no sea ancho:

Objetivo

Sin embargo, ten en cuenta que tu cámara puede estar mirando el objetivo desde un ángulo extraño. Esto puede afectar drásticamente la relación de aspecto de su contorno. ¡Asegúrate de probar tus configuraciones desde una variedad de ángulos para asegurarte de que no filtres de manera demasiado agresiva y termines ignorando el objetivo de visión!

Objetivo

Este siguiente objetivo de imagen es muy interesante. Es uno de los objetivos de visión mejor diseñados en FRC (en nuestra opinión). Limelight calcula automáticamente un valor llamado plenitud de un contorno. La plenitud es la relación entre el área de píxeles del contorno y su área convexa. Esta forma particular tiene una plenitud muy baja y casi nunca se ven luces de techo, ventanas, etc. con una plenitud tan baja. Así que puedes filtrar muy eficazmente los contornos no deseados si tu objetivo de visión se parece a este.

Objetivo

Limelight tiene muchas opciones para filtrar contornos. Puedes usar estas opciones junto con lo que sabes sobre las propiedades geométricas del objetivo de visión particular que estás tratando de rastrear.

Actualmente, si múltiples contornos pasan a través de tus opciones de filtrado, se elige el contorno más grande. Además, el pipeline prefiere "bloquearse" en contornos usando histéresis. Esta es una característica que ayuda a prevenir el parpadeo entre objetivos similares.

De Píxeles a Ángulos

El resultado final del pipeline de visión es una ubicación de píxel del mejor contorno en la imagen. Para la mayoría de los juegos, podemos simplemente apuntar al centro del contorno. A veces también es útil apuntar al centro superior o algún otro punto, pero esencialmente tenemos una coordenada de píxel a la que queremos apuntar. Para calcular los ángulos a este objetivo, necesitamos usar un poco de trigonometría.

Primero asumimos que tenemos una cámara "pinhole" perfecta. En la práctica, esto puede estar lejos de la verdad, pero la cámara de Limelight está muy cerca. (Una lente de ojo de pez estaría lejos de este ideal como contraejemplo.)

La cámara Limelight tiene un campo de visión horizontal de 54 grados y un campo de visión vertical de 41 grados. Captura imágenes a una resolución de 320x240. Asumimos que el centro de la imagen es el eje óptico de la cámara (por lo que los ángulos x e y para esa ubicación son 0,0). Dados estos valores conocidos, podemos usar un poco de trigonometría para calcular los ángulos para cualquier píxel en la imagen.

El siguiente diagrama muestra un ejemplo de punto objetivo para el que queremos calcular los ángulos. Las coordenadas de píxeles comienzan en la esquina superior izquierda de la imagen y son positivas hacia la derecha y hacia abajo.

Píxeles a Ángulos

Nuestro primer paso será convertir de coordenadas de píxeles a coordenadas 2D normalizadas donde 0,0 es el centro de la imagen y 1.0:

(px, py) = coordenadas de píxeles, 0,0 está en la esquina superior izquierda, positivo hacia abajo y hacia la derecha

(nx, ny) = coordenadas de píxeles normalizadas, 0,0 está en el centro, positivo hacia la derecha y hacia arriba

nx = (1/160) * (px - 159.5)

ny = (1/120) * (119.5 - py)

A continuación, definimos un plano de visión imaginario y calculamos su tamaño. Para simplificar, podemos elegir colocar este plano a 1.0 unidad frente a la ubicación de la cámara. Aquí hay una vista mirando hacia abajo a la cámara. Nuestro objetivo es calcular el ancho y la altura del plano de visión, ya que esos valores se utilizarán para calcular los ángulos más adelante:

Píxeles a Ángulos Coordenadas Normalizadas

Dada una distancia de 1.0 unidad y un campo de visión horizontal y vertical conocido, podemos calcular el tamaño del rectángulo del plano de visión con las siguientes fórmulas:

vpw = 2.0*tan(horizontal_fov/2)

vph = 2.0*tan(vertical_fov/2)

Usando estos dos valores, ahora podemos convertir entre coordenadas de píxeles normalizadas y coordenadas del plano de visión usando una simple multiplicación.

x = vpw/2 * nx;

y = vph/2 * ny;

Recuerda que elegimos que nuestro plano de visión estuviera posicionado a una distancia de 1.0. Ahora tenemos todo lo que necesitamos para calcular los ángulos al punto objetivo.

Cálculo de Píxeles a Ángulos

tan(ax) = x / 1

tan(ay) = y / 1

ax = atan2(1, x)

ay = atan2(1, y)