计算相机固有参数时获取复数

问题描述 投票:0回答:2

我正在尝试在 MATlab 中实现张氏相机标定算法。执行此操作的步骤应该非常简单且易于实施,尤其是使用 MATLab。然而,我一直陷入这样的境地:在我应该得到实数的地方却得到了复数。

如果你们中的任何人以前做过此操作,您就会确切地知道必须做什么。第一步是拍摄棋盘格的图像并使用以下方程计算模型平面和图像平面之间的单应映射(I'我基本上会包含我的大部分代码,因为它非常小):

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 完全正确,而其他的只是复杂的胡言乱语。

你能帮忙吗?我真的很感激!!

python matlab camera camera-calibration calibration
2个回答
0
投票

hj 是列向量,所以 vij 应该如下所示, vij=@(i,j,H)[ H(1,i)*H(1,j); ... H(1,i)*H(2,j)+H(2,i)*H(1,j);... H(2,i)*H(2,j);... H(3,i)*H(1,j)+H(1,i)*H(3,j);... H(3,i)*H(2,j)+H(2,i)*H(3,j);... H(3,i)*H(3,j)];


-1
投票

可能有点太微不足道了,但是您是否尝试过使用除

i
j
之外的其他变量名称?

© www.soinside.com 2019 - 2024. All rights reserved.