¿Cuáles son las principales referencias al modelo de cámara ojo de pez en OpenCV3.0.0dev?

Estoy luchando con el modelo de cámara Fish-Eye usado en OpenCV 3.0.0.dev . He leído la documentación en este enlace varias veces, especialmente la parte de “Descripción detallada” y las fórmulas que modelan la distorsión de ojo de pez. Por ahora tengo dos preocupaciones:

  1. Basándome en los modelos de proyección enumerados aquí y sus explicaciones conceptuales en ” Precisión del modelo de lente ojo de pez ” por Hughes, no puedo averiguar qué modelo de proyección se ha utilizado en la implementación de OpenCV.
  2. Dado que la descripción es tan concisa, necesito conocer los principales documentos de referencia utilizados por los desarrolladores de OpenCV para implementar el espacio de nombres de ojo de pez, de modo que pueda estar al tanto del tema y obtener más detalles. PD: comprobé la documentación de OpenCV 3.0.0-dev y no encontré nada útil.
    Gracias a todos por su ayuda,

Saludos cordiales,

Masih

Respuesta corta:

El modelo de cámara Fisheye de OpenCV 3.0.0 no usa el modelo Brown ni ninguno de los modelos a los que se refiere OP en Panotools, sino un modelo de cámara genérico de Juho Kannala y Sami S. Brandt.

Respuesta detallada:

Como señala Cfr en su respuesta, este comentario de Ilya Krylov (quien implementó el modelo de ojo de pez en OpenCV) dice que portaron la Caja de herramientas de calibración de la cámara para Matlab de Jean-Yves Bouguet:

Instantánea del comentario.

El sitio web de Jean-Yves Bouguet ( enlace ), a su vez, menciona el modelo del Modelo de cámara y método de calibración generics para lentes convencionales, gran angular y ojo de pez , y dice:

El modelo de ojo de pez “no documentado” contenido en la caja de herramientas de calibración sigue el modelo de proyección de equidistancia descrito por la ecuación (3) en este excelente artículo. El modelo de distorsión sigue la ecuación (6), con la excepción de que k1 = 1 (de lo contrario, no se puede distinguir de f).

Lo que en mi opinión es una statement engañosa o una idea errónea como la ecuación (3) y la ecuación (6) corresponden a diferentes modelos: la ecuación (6) es el modelo real introducido en este documento que los autores denominan Modelo de cámara genérico (de ahí que El nombre del papel). Para ser más precisos, la ecuación (6) estaba destinada a usarse como modelo de cámara y la ecuación (8) y (9) como la “distorsión” o desviación de este modelo.

Pero la odisea no ha terminado. La implementación de OpenCV (según su documentación ) primero calcula la proyección del orificio para encontrar el ángulo del campo (el ángulo entre el punto 3D, el centro de proyección y el eje óptico). Esto significa que no puede usar su modelo de ojo de pez para proyectar rayos a 90º (o dividiría entre 0) o cerca de 90º (los problemas de estabilidad numérica, como el desbordamiento pueden ocurrir si z es lo suficientemente pequeño). Además, no estoy seguro de si funcionará para rayos por más de 90º. Todo esto hace que me pregunte la “utilidad” de su modelo de cámara de ojo de pez para lentes de ojo de pez o de gran angular.

En caso de que sea escéptico, puede consultar el código fuente de OpenCV, concretamente en sources \ modules \ calib3d \ src \ fisheye.cpp (agregué algunos comentarios)

