Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 校准摄像机获得匹配点进行三维重建,理想测试失败_Matlab_Opencv_Matlab Cvst_3d Reconstruction - Fatal编程技术网

Matlab 校准摄像机获得匹配点进行三维重建,理想测试失败

Matlab 校准摄像机获得匹配点进行三维重建,理想测试失败,matlab,opencv,matlab-cvst,3d-reconstruction,Matlab,Opencv,Matlab Cvst,3d Reconstruction,我以前曾问过“使用校准相机获取匹配点进行三维重建”的问题,但问题没有明确描述。所以在这里,我用一个详细的案例来展示每一步。希望有人能帮我找出我的错误所在 首先,我用坐标创建了10个3D点: >> X = [0,0,0; -10,0,0; -15,0,0; -13,3,0; 0,6,0; -2,10,0; -13,10,0; 0,13,0; -4,13

我以前曾问过“使用校准相机获取匹配点进行三维重建”的问题,但问题没有明确描述。所以在这里,我用一个详细的案例来展示每一步。希望有人能帮我找出我的错误所在

首先,我用坐标创建了10个3D点:

>> X = [0,0,0; 
       -10,0,0; 
       -15,0,0; 
       -13,3,0; 
         0,6,0; 
       -2,10,0; 
       -13,10,0; 
         0,13,0; 
       -4,13,0; 
       -8,17,0]
>> Points1 = [1850, 4254; 
              686.5, 3871.7; 
              126.3, 3687.6; 
              255.2, 4116.5; 
              1653.9, 4987.6; 
              1288.6, 5391.0; 
              37.7, 4944.1; 
              1426.1, 5839.6; 
              960.0, 5669.1; 
              377.3, 5977.8]
>> Points2 = [1850, -854; 
              625.4, -585.8; 
              -11.3, -446.3; 
              348.6, -117.7; 
              2046.1, -110.1; 
              1939.0, 442.9; 
              588.6, 776.9; 
              2273.9, 754.0; 
              1798.1, 875.7; 
              1446.2, 1501.8]
E = K'*F*K;
[u1,w1,v1] = svd(E);
t = (w1(1,1)+w1(2,2))/2;
w1_new = [t,0,0;0,t,0;0,0,0];
E_new = u1*w1_new*v1';
[u2,w2,v2] = svd(E_new);
W = [0,-1,0;1,0,0;0,0,1];
S = [0,0,-1];
P1 = K*eye(3,4);
R = u2*W'*v2';
t = u2*S;
P2 = K*[R t];
for i=1:size(Points1,1)
    A = [P1(3,:)*Poinst1(i,1)-P1(1,:);P1(3,:)*Points1(i,2)-P1(2,:);P2(3,:)*Points2(i,1)-P2(1,:);P2(3,:)*Points2(i,2)-P2(2,:)];
    [u3,w3,v3] = svd(A);
    dpt(i,:) = [v3(1,4) v3(2,4) v3(3,4)];
end
这些点位于本图所示的同一平面上:

我的下一步是使用3D-2D投影代码获得2D坐标。在这一步中,我使用了加州理工学院校准工具箱中名为“project_points.m”的MATLAB代码。此外,我使用OpenCV C++代码验证结果,结果相同。(我使用了cvProjectPoints2())

对于第一个投影,参数为:

>> R = [0, 0.261799387, 0.261799387]
>> T = [0, 20, 100]
>> K = [12800, 0, 1850; 0, 12770, 1700; 0 0 1]
而且没有失真

>> DisCoe = [0,0,0,0]
旋转仅为两次旋转,使用
pi/12
。然后我得到了第一视图的二维坐标:

>> X = [0,0,0; 
       -10,0,0; 
       -15,0,0; 
       -13,3,0; 
         0,6,0; 
       -2,10,0; 
       -13,10,0; 
         0,13,0; 
       -4,13,0; 
       -8,17,0]
>> Points1 = [1850, 4254; 
              686.5, 3871.7; 
              126.3, 3687.6; 
              255.2, 4116.5; 
              1653.9, 4987.6; 
              1288.6, 5391.0; 
              37.7, 4944.1; 
              1426.1, 5839.6; 
              960.0, 5669.1; 
              377.3, 5977.8]
>> Points2 = [1850, -854; 
              625.4, -585.8; 
              -11.3, -446.3; 
              348.6, -117.7; 
              2046.1, -110.1; 
              1939.0, 442.9; 
              588.6, 776.9; 
              2273.9, 754.0; 
              1798.1, 875.7; 
              1446.2, 1501.8]
E = K'*F*K;
[u1,w1,v1] = svd(E);
t = (w1(1,1)+w1(2,2))/2;
w1_new = [t,0,0;0,t,0;0,0,0];
E_new = u1*w1_new*v1';
[u2,w2,v2] = svd(E_new);
W = [0,-1,0;1,0,0;0,0,1];
S = [0,0,-1];
P1 = K*eye(3,4);
R = u2*W'*v2';
t = u2*S;
P2 = K*[R t];
for i=1:size(Points1,1)
    A = [P1(3,:)*Poinst1(i,1)-P1(1,:);P1(3,:)*Points1(i,2)-P1(2,:);P2(3,:)*Points2(i,1)-P2(1,:);P2(3,:)*Points2(i,2)-P2(2,:)];
    [u3,w3,v3] = svd(A);
    dpt(i,:) = [v3(1,4) v3(2,4) v3(3,4)];
end
对于第二个视图,我更改了:

>> R = [0, -0.261799387, -0.261799387]
>> T = [0, -20, 100]
然后得到第二视图的二维坐标:

>> X = [0,0,0; 
       -10,0,0; 
       -15,0,0; 
       -13,3,0; 
         0,6,0; 
       -2,10,0; 
       -13,10,0; 
         0,13,0; 
       -4,13,0; 
       -8,17,0]
>> Points1 = [1850, 4254; 
              686.5, 3871.7; 
              126.3, 3687.6; 
              255.2, 4116.5; 
              1653.9, 4987.6; 
              1288.6, 5391.0; 
              37.7, 4944.1; 
              1426.1, 5839.6; 
              960.0, 5669.1; 
              377.3, 5977.8]
>> Points2 = [1850, -854; 
              625.4, -585.8; 
              -11.3, -446.3; 
              348.6, -117.7; 
              2046.1, -110.1; 
              1939.0, 442.9; 
              588.6, 776.9; 
              2273.9, 754.0; 
              1798.1, 875.7; 
              1446.2, 1501.8]
E = K'*F*K;
[u1,w1,v1] = svd(E);
t = (w1(1,1)+w1(2,2))/2;
w1_new = [t,0,0;0,t,0;0,0,0];
E_new = u1*w1_new*v1';
[u2,w2,v2] = svd(E_new);
W = [0,-1,0;1,0,0;0,0,1];
S = [0,0,-1];
P1 = K*eye(3,4);
R = u2*W'*v2';
t = u2*S;
P2 = K*[R t];
for i=1:size(Points1,1)
    A = [P1(3,:)*Poinst1(i,1)-P1(1,:);P1(3,:)*Points1(i,2)-P1(2,:);P2(3,:)*Points2(i,1)-P2(1,:);P2(3,:)*Points2(i,2)-P2(2,:)];
    [u3,w3,v3] = svd(A);
    dpt(i,:) = [v3(1,4) v3(2,4) v3(3,4)];
end
然后是重建步骤,我已经建立了理想的匹配点(我想是的),下一步是计算基本矩阵,使用
estimateFundamentalMatrix()

对于已知的
K
,我使用下面的matlab代码来计算基本矩阵,并计算
R
t
,最后是3D坐标:

>> X = [0,0,0; 
       -10,0,0; 
       -15,0,0; 
       -13,3,0; 
         0,6,0; 
       -2,10,0; 
       -13,10,0; 
         0,13,0; 
       -4,13,0; 
       -8,17,0]
>> Points1 = [1850, 4254; 
              686.5, 3871.7; 
              126.3, 3687.6; 
              255.2, 4116.5; 
              1653.9, 4987.6; 
              1288.6, 5391.0; 
              37.7, 4944.1; 
              1426.1, 5839.6; 
              960.0, 5669.1; 
              377.3, 5977.8]
>> Points2 = [1850, -854; 
              625.4, -585.8; 
              -11.3, -446.3; 
              348.6, -117.7; 
              2046.1, -110.1; 
              1939.0, 442.9; 
              588.6, 776.9; 
              2273.9, 754.0; 
              1798.1, 875.7; 
              1446.2, 1501.8]
E = K'*F*K;
[u1,w1,v1] = svd(E);
t = (w1(1,1)+w1(2,2))/2;
w1_new = [t,0,0;0,t,0;0,0,0];
E_new = u1*w1_new*v1';
[u2,w2,v2] = svd(E_new);
W = [0,-1,0;1,0,0;0,0,1];
S = [0,0,-1];
P1 = K*eye(3,4);
R = u2*W'*v2';
t = u2*S;
P2 = K*[R t];
for i=1:size(Points1,1)
    A = [P1(3,:)*Poinst1(i,1)-P1(1,:);P1(3,:)*Points1(i,2)-P1(2,:);P2(3,:)*Points2(i,1)-P2(1,:);P2(3,:)*Points2(i,2)-P2(2,:)];
    [u3,w3,v3] = svd(A);
    dpt(i,:) = [v3(1,4) v3(2,4) v3(3,4)];
end
根据这段代码,我得到如下结果:

>>X_result = [-0.00624167168027166  -0.0964921215725801 -0.475261364542900;
               0.0348079221692933   -0.0811757557821619 -0.478479857606225;
               0.0555763217997650   -0.0735028994611970 -0.480026199527202;
               0.0508767193762549   -0.0886557226954657 -0.473911682320574;
               0.00192300693541664  -0.121188713743347  -0.466462048338988;
               0.0150597271598557   -0.133665834494933  -0.460372995991565;
               0.0590515135110533   -0.115505488681438  -0.460357357303399;
               0.0110271144368152   -0.148447743355975  -0.455752218710129;
               0.0266380667320528   -0.141395768700202  -0.454774266762764;
               0.0470113238869852   -0.148215424398514  -0.445341461836899]
在Geomagic中显示这些点,结果是“有点弯曲”。但这些立场似乎是正确的。我不知道为什么会这样。有人知道吗?请看图片:

它看起来像是数值不准确,可能在函数estimateFundamentalMatrix()中

我的第二个猜测是,您的estimateFundamentalMatrix()没有处理平面情况,这是某些算法的退化情况(例如,线性8点算法不能很好地处理平面场景)

对于平面场景(至少2个解),未校准的基本矩阵估计是不明确的。例如,请参见Hartley&Zisserman的“多视图几何体”