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

时间:2018-09-30 17:19:08

标签: python matlab camera camera-calibration calibration

我正在尝试在MATlab中实现Zhang的相机校准算法。做到这一点的步骤应该非常简单并且易于实现,尤其是使用MATLab时。但是,我一直陷在一个复杂的数字上,我应该获得一个实数。

如果您以前曾做过此事,您将确切知道要做什么。第一步是拍摄棋盘格图像并使用以下等式计算模型平面与图像平面之间的单应性映射(我基本上将包含我的大部分代码,因为它很小):

add_action( 'woocommerce_view_order', 'custom_action_view_order', 5, 1 );
function custom_action_view_order( $order_id ){
    $value = false;

    if( ! $value ){
        remove_action( 'woocommerce_view_order', 'woocommerce_order_details_table', 10 );

        ## ----- Optionally show customer details (if needed) ----- ##

        if ( ! $order = wc_get_order( $order_id ) ) {
            return;
        }

        if( is_user_logged_in() ){
            wc_get_template( 'order/order-details-customer.php', array( 'order' => $order ) );
        }
    }
}

其中X保持世界平面中棋盘格角的同质坐标,x保持图像平面中的同质坐标。

下一步是求解方程EH = 0以获得H:

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

我不会详细介绍其余代码中每个变量的含义,因为我假设我将从已经这样做的人那里得到帮助(这是一种非常流行的算法),所以我将把代码按原样添加一些注释:

  [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   ]

其中高度和宽度以像素为单位。

最后,内在矩阵A可以通过以下行获得:

N = [ 2/width     0      -1
                0     2/height  -1
                0        0       1 ];

现在,为了确保获得准确的结果,我将我的结果与caltech(Bouget)的校准工具进行了比较,由于某种原因,我正确地获得了u0和v0,但是其余的(alpha,beta, gamma)相去甚远,实际上它们是复数。

我意识到这是因为lambda可能是负数。除此之外,它不应该!就是这个问题!

我从字面上看过数百种在线实现,它们都非常接近我,但是所有人都正确理解了所有内在函数。让我感到困惑的是,我的u0和v0完全正确,而其他的只是复杂的胡言乱语。

可以帮忙吗?我真的很感激!

1 个答案:

答案 0 :(得分:0)

可能有点琐碎,但是您是否尝试过使用ij以外的其他变量名?