听说可以使用
cv::calibrateCamera(...)
来实现,但我无法完全理解。有没有人遇到过这种问题?
cv::calibrateCamera(...)
来实现,但我无法完全理解。我遇到了和你同样的问题,使用OpenCV处理立体图像对,想要计算摄像机的外部参数和所有观察点的世界坐标。这个问题在这里得到了解决:
Berthold K. P. Horn. Relative orientation revisited. Berthold K. P. Horn. Massachusetts Institute of Technology人工智能实验室,545 Technology...
http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.64.4700
然而,我没有找到一个合适的实现方法(也许你能找到一个)。由于时间限制,我没有时间理解论文中的所有数学知识并自己实现它,所以我想出了一个快速且简单的解决方案,并且对我有用。我将解释我是如何解决这个问题的:
假设我们有两台相机,第一台相机的外部参数为RT = Matx::eye()。现在猜测第二台相机的旋转R。对于两幅图像中都被观察到的每一对图像点,我们计算它们在世界坐标系中对应射线的方向,并将其存储在二维数组dirs中(编辑:假设已知内部相机参数)。我们可以这样做是因为我们假设已经知道每个相机的方向。现在,我们建立一个超定线性系统AC = 0,其中C是第二台相机的中心。我提供了计算A的函数:
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;
}
调用cv::SVD::solveZ(A)将为您提供该系统1范数的最小二乘解。这样,您就可以获得第二个相机的旋转和平移。然而,由于我只是猜测第二个相机的旋转,所以我对其旋转进行了多次猜测(使用3x1向量ω进行参数化,从中计算旋转矩阵使用cv :: Rodrigues)。然后,我通过在Levenberg-Marquardt优化器中重复求解系统AC = 0来改进此猜测,并使用数值雅可比矩阵。它对我很有用,但有点不干净,因此如果您有时间,我鼓励您实现论文中所述的内容。
编辑:
以下是Levenberg-Marquardt优化器中用于评估残差向量的例程:
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);
}
顺便说一下,我在互联网上搜索了一些其他代码,可以用于计算相机之间的相对定位。虽然我还没有尝试过这些代码,但它们似乎很有用:
http://www9.in.tum.de/praktika/ppbv.WS02/doc/html/reference/cpp/toc_tools_stereo.html
cv::calibrateCamera(...)
的工作方式与您提出的方法非常相似。他们将算法描述如下: - Martin Hennigcv::calibrateCamera
文档的链接:http://opencv.willowgarage.com/documentation/cpp/camera_calibration_and_3d_reconstruction.html - Martin Hennigcv::calibrateCamera(...)
在计算过程中使用了 cv::stereoCalibrate()
。 - Martin Hennig