我正在研究一个 Structure from Motion 框架,用于使用固定相机生成移动物体的 3D 模型。为此,我遵循此管道:
- 通过关键点获得基本矩阵 F。由于我仍在开发中并且我无法(还)访问我将建模的最终对象,我正在使用一个小对象和两个图像之间手动注释的关键点对来执行此操作:
These是用于计算 F 的对应关系。通过
x'Fx
计算 F 的误差,其中 x' 是右图像的点,x 是左图像的点(以像素坐标表示)给出误差的 0,1196。 使用内在矩阵和基础计算基本矩阵 E:
E = Kleft'*F*Kright
其中 Kleft' 是左相机的逆内在矩阵。通过 SVD 分解,我创建了一个新的 E,它只有两个奇异值等于 1。分解 E 得到 R 和 t。为此,我使用了自制的定制版 OpenCV recoverPose()函数,允许两个不同的相机矩阵。
获取 Pleft 作为对角矩阵,Pright 作为 R 和 t 的构造。
以下是代码的重要部分:
F = findFundamentalMat( alignedLeft.points, alignedRight.points, mask, RANSAC);
E = cameraMatrixLeftInv*F*cameraMatrixRight;
SVD::compute(E, w, u, vt);
Mat diag = Mat::zeros(Size(3,3),6);
diag.at<double>(0,0) = 1;
diag.at<double>(1,1) = 1;
E = u*diag*vt;
int good = recoverPoseFromTwoCameras(E,alignedLeft.points,alignedRight.points,intrinsicsLeft.K,intrinsicsRight.K,R,t,mask);
Pleft = Matx34f::eye();
Pright = Matx34f(R.at<double>(0,0), R.at<double>(0,1), R.at<double>(0,2), t.at<double>(0),
R.at<double>(1,0), R.at<double>(1,1), R.at<double>(1,2), t.at<double>(1),
R.at<double>(2,0), R.at<double>(2,1), R.at<double>(2,2), t.at<double>(2));
然后我使用 viz 可视化相机姿势:
viz::Viz3d myWindow("Results");
viz::WCameraPosition cameraLeft(imgLeft->getIntrinsics().K,imgLeft->getImage());
viz::WCameraPosition cameraRight(imgRight->getIntrinsics().K,imgRight->getImage());
我使用 Pleft 和 Pright 将其放置在查看器中:
myWindow.showWidget("cameraLeft",cameraLeft,Affine3d(Pleft(Range::all(),Range(0,3)),Pleft.col(3)));
myWindow.showWidget("cameraRight",cameraRight,Affine3d(Pright(Range::all(),Range(0,3)),Pright.col(3)));
但是,如果我这样做,结果是相反的。由于声誉低,我不能嵌入多个链接,但相机 1 是相机 2 应该在的位置,反之亦然。
但是如果我像这样应用矩阵:
myWindow.showWidget("cameraLeft",cameraLeft,Affine3d(Pright(Range::all(),Range(0,3)),Pleft.col(3)));
myWindow.showWidget("cameraRight",cameraRight,Affine3d(Pleft(Range::all(),Range(0,3)),Pleft.col(3)));
结果正确。
我错过了什么?
最佳答案
希望你已经成功了!如果没有,最好上传更多数据。例如,特征、您计算的 F/E、相机固有特性。然后我们可以测试你的代码并尝试找到你的错误,否则,有很多可能。
关于c++ - 相机姿态估计被反转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41142102/