void cv::fisheye::projectPoints(InputArray objectPoints, OutputArray imagePoints, InputArray _rvec, InputArray _tvec, InputArray _K, InputArray _D, double alpha, OutputArray jacobian) { ... Rodrigues(om, R, dRdom); Affine3d aff(om, T); ... Vec3d Xi = objectPoints.depth() == CV_32F ? (Vec3d)Xf[i] : Xd[i]; Vec3d Y = aff*Xi; /* To transform to camera reference frame*/ Vec2d x(Y[0]/Y[2], Y[1]/Y[2]); /* <- The root of all evil (division by z) */ double r2 = x.dot(x); double r = std::sqrt(r2); // Angle of the incoming ray: double theta = atan(r); double theta2 = theta*theta, theta3 = theta2*theta, theta4 = theta2*theta2, theta5 = theta4*theta, theta6 = theta3*theta3, theta7 = theta6*theta, theta8 = theta4*theta4, theta9 = theta8*theta; double theta_d = theta + k[0]*theta3 + k[1]*theta5 + k[2]*theta7 + k[3]*theta9; double inv_r = r > 1e-8 ? 1.0/r : 1; double cdist = r > 1e-8 ? theta_d * inv_r : 1; Vec2d xd1 = x * cdist; Vec2d xd3(xd1[0] + alpha*xd1[1], xd1[1]); Vec2d final_point(xd3[0] * f[0] + c[0], xd3[1] * f[1] + c[1]); ... } 

Actualización : esta solicitud de extracción soluciona el problema de los rayos en angularjs ≥ 90º. A partir de abril de 2018, aún no se ha fusionado con el maestro, pero se está considerando para OpenCV 4.x Calibration Module .

Después de horas de lectura, descubrí que la fórmula θ = atan (r) en la documentación de ojo de pez de OpenCV, es la inversa normalizada de r = f * tanθ correspondiente a la proyección de orificios y, por lo tanto, ninguno de los modelos de proyección de ojo de pez mencionados en Los enlaces anteriores se utilizan en OpenCV.

Además, con respecto al modelo de distorsión, supongo que se usa el Modelo de división de Fitzgibbon en su artículo de 2001 “Estimación lineal simultánea de geometría de vista múltiple y distorsión de lente”. Según Hughes en su artículo de 2008 “Revisión de la compensación de distorsión geométrica en cámaras de ojo de pez”, entre otras alternativas están el “Modelo polinómico impar” y “Transformación de ojo de pez polinómica”. En su artículo, en la página 2, ha escrito:

(1) (que se refiere al Modelo Polinómico Odd ) y (3) (que se refiere al Modelo de División , que creo que es el que usa OpenCV) se puede usar para describir la distorsión en lentes estándar, que no son de ojo de pez. generalmente se considera que estos modelos polinomiales son insuficientes para describir el nivel de distorsión introducida por las lentes ojo de pez. Shah y Aggarwal han demostrado en [9] (Procedimiento de calibración de parámetros intrínsecos para una cámara de lente ojo de pez de alta distorsión con modelo de distorsión y Estimación de precisión) que incluso cuando se usa una versión de séptimo orden de (1) para modelar la distorsión radial de ojo de pez, permanece una distorsión considerable , en la medida en que tuvieron que usar un modelo con mayor grado de libertad. Por lo tanto, un polinomio que usa ambos Se pueden usar coeficientes pares e impares (en lugar de simplemente uno u otro) para modelar la distorsión radial introducida por una lente ojo de pez ”

Después de todo, llego a la conclusión de que el modelo de ojo de pez en OpenCV tiene una aplicabilidad muy limitada y podría ser mucho más sólido en términos de modelos de distorsión y modelos de proyección. Me gustaría volver a enfatizar que todavía necesito saber qué documentos utilizaron los desarrolladores de OpenCV para implementar el espacio de nombres de ojo de pez.

Apreciaría profundamente los comentarios de cualquiera sobre esto.

de acuerdo con el código de bouguet calib_tool “project_points_fisheye.m”

 %Definitions: %Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X) %The coordinate vector of P in the camera reference frame is: Xc = R*X + T %where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om); %call x, y and z the 3 coordinates of Xc: x = Xc(1); y = Xc(2); z = Xc(3); %The pinehole projection coordinates of P is [a;b] where a=x/z and b=y/z. %call r^2 = a^2 + b^2, %call theta = atan(r), %Fisheye distortion -> theta_d = theta * (1 + k(1)*theta^2 + k(2)*theta^4 + k(3)*theta^6 + k(4)*theta^8) % %The distorted point coordinates are: xd = [xx;yy] where: % %xx = (theta_d / r) * x %yy = (theta_d / r) * y % %Finally, convertion into pixel coordinates: The final pixel coordinates vector xp=[xxp;yyp] where: % %xxp = f(1)*(xx + alpha*yy) + c(1) %yyp = f(2)*yy + c(2) 

Es el modelo de Brown-Conrady , mencionado en la Caja de herramientas de calibración de la cámara para referencias de Matlab . Se analiza en este documento: DC Brown “Calibración de cámara de corto scope” .

También parece que el modelo actual de OpenCV ignora la distorsión tangencial ( P(r) ).

Ver este comentario .