• OpenCV相机标定


    标签(空格分隔): Opencv


    相机标定是图像处理的基础,虽然相机使用的是小孔成像模型,但是由于小孔的透光非常有限,所以需要使用透镜聚焦足够多的光线。在使用的过程中,需要知道相机的焦距、成像中心以及倾斜因子(matlab的模型有考虑,实际中这个因子很小,也可以不考虑)。为了增加光照使用了透镜,而使用透镜的代价是会产生畸变,现在市面上买到的相机,都存在着或多或少的畸变。畸变的种类比较多,这里介绍常见的两种:径向畸变、切向畸变。相机标定就是求解相机的内参数以及畸变参数的过程。

    畸变种类

    (1)径向畸变(参考自《学习opencv》412页)
    摄像头的透镜在传感器的边缘产生显著的畸变,如下图所示。对于径向畸变,光学中心的畸变为-,随着向边缘移动,畸变会越来越严重。由于畸变比较小,所以可以用泰勒级数的低阶项来近似。

    径向畸变

    (2)切向畸变。
    另外一种需要考虑的相机畸变是切向畸变,切向畸变的主要原因是透镜本身和图像平面不平行,如下左图所示。切向畸变导致的结果是在成像平面上所成的像为下右图所示。
    切向畸变原因 切向畸变结果

    相机的标定

    相机的标定主要有两种:传统的摄像头标定方法和摄像头自标定方法,典型的有:(1)Tsai(传统的标定方法);(2)张正友(介于传统和自标定之间)。张正友标定方法由于简单、效果好而得到广泛使用。这里只介绍张正友标定方法。

    • 张正友标定法的标定步骤
      1、打印一张模板并贴在一个平面上;
      2、从不同角度拍摄若干张模板图像;
      3、检测出图像中的特征点;
      4、求出摄像机的外参数(单应性矩阵)和内参数(最大似然估计) ;
      5、求出畸变系数;
      6、优化求精。

    • 理论基础
      现在来介绍张正友标定方法中的理论知识,以飨读者。张正友标定方法的主要思想是、
      1、相机内参矩阵

    [q=MQ ]

    其中,$$
    q=left[
    egin{array}{c}
    u
    v
    w
    end{array}
    ight] ,quad
    M=
    left[
    egin{array}{ccc}
    f_x & s & c_x
    0 & f_y & c_y
    0 & 0 & 1
    end{array}
    ight],quad
    Q=left[
    egin{array}{c}
    X
    Y
    Z
    end{array}
    ight]

    [ $q$的坐标系是默认的OpenCV的像素坐标系,$Q$的坐标系是标定板坐标系,Z轴为0,原点在标定板的某个内角点上(标定板上角点的坐标均为[*,*,0]的形式),在Open CV 3.0中使用的是($[i*Squres\_Size,j*Square\_Size,0]$的形式)。其中$f_x$和$f_y$表示相机$x$轴和$y$轴的焦距,$s$表示成像平面$x$轴和$y$轴的不正交性(OpenCV模型中把该项置为0,Matlab考虑了该项)。 2、基础公式 对于不同位置的棋盘格到相机的成像,可以使用下面的公式进行表示: $$s ilde{m}=A[R|t] ilde{M}]

    其中,([R|t])表示棋盘格坐标系相对于相机坐标系的位姿。把矩阵(R)( ilde{M})写开,如下式所示:

    [ ilde{m}= left[ egin{array}{c} u \ v \ 1 end{array} ight],quad ilde{M}= left[ egin{array}{c} X \ Y \ 0 \ 1 end{array} ight],quad R=[r_1quad r_2quad r_3],quad ilde{M}= left[ egin{array}{c} X \ Y \ 0 \ 1 end{array} ight] ]

    进行化简得到:

    [s left[ egin{array}{c} u \ v \ 1 end{array} ight]=A[r_1quad r_2quad t] left[ egin{array}{c} X \ Y \ 1 end{array} ight] ]

    其中([uquad vquad 1])是已知量,([Xquad Yquad 1])也是已知量,(A)([r_1quad r_2 quad t])是未知量。
    其中(H=A[r_1quad r_2quad t])又叫做单应性矩阵,可以使用下面的(3)中所述的方法求解。
    3、单应矩阵求解:
    这里使用的方法基于最大似然准则:假设提取的(m)存在均值为0,噪声协方差矩阵为的高斯白噪声。
    则优化目标为

    [sum_{i}(m_i-hat{m}_i)^TLambda_{m_i}^{-1}(m_i - hat{m}_i) ]

    其中$$m_i= frac{1}{overline{h}_3^TM_i}
    left[
    egin{array}{c}
    overline{h}_1^TM_i
    overline{h}_2^TM_i
    end{array}
    ight]$$,其中(overline{h}_i)是矩阵(H)的第(i)列,并且假设(Lambda_{m_i}=sigma^2 I)(m_i)(M_i)已知)
    求解上面的非线性优化问题可以使用LM算法。
    (1)初始值求解
    (x=[overline{h}_1,overline{h}_2,overline{h}_3]),则(s ilde{m}=H ilde{M})可以重写为

    [left[ egin{array}{ccc} ilde{M}^T & 0^T & -u ilde{M}^T \ 0^T & ilde{M}^T & -v ilde{M}^T end{array} ight]x=0 ]

    对于(n)个点,对应(n)个方程,(Lx=0),其中(x)(1 imes 9)的,(L)(2n imes 9)的。(x)的解对应于(L)的最小奇异值的右奇异向量。
    Q:为什么用svd求了,还需要用最大似然方法来优化?svd求的(H)是有误差的,需要用优化来精确求解。
    4、求解相机内参
    (1)利用约束条件求解内参矩阵A
    在公式中,由于(r_1)(r_2)是单位向量且是正交的,所以存在下面的关系:

    [h_1^TA^{-T}A^{-1}h_2=0\ h_1^TA^{-T}A^{-1}h_1=h_2^TA^{-T}A^{-1}h_2]

    上面的公式写成方程组的形式如下所示:

    [left[ egin{array}{c} v_{12}^T \ (v_{11}-v_{22})^T end{array} ight] b=0 ]

    上面的等式是一个最小二乘问题,可以使用SVD求解.由于A有5个参数:(alpha,eta,u_0,v_0,gamma),一个单应性矩阵对应两个约束,所以求解A需要3个单应性矩阵,也就是最小需要3幅图像(超定方程)。当然,
    也可以使用两个单应性矩阵,此时需要令(gamma=0)。算出了b之后,可以用下面的公式求(A)

    [v_0=(B_{12}B_{13}-B_{11}B_{23})/(B_{11}B_{22}-B_{12}^2)\ lambda=B_{33}-[B_{13}^2+v_0(B_{12}B_{13}-B_{11}B_{23})]/B_{11} \ alpha = sqrt{lambda/B_{11}}\ eta=sqrt{lambda B_{11}/(B_{11}B_{12}-B_{12}^2)} \ gamma= -B_{12}alpha^2 eta / lambda \ u_0 =gamma v_0 / eta - B_{13}alpha^2 / lambda ]

    5、求解相机外参
    在上面求解了相机的内参之后,可以求出棋盘格的位姿,公式如下:

    [r_1 = lambda A^{-1}h_1 \ r_2 = lambda A^{-1}h_2 \ r_3 = r_1 imes h_2 t = lambda A^{-1} h_3 ]

    在OpenCV中,上面的公式是用来求解优化参数的初始值的,最终的结果是使用优化的方法得到的。
    由于存在误差,还是需要迭代求解以提高精度(问题描述如下):
    给定棋盘格的(n)个图像和(m)个角点,并假设图像点被独立同分布的噪声影响。
    似然函数如下所示:

    [sum_{i=1}^{n}sum_{j=1}^{m}=Vert m_{ij}-m(A,R_i, t_i, M_j)Vert^2 ]

    其中旋转矩阵(R)用向量(r)表示(罗巨格公式)
    6、相机的畸变参数求解
    上面的讨论中一直没有引入相机畸变的问题,这里引入相机的畸变。
    ((u,v))为理想的像素坐标,((reve{u},reve{v}))为实际观测得到的像素坐标(受到畸变)。同样的,有归一化的相机坐标系((x,y))((reve{x},reve{y}))
    对于径向畸变(这是张正友上的模型,泰勒展开):

    [reve{x}=x+x[K_1(x^2+y^2)+k_2(x^2+y^2)^2]\ reve{y}=y+y[K_1(x^2+y^2)+k_2(x^2+y^2)^2] ]

    用像素坐标表示则为:

    [reve{u}=u+(u-u_0)[K_1(x^2+y^2)+k_2(x^2+y^2)^2]\ reve{v}=v+(v-v_0)[K_1(x^2+y^2)+k_2(x^2+y^2)^2] ]

    写成如下形式:

    [left[ egin{array}{cc} (u-u_0)(x^2+y^2) & (u-u_0)(x^2+y^2)^2\ (v-v_0)(x^2+y^2) & (v-v_0)(x^2+y^2) end{array} ight] left[ egin{array}{c} k_1 \ k_2 end{array} ight]= left[ egin{array}{c} reve{u}-u \ reve{v}-v end{array} ight] ]

    给定(n)个图像中的(m)个点,可以得到(2mn)个方程,记为(Dk=d)
    (k=(D^TD)^{-1}D^Td)
    最小二乘方法求解:

    [sum_{i=1}^{n}sum_{j=1}^{m}Vert m_{ij}-reve{m} (A,k_1,k_2,R_i,t_i,M_j)Vert^2 ]

    如果求解了畸变参数(k_1)(k_2),则可以求解出没有畸变的坐标,从而使用上面的方法求解位姿和内参。
    畸变参数(k_1)(k_2)初始化可以简单的设为0,也可以使用后续的估计方法。
    OpenCV的模型(《学习OpenCV》,这是Brown和Fryer的工作)还包括了切向畸变,并且镜像畸变有三项。因此,opencv中一共有五个参数([k_1,k_2,p1,p2,k_3])

    OpenCV的标定步骤

    1、初始化参数求解;
    a、求解单应性矩阵;
    b、根据理论的第4步求解相机内参的初始值;
    c、根据理论的第5步求解相机外参的初始值;
    d、畸变参数设置为0。
    2、迭代求解总体最小二乘问题,也就是上面6所示的最小二乘问题。

    后面会接着介绍最小二乘中的数学相关知识。

  • 相关阅读:
    js判断undefined类型
    js replace 全部替换
    第五次作业--原型设计
    第三次作业--团队展示
    第二次作业——数独终盘
    软件工程实践2017第一次作业
    课堂作业2
    课堂作业1
    第四次作业 计算器第二步
    第三次作业
  • 原文地址:https://www.cnblogs.com/jian-li/p/5615931.html
Copyright © 2020-2023  润新知