pic*_*ter 10 opencv translation rotation motion 3d-reconstruction
我正在尝试根据相应图像的运动计算新的摄像机位置.图像符合针孔相机模型.
事实上,我没有得到有用的结果,所以我试着描述我的程序,并希望有人可以帮助我.
我将相应图像的特征与SIFT匹配,将它们与OpenCV的FlannBasedMatcher匹配,并使用OpenCV的findFundamentalMat(方法RANSAC)计算基本矩阵.
然后我通过相机内部矩阵(K)计算基本矩阵:
Mat E = K.t() * F * K;
Run Code Online (Sandbox Code Playgroud)
我通过奇异值分解将基本矩阵分解为旋转和平移:
SVD decomp = SVD(E);
Matx33d W(0,-1,0,
1,0,0,
0,0,1);
Matx33d Wt(0,1,0,
-1,0,0,
0,0,1);
R1 = decomp.u * Mat(W) * decomp.vt;
R2 = decomp.u * Mat(Wt) * decomp.vt;
t1 = decomp.u.col(2); //u3
t2 = -decomp.u.col(2); //u3
Run Code Online (Sandbox Code Playgroud)
然后我尝试通过三角测量找到正确的解决方案.(这部分来自http://www.morethantechnical.com/2012/01/04/simple-triangulation-with-opencv-from-harley-zisserman-w-code/所以我认为这应该是正确的).
然后计算新职位:
new_pos = old_pos + -R.t()*t;
Run Code Online (Sandbox Code Playgroud)
其中new_pos&old_pos是向量(3x1),R是旋转矩阵(3x3),t是平移向量(3x1).
不幸的是,我没有得到任何有用的结果,所以也许任何人都知道可能出现的问题.
以下是一些结果(以防万一有人可以确认其中任何一个肯定是错误的):
F = [8.093827077399547e-07, 1.102681999632987e-06, -0.0007939604310854831;
1.29246107737264e-06, 1.492629957878578e-06, -0.001211264339006535;
-0.001052930954975217, -0.001278667878010564, 1]
K = [150, 0, 300;
0, 150, 400;
0, 0, 1]
E = [0.01821111092414898, 0.02481034499174221, -0.01651092283654529;
0.02908037424088439, 0.03358417405226801, -0.03397110489649674;
-0.04396975675562629, -0.05262169424538553, 0.04904210357279387]
t = [0.2970648246214448; 0.7352053067682792; 0.6092828956013705]
R = [0.2048034356172475, 0.4709818957303019, -0.858039396912323;
-0.8690270040802598, -0.3158728880490416, -0.3808101689488421;
-0.4503860776474556, 0.8236506374002566, 0.3446041331317597]
Run Code Online (Sandbox Code Playgroud)
who*_*9vy 11
首先,你应该检查一下
x' * F * x = 0
Run Code Online (Sandbox Code Playgroud)
为你的点对应x'和x.当然,这应该仅仅是使用RANSAC进行基本矩阵估计的内点的情况.
此后,您必须将点对应关系转换为标准化图像坐标(NCC)
xn = inv(K) * x
xn' = inv(K') * x'
Run Code Online (Sandbox Code Playgroud)
其中K'是第二图像的固有相机矩阵,并且x'是第二图像的点.我想你的情况就是这样K = K'.
使用这些NCC,您可以像您描述的那样分解您的基本矩阵.您可以对标准化的摄像机坐标进行三角测量并检查三角测量点的深度.但要小心,在文献中他们说一点就足以得到正确的轮换和翻译.根据我的经验,你应该检查几点,因为即使在RANSAC之后,一点也可能是异常值.
在分解基本矩阵之前,请确保E=U*diag(1,1,0)*Vt.需要这个条件才能获得投影矩阵的四种可能选择的正确结果.
当您获得正确的旋转和平移时,您可以对所有点对应进行三角测量(使用RANSAC进行基本矩阵估计的内点).然后,您应该计算重投影错误.首先,您可以像这样计算重新投影的位置
xp = K * P * X
xp' = K' * P' * X
Run Code Online (Sandbox Code Playgroud)
X计算的(同质)3D位置在哪里.P并且P'是3x4投影矩阵.投影矩阵P通常由身份给出.P' = [R, t]由前3列和行中的旋转矩阵和第4列中的平移给出,因此它P是3×4矩阵.这仅适用于将3D位置转换为齐次坐标,即4x1向量而不是3x1.然后,xp和xp'也表示你对你的对应点的(再投影)2D位置齐次坐标.
我觉得
new_pos = old_pos + -R.t()*t;
Run Code Online (Sandbox Code Playgroud)
是不正确的,因为首先,你只翻译old_pos,你不旋转它,其次,你用错误的向量翻译它.上面给出了正确的方法.
因此,在计算出重新投影的点后,您可以计算重投影错误.由于您使用齐次坐标,因此必须对它们进行标准化(xp = xp / xp(2)除以最后一个坐标).这是由
error = (x(0)-xp(0))^2 + (x(1)-xp(1))^2
Run Code Online (Sandbox Code Playgroud)
如果误差很大,例如10 ^ 2,则您的固有摄像机校准或旋转/平移不正确(可能两者都有).根据您的坐标系,您可以尝试反转投影矩阵.因此,您需要将它们转换为齐次坐标,因为您无法反转3x4矩阵(没有伪逆).因此,添加第四行[0 0 0 1],计算反向并删除第四行.
重投影错误还有一件事.通常,重投影误差是原始点对应(在每个图像中)与重新投影位置之间的平方距离.你可以取平方根来获得两点之间的欧几里德距离.
| 归档时间: |
|
| 查看次数: |
8853 次 |
| 最近记录: |