Me enfrenté con el mismo problema que usted, en OpenCV. Tenía un par de imágenes estéreo y quería calcular los parámetros externos de las cámaras y las coordenadas mundiales de todos los puntos observados. Este problema se ha tratado aquí:
Berthold K. P. Horn. Orientación relativa revisitada. Berthold K. P. Horn. Laboratorio de Inteligencia Artificial del Instituto de Tecnología de Massachusetts, 545 Tecnología ...
http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.64.4700
Sin embargo, no fue capaz de encontrar una aplicación adecuada de este problema (tal vez se encuentra uno). Debido a limitaciones de tiempo, no tuve tiempo para entender todas las matemáticas en este documento y aplicarlo yo mismo, así que se me ocurrió una solución rápida y sucia que me funciona. Explicaré lo que hice para resolverlo:
Suponiendo que tenemos dos cámaras, donde la primera cámara tiene parámetros externos RT = Matx :: eye(). Ahora adivine sobre la rotación R de la segunda cámara. Para cada par de puntos de imagen observados en ambas imágenes, calculamos las direcciones de sus rayos correspondientes en coordenadas mundiales y los almacenamos en una matriz 2d dirs (EDITAR: Se supone que se conocen los parámetros internos de la cámara). Podemos hacer esto ya que suponemos que sabemos la orientación de cada cámara. Ahora construimos un sistema lineal sobredeterminado AC = 0 donde C es el centro de la segunda cámara. Yo le proporcionará la función para calcular R:
Mat buildA(Matx<double, 3, 3> &R, Array<Vec3d, 2> dirs)
{
CV_Assert(dirs.size(0) == 2);
int pointCount = dirs.size(1);
Mat A(pointCount, 3, DataType<double>::type);
Vec3d *a = (Vec3d *)A.data;
for (int i = 0; i < pointCount; i++)
{
a[i] = dirs(0, i).cross(toVec(R*dirs(1, i)));
double length = norm(a[i]);
if (length == 0.0)
{
CV_Assert(false);
}
else
{
a[i] *= (1.0/length);
}
}
return A;
}
Entonces llamando cv :: :: SVD solveZ (A) le dará la solución de mínimos cuadrados de la norma 1 de este sistema. De esta forma, obtienes la rotación y la traducción de la segunda cámara. Sin embargo, como acabo de adivinar la rotación de la segunda cámara, hago varias conjeturas sobre su rotación (parametrizada usando un vector 3x1 omega a partir del cual calculo la matriz de rotación usando cv :: Rodrigues) y luego refino esta suposición resolviendo el sistema AC = 0 repetidamente en un optimizador Levenberg-Marquardt con jacobian numérico. Funciona para mí, pero está un poco sucio, así que si tienes tiempo, te animo a implementar lo que se explica en el documento.
EDIT:
Aquí está la rutina en el optimizador de Levenberg-Marquardt para evaluar el vector de residuos:
void Stereo::eval(Mat &X, Mat &residues, Mat &weights)
{
Matx<double, 3, 3> R2Ref = getRot(X); // Map the 3x1 euler angle to a rotation matrix
Mat A = buildA(R2Ref, _dirs); // Compute the A matrix that measures the distance between ray pairs
Vec3d c;
Mat cMat(c, false);
SVD::solveZ(A, cMat); // Find the optimum camera centre of the second camera at distance 1 from the first camera
residues = A*cMat; // Compute the output vector whose length we are minimizing
weights.setTo(1.0);
}
Por cierto, he buscado un poco más en el Internet y encontrar algún otro código que podría ser útil para calcular la orientación relativa entre cámaras. No he probado todavía ningún código, pero parece útil:
http://www9.in.tum.de/praktika/ppbv.WS02/doc/html/reference/cpp/toc_tools_stereo.html
http://lear.inrialpes.fr/people/triggs/src/
http://www.maths.lth.se/vision/downloads/
No está claro por encima de si se conoce el mundo 3d coordenadas de los puntos que usted observe en las diferentes imágenes. Si este es el caso, este es un problema Perspective-n-point y puede calibrar los parámetros de cada cámara utilizando el algoritmo EPnP disponible aquí: http://cvlab.epfl.ch/software/EPnP/index.php. De lo contrario, vea mi respuesta a continuación. – Rulle
Las coordenadas 3d del objeto fotografiado son desconocidas. –
Si las coordenadas mundiales tridimensionales de los puntos del objeto son 'desconocidas_, no creo que cv :: calibrateCamera funcione, porque parece suponer que los puntos del objeto son _known_. – Rulle