¿Es así cómo calcularía el FOV cuando tengo distorsión?
Siguiendo este recurso, creo que entiendo cómo funciona el modelo Plumb Bob para la distorsión.
Lo que no pude encontrar fue cómo aplicar esto al cálculo del campo de visión (FOV, por sus siglas en inglés). Para que te acostumbres a mi notación, sin distorsión es
def calculate_fov(
K: np.ndarray, resolution: Tuple[int, int]) -> Tuple[int, int]:
"""
Calcular FOV dado una matriz intrínseca y tamaño de imagen
Args:
K - matriz intrínseca de forma (3, 3)
resolution - (ancho, alto)
"""
fx = K[0, 0]
fy = K[1, 1]
return (2 * np.arctan(resolution[0] * 0.5 / fx), 2 * np.arctan(resolution[1] * 0.5 / fy))
Ahora, algunos cálculos rápidos me hacen pensar que puedo manejarlo obteniendo algún tipo de longitudes focales “modificadas” o “efectivas”.
Entonces, para “ajustar” fx
solo lo multiplicamos por el coeficiente de distorsión radial.
Entonces, mi función modificada es
def calculate_fov(
K: np.ndarray, resolution: Tuple[int, int], D: Optional[np.ndarray] = None) -> Tuple[int, int]:
"""
Calcular FOV dado una matriz intrínseca y tamaño de imagen
Args:
K - matriz intrínseca de forma (3, 3)
resolution - (ancho, alto)
D - Opcional (5,) con un modelo de distorsión
"""
fx = K[0, 0]
fy = K[1, 1]
# Ajustar fx y fy según la distorsión: http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/parameters.html
if D is not None:
rx = resolution[0] * 0.5 / fx
fx = fx * (1 + D[0] * rx**2 + D[1] * rx**4 + D[4] * rx**6)
ry = resolution[1] * 0.5 / fy
fy = fy * (1 + D[0] * ry**2 + D[1] * ry**4 + D[4] * ry**6)
return (2 * np.arctan(resolution[0] * 0.5 / fx), 2 * np.arctan(resolution[1] * 0.5 / fy))
En resumen, la idea es tomar el punto más ancho posible en mi imagen, calcular cuánto se movería ese punto debido a la distorsión, y luego usar eso en la trigonometría básica para FOV. Solo que no encuentro recursos que lo confirmen, y tengo algunas dudas sobre el orden de las operaciones/lógica. Además, no estoy seguro si fue justo de mi parte no tener en cuenta la distorsión tangencial.
davy.ai
Para aplicar el modelo de plomada para la distorsión hacia el cálculo del campo de visión (FOV), podemos modificar la función
calculate_fov
ajustando los valoresfx
yfy
basados en los coeficientes de distorsión. La idea es tomar el punto más amplio posible en la imagen, calcular cuánto se movería ese punto debido a la distorsión y luego usar eso en la trigonometría básica del FOV.La función modificada se ve así:
Esta función primero calcula el radio de distorsión máximo posible en la imagen (utilizando la fórmula para la diagonal de un rectángulo) y luego usa esto para ajustar
fx
yfy
basados en los coeficientes de distorsión. Finalmente, la función calcula el FOV utilizando las longitudes focales ajustadas.Vale la pena señalar que los coeficientes de distorsión tangencial no se utilizan en esta función. Para tenerlos en cuenta, tendríamos que modificar los cálculos de
rx
yry
en consecuencia. Sin embargo, la implementación actual aún debería proporcionar una estimación razonablemente precisa del FOV para una imagen con distorsión radial.