我有两个严格并排连接的摄像机,朝着平行的方向看。
的投影矩阵当我对相应点的两个向量执行triangulatePoints
时,我得到了3D空间中的点集合。 3D空间中的所有点都具有负Z坐标。
所以,要深究这个......
我的假设是OpenCV使用右手坐标系。
我假设每个摄影机的初始方向都指向在正Z轴方向。
因此,通过使用像我在开头提到的那些投影矩阵,我会假设相机在这样的空间中定位:
这个假设与我观察到的交叉点的负Z值时的观察结果相冲突。我能想到的唯一解释是OpenCV实际上使用左手坐标系。因此,对于我在开头所述的投影矩阵,这就是摄像机在太空中的定位方式:
这表示我在这种情况下的左相机不在左侧。这就是为什么我得分为负的深度。
此外,如果我尝试将triangulatePoints
与solvePnP
合并,我会遇到问题。
我使用triangulatePoints
的输出作为solvePnP
的输入。我希望相机坐标靠近3D坐标系的原点。我希望计算出的相机位置与开头使用的投影矩阵相匹配。但这不会发生。我得到了一些完全狂野的结果,错过了预期值超过基线长度的10倍。
此示例比上述内容更完整地表示问题。
Here是生成这些点的代码。
移动,设置相机 A 和相机 D ......
Mat cameraMatrix = (Mat_<double>(3, 3) <<
716.731, 0, 660.749,
0, 716.731, 360.754,
0, 0, 1);
Mat distCoeffs = (Mat_<double>(5, 1) << 0, 0, 0, 0, 0);
Mat rotation_a = Mat::eye(3, 3, CV_64F); // no rotation
Mat translation_a = (Mat_<double>(3, 1) << 0, 0, 0); // no translation
Mat rt_a;
hconcat(rotation_a, translation_a, rt_a);
Mat projectionMatrix_a = cameraMatrix * rt_a;
Mat rotation_d = (Mat_<double>(3, 1) << 0, CV_PI / 6.0, 0); // 30° rotation about Y axis
Rodrigues(rotation_d, rotation_d); // convert to 3x3 matrix
Mat translation_d = (Mat_<double>(3, 1) << 100, 0, 0);
Mat rt_d;
hconcat(rotation_d, translation_d, rt_d);
Mat projectionMatrix_d = cameraMatrix * rt_d;
投影 A 和 D 观察时points3D
的像素坐标是多少。
Mat points2D_a = projectionMatrix_a * points3D;
Mat points2D_d = projectionMatrix_d * points3D;
我把它们放在载体中:
vector<Point2f> points2Dvector_a, points2Dvector_d;
之后,我再次生成3D点。
Mat points3DHomogeneous;
triangulatePoints(projectionMatrix_a, projectionMatrix_d, points2Dvector_a, points2Dvector_d, points3DHomogeneous);
Mat triangulatedPoints3D;
transpose(points3DHomogeneous, triangulatedPoints3D);
convertPointsFromHomogeneous(triangulatedPoints3D, triangulatedPoints3D);
现在,triangulatedPoints3D
就像这样开始:
,它们与points3D
相同。
然后是最后一步。
Mat rvec, tvec;
solvePnP(triangulatedPoints3D, points2Dvector_d, cameraMatrix, distCoeffs, rvec, tvec);
结果rvec
和tvec
:
我原本希望得到更类似于projectionMatrix_d
创作中使用的变换,即(100,0,0)的平移和绕Y轴旋转30°。
如果我在创建投影矩阵时使用反转换,如下所示:
Mat rotation_d = (Mat_<double>(3, 1) << 0, CV_PI / 6.0, 0); // 30° rotation about Y axis
Rodrigues(-rotation_d, rotation_d); // NEGATIVE ROTATION
Mat translation_d = (Mat_<double>(3, 1) << 100, 0, 0);
Mat rt_d;
hconcat(rotation_d, -translation_d, rt_d); // NEGATIVE TRANSLATION
Mat projectionMatrix_d = cameraMatrix * rt_d;
然后我得到rvec
和tvec
:
这更有意义。但后来我改变了起始变换,使旋转为负CV_PI / 6.0
- &gt; -CV_PI / 6.0
生成的rvec
和tvec
为:
我想找到解释为什么会发生这种情况的原因。为什么我会从solvePnP
获得如此奇怪的结果。