我正在做一些SfM并且遇到从基本矩阵中获得R和T的麻烦。
以下是我在源代码中所做的事情:
Mat fundamental = Calib3d.findFundamentalMat(object_left, object_right);
Mat E = new Mat();
Core.multiply(cameraMatrix.t(), fundamental, E); // cameraMatrix.t()*fundamental*cameraMatrix;
Core.multiply(E, cameraMatrix, E);
Mat R = new Mat();
Mat.zeros(3, 3, CvType.CV_64FC1).copyTo(R);
Mat T = new Mat();
calculateRT(E, R, T);
where `calculateRT` is defined as follows:
private void calculateRT(Mat E, Mat R, Mat T) {
/*
* //-- Step 6: calculate Rotation Matrix and Translation Vector
Matx34d P;
//decompose E
SVD svd(E,SVD::MODIFY_A);
Mat svd_u = svd.u;
Mat svd_vt = svd.vt;
Mat svd_w = svd.w;
Matx33d W(0,-1,0,1,0,0,0,0,1);//HZ 9.13
Mat_<double> R = svd_u * Mat(W) * svd_vt; //
Mat_<double> T = svd_u.col(2); //u3
if (!CheckCoherentRotation (R)) {
std::cout<<"resulting rotation is not coherent\n";
return 0;
}
*/
Mat w = new Mat();
Mat u = new Mat();
Mat vt = new Mat();
Core.SVDecomp(E, w, u, vt, Core.DECOMP_SVD); // Maybe use flags
Mat W = new Mat(new Size(3,3), CvType.CV_64FC1);
W.put(0, 0, W_Values);
Core.multiply(u, W, R);
Core.multiply(R, vt, R);
T = u.col(2);
}
以下是计算后和计算过程中所有矩阵的结果。
Number matches: 10299
Number of good matches: 590
Number of obj_points left: 590.0
CameraMatrix:
[1133.601684570312, 0, 639.5;
0 , 1133.601684570312, 383.5;
0, 0, 1]
DistortionCoeff: [0.06604336202144623; 0.21129509806633; 0; 0; -1.206771731376648]
Fundamental:
[4.209958176688844e-08, -8.477216249742946e-08, 9.132798068178793e-05;
3.165719895008366e-07, 6.437858397735847e-07, -0.0006976204595236443;
0.0004532506630569588, -0.0009224427024602799, 1]
Essential:
[0.05410018455525099, 0, 0;
0, 0.8272987826496967, 0;
0, 0, 1]
U: (SVD)
[0, 0, 1;
0, 0.9999999999999999, 0;
1, 0, 0]
W: (SVD)
[1; 0.8272987826496967; 0.05410018455525099]
vt: (SVD)
[0, 0, 1;
0, 1, 0;
1, 0, 0]
R:
[0, 0, 0;
0, 0, 0;
0, 0, 0]
T:
[1; 0; 0]
在制作FeaturePoints等之前,我正在对图像进行不正确的处理。
有人可以指出出错的地方或我做错了吗?
编辑:问题 我的基本矩阵是否可能与基本矩阵相等,因为我处于校准状态,Hartley和zissermann说:
“11.7.3校准案例: 在校准相机的情况下,可以使用归一化图像坐标,并且计算基本矩阵E而不是基本矩阵“
答案 0 :(得分:1)
我发现了错误。这段代码没有做正确的矩阵乘法。
Mat E = new Mat();
Core.multiply(cameraMatrix.t(),fundamental, E);
Core.multiply(E, cameraMatrix, E);
我将此更改为
Core.gemm(cameraMatrix.t(), fundamental, 1, cameraMatrix, 1, E);
现在正在进行正确的矩阵乘法。据我所知,Core.multiply正在为每个元素进行乘法运算。不是row * col。的点积。
答案 1 :(得分:0)
首先,除非您通过明确考虑相机矩阵的倒数计算基本矩阵,否则您不在校准情况下,因此您估计的基本矩阵不是必要矩阵。这也很容易测试:你只需要对基本矩阵进行特征分解,看看这两个非零特征值是否相等(参见Hartley&amp; Zisserman's book中的第9.6.1节)。
其次,基本矩阵和基本矩阵都是针对两个摄像头定义的,如果只考虑一个摄像头则没有意义。如果你有两个相机,各自的矩阵K 1 和K 2 ,那么你可以得到基本矩阵E 12 ,给定基本矩阵F 12 (将I 1 中的点映射到I 2 中的行),使用下面的公式(参见Hartley&amp; Zisserman's中的公式9.12)书):
E 12 = K 2 T 。 F 12 。 ķ<子> 1 子>
在您的情况下,您在两侧都使用了K 2 。