计算内在相机参数时获取复数
Posted
技术标签:
【中文标题】计算内在相机参数时获取复数【英文标题】:Getting complex numbers when calculating intrinsic camera parameters 【发布时间】:2018-09-30 17:19:08 【问题描述】:我正在尝试在 MATlab 中实现 Zhang 的相机校准算法。执行此操作的步骤应该非常简单且易于实施,尤其是使用 MATLab。但是,我一直被困在我得到复数的地方,而我应该得到实数。
如果你们中的任何人以前做过这个,你就知道必须做什么。第一步是拍摄棋盘的图像,并使用以下方程计算模型平面和图像平面之间的单应映射(我基本上会包含我的大部分代码,因为它非常小):
for i=1:n
p=[X(i,:) z -x(i,1).*X(i,1) -x(i,1).*X(i,2) -x(i,1)];
q=[z X(i,:) -x(i,2).*X(i,1) -x(i,2).*X(i,2) -x(i,2)];
E=[E;p;q];
end
其中 X 保存世界平面中棋盘角的齐次坐标,x 保存图像平面中的齐次坐标。
下一步是求解方程 EH = 0 得到 H:
[u d v]=svd(E);
H= v(:,end);
H= reshape(H,3,3)';
我不打算详细说明每个变量在剩余代码中的含义,因为我假设我会从已经这样做的人那里获得帮助(这是一个非常流行的算法),所以我将按原样放置代码并附上一些评论:
vij = @(i,j,H) [ H(i,1)*H(j,1)
H(i,1)*H(j,2) + H(i,2)*H(j,1)
H(i,2)*H(j,2)
H(i,3)*H(j,1) + H(i,1)*H(j,3)
H(i,3)*H(j,2) + H(i,2)*H(j,3)
H(i,3)*H(j,3) ];
G = [ vij(1,2,H)'; (vij(1,1,H)-vij(2,2,H))' ];
V = [ V; G ];
当然,在上面的代码块中,我们处于一个循环中,该循环运行的次数与图像的数量一样多
接下来是整个算法中最直接的部分,你不会出错,我们计算内在参数:
[u1,d1,v1] = svd( V );
b = v1(:,end);
v0 = ( b(2)*b(4)-b(1)*b(5) ) / ( b(1)*b(3)-b(2)^2 );
lambda = b(6) - ( b(4)^2 + v0*(b(2)*b(4)-b(1)*b(5)) ) / b(1);
b(1)
alpha = sqrt( lambda / b(1) );
beta = sqrt( lambda*b(1) / (b(1)*b(3)-b(2)^2) );
gamma = -b(2)*alpha^2*beta / lambda;
u0 = gamma*v0 / beta - b(4)*alpha^2 / lambda;
A = [ alpha gamma u0;
0 beta v0;
0 0 1 ]
然后,我们需要考虑图像平面和世界平面之间正方形大小的差异,因此我们构建了一个归一化矩阵:
N = [ 2/width 0 -1
0 2/height -1
0 0 1 ];
其中高度和宽度是以像素为单位的图像。
最后,可以通过以下行获得内在矩阵A:
A = N\A;
现在,为了确保我得到准确的结果,我将我的结果与加州理工学院的校准工具 (Bouget) 进行了比较,出于某种原因,我得到了正确的 u0 和 v0,但其余的 (alpha,beta, gamma ) 很遥远,实际上它们是复数。
我意识到这是因为 lambda 可能是负数。除此之外,不应该!这就是问题所在!
我已经在线查看了数百个实现,它们都与我的非常接近,但它们都完全正确。令我难以置信的是,我的 u0 和 v0 完全正确,而其他的只是复杂的胡言乱语。
你能帮忙吗?我真的很感激!
【问题讨论】:
你能解决这个问题吗?我遇到了同样的问题。 你发现了吗? 【参考方案1】:可能有点太琐碎了,但是您是否尝试过使用除i
和j
之外的其他变量名?
【讨论】:
以上是关于计算内在相机参数时获取复数的主要内容,如果未能解决你的问题,请参考以下文章