5.22. Corrección de lente y perspectiva¶
Dos clases de corrección geométrica deforman la imagen de maneras que un mapeo de rectángulo a rectángulo no puede lograr. La corrección de lente deshace la distorsión radial que introduce una lente angular real – el abombamiento de ojo de pez que curva las líneas rectas de la escena en curvas visibles cerca de las esquinas del fotograma. La corrección de perspectiva deshace el efecto trapezoidal que ocurre cuando la lente no apunta perpendicular a la escena – la deformación trapezoidal que convierte un rectángulo conocido del mundo en una mancha (blob) no rectangular en la imagen. Ambas correcciones deshacen, una vez completada la captura, efectos que son ópticos en su origen.
5.22.1. Distorsión radial de la lente¶
El material sobre efectos reales de la lente describe la distorsión de barril que introducen las lentes angulares económicas. Los píxeles cerca del centro del fotograma están aproximadamente donde predice el modelo de cámara estenopeica; los píxeles cerca de los bordes se curvan hacia afuera en una cantidad que crece con el cuadrado de la distancia radial al eje óptico. Una línea recta de la escena que pasa cerca del borde del fotograma se curva de forma visible en la imagen capturada, y cualquier algoritmo clásico de visión artificial que asuma que las líneas rectas permanecen rectas – detección de esquinas de AprilTag, seguimiento de bordes, navegación por seguimiento de líneas – obtiene la respuesta equivocada cerca de las esquinas.
lens_corr() deshace la distorsión. El método ejecuta el mapeo inverso: cada píxel de salida se muestrea desde la posición de la entrada desde la cual la lente lo habría curvado hacia afuera, y el resultado es una imagen geométricamente recta.
img.lens_corr(strength=1.8)
El parámetro strength es el núcleo de la corrección. Es un único número que describe con cuánta intensidad se abomba la lente; un valor cercano a 1.0 es una corrección suave para una lente moderadamente angular, y valores de hasta aproximadamente 2.0 son razonables para un ojo de pez pronunciado. El valor predeterminado de 1.8 es un buen punto de partida para las lentes de serie de la OpenMV Cam; el valor correcto para cualquier lente específica es cuestión de probar unos cuantos y observar la imagen.
Los dos parámetros secundarios suelen estar bien con sus valores predeterminados. zoom (predeterminado 1.0) escala la salida – un valor mayor que uno recorta hacia afuera para compensar la forma en que la corrección de lente empuja las esquinas más lejos; los valores más pequeños dejan más de la escena corregida visible a costa de incluir píxeles en blanco en los bordes de la imagen. x_corr e y_corr desplazan el centro de la corrección respecto al centro geométrico de la imagen, lo cual es útil cuando la lente no está ópticamente centrada sobre el sensor (un caso inusual pero que conviene conocer).
Una canalización típica: capturar, ejecutar lens_corr() una vez para enderezar la geometría, y luego ejecutar lo que la aplicación haga realmente con el resultado.
5.22.2. Corrección de rotación 3D¶
La otra clase de distorsión geométrica es la deformación de perspectiva que ocurre cuando el plano del sensor no es paralelo al plano de la escena. El caso clásico es una señal o una matrícula vista desde abajo: la parte superior de la señal está más lejos de la lente que la parte inferior, por lo que se proyecta más pequeña, y la imagen capturada muestra el rectángulo como un trapecio con el borde superior más corto que el inferior.
La solución consiste en aplicar una rotación 3D al fotograma capturado que reorienta virtualmente el plano del sensor para que quede paralelo al plano de la escena. La matemática es el mismo mapeo de perspectiva que utiliza la detección de AprilTag para recuperar la pose de una etiqueta a partir de sus cuatro esquinas, ejecutado a la inversa: dada una rotación, la operación asigna cada píxel de salida de vuelta a la posición de entrada de la que la rotación habría provenido.
rotation_corr() ejecuta esa corrección:
img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)
Los tres parámetros de rotación se expresan en grados y describen rotaciones alrededor de los ejes x, y y z de una cámara virtual centrada en la imagen. x_rotation inclina la cámara hacia arriba o hacia abajo (la corrección natural para una toma de una pared a nivel del suelo); y_rotation desplaza la cámara hacia la izquierda o la derecha; z_rotation gira la cámara alrededor de su eje óptico (la corrección natural para un montaje desnivelado).
x_translation e y_translation mueven la cámara virtual lateralmente sin rotarla. zoom (predeterminado 1.0) escala la salida. fov (predeterminado 60.0) describe el campo de visión vertical de la cámara, usado para calcular la proyección – el valor debe coincidir con la lente real para mantener la geometría consistente.
Para una combinación arbitraria de inclinación y desplazamiento, varias rotaciones distintas de cero se componen en una sola llamada. El orden de las operaciones es fijo dentro de la implementación; la aplicación solo proporciona los ángulos y el resultado se produce.
5.22.3. Rectificar un rectángulo conocido¶
La forma más útil de rotation_corr() es el argumento de palabra clave corners=, que toma una lista de cuatro tuplas (x, y) que describen las esquinas de un rectángulo conocido en la imagen de entrada. El método calcula la rotación 3D que habría mapeado un rectángulo verdadero a esos cuatro puntos concretos, aplica la inversa de esa rotación a toda la imagen, y devuelve un resultado en el que el rectángulo conocido vuelve a ser rectangular:
plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)
El uso clásico es exactamente lo que sugiere el nombre: una matrícula (o cualquier otra característica rectangular) fotografiada desde un ángulo oblicuo. Una etapa previa detecta la matrícula y reporta las posiciones de sus cuatro esquinas en la imagen capturada; pasar esas esquinas a rotation_corr() produce una imagen en la que la matrícula aparece como un rectángulo verdadero, lista para la etapa de reconocimiento de caracteres o de coincidencia de plantillas que venga a continuación.
Cuando la forma de cuatro esquinas resuelve el problema que una aplicación intenta resolver, es muchísimo más útil que la forma de seis parámetros. La aplicación no tiene que estimar ningún ángulo de rotación; simplemente le entrega al método cuatro puntos y deja que el método deduzca el resto. La forma de seis parámetros es útil cuando no hay ningún rectángulo identificable visible en la escena y la rotación debe ajustarse a mano a partir de conocimiento externo (un ángulo de montaje calibrado, por ejemplo).