精华内容
下载资源
问答
  • 关于摄像机定位中很重要的一个步骤:摄像机标定的一种常用的方法。由微软张正友提出
  • 击上方“新机器视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达前言”张正友标定”是指张正友教授1998年提出的单平面棋盘格的摄像机标定方法[1]。文中提出的方法介于传统标定法和自标定法之间,但克服了传统...

    击上方新机器视觉”,选择加"星标"或“置顶”

    重磅干货,第一时间送达ae596da916800e92bb19c00becc7e679.png

    前言

    ”张正友标定”是指张正友教授1998年提出的单平面棋盘格的摄像机标定方法[1]。文中提出的方法介于传统标定法和自标定法之间,但克服了传统标定法需要的高精度标定物的缺点,而仅需使用一个打印出来的棋盘格就可以。同时也相对于自标定而言,提高了精度,便于操作。因此张氏标定法被广泛应用于计算机视觉方面。

    原理

    1.计算外参
    • 设三维世界坐标的点为M=[X,Y,Z,1]T,二维相机平面像素坐标为m=[u,v,1]T,所以标定用的棋盘格平面到图像平面的单应性关系为:sm=A[R,t]M
      其中

      fef5e53baa22ece9da99bf9898cf0191.png


      不妨设棋盘格位于Z = 0,定义旋转矩阵R的第i列为 ri, 则有:

      ffc2a37a430f41b8f8b6d7df96a45c88.png


      H=[h1 h2 h3]=λA[r1 r2 t]
      于是空间到图像的映射可改为:sm=HM
      其中H是描述Homographic矩阵,H是一个齐次矩阵,所以有8个未知数,至少需要8个方程,每对对应点能提供两个方程,所以至少需要四个对应点,就可以算出世界平面到图像平面的单应性矩阵H

      1895bda5d19cedfacb6a28826f0dd672.png

      外参具体计算公式。注意:R3是 t

    一般而言,求解出的R = [r1 r2 t] 不会满足正交与归一的标准
    在实际操作中,R 可以通过SVD分解实现规范化(详见原文)


    2.计算内参

    由r1和r2正交,且r1和r2的模相等,可以得到如下约束:

    839e45cd189fd4bd20e7d18b9ce89882.png

    正交

    8751fd58034fe88a8132ce53f4831871.png

    模相等

    943e1548fec56f477d602b1f99784996.png

    863f1fce36d48ed546b7e0259031f6c0.png

    可以推到出

    baeca869ff37b99c0c4f53e7e649c966.png

    根据推到的结果可知如果有n组观察图像,则V 是 2n x 6 的矩阵
    根据最小二乘定义,V b = 0 的解是 VTV 最小特征值对应的特征向量。
    因此, 可以直接估算出 b,后续可以通过b求解内参
    因为B中的未知量为6个,
    所以当观测平面 n ≥ 3 时,可以得到b的唯一解
    当 n = 2时, 一般可令畸变参数γ = 0
    当 n = 1时, 仅能估算出α 与 β, 此时一般可假定像主点坐标 u0 与 v0 为0

    内部参数可通过如下公式计算(cholesky分解):

    5ea5187bd8b31bd91d460f4c7de0f334.png

    内参具体计算公式

    3.最大似然估计

    上述的推导结果是基于理想情况下的解,但由于可能存在高斯噪声,所以使用最大似然估计进行优化。设我们采集了n副包含棋盘格的图像进行定标,每个图像里有棋盘格角点m个。令第i副图像上的角点Mj在上述计算得到的摄像机矩阵下图像上的投影点为:

    2c13091aa8ea37887be4c684eae4d13a.png

    这里的K为相机内参矩阵A

    其中Ri和ti是第i副图对应的旋转矩阵和平移向量,K是内参数矩阵。则角点mij的概率密度函数为:

    79dc8c98ce0e0e8694669f65f7cbce3d.png

    这里的K为相机内参矩阵A


    构造似然函数:

    a84662b188523888e4068386f91f5b40.png

    这里的K为相机内参矩阵A


    让L取得最大值,即让下面式子最小。这里使用的是多参数非线性系统优化问题的Levenberg-Marquardt算法[2]进行迭代求最优解。

    5912b386c7492fa65cf060b98f16b610.png

    这里的K为相机内参矩阵A

    4.径向畸变估计

    张氏标定法只关注了影响最大的径向畸变。则数学表达式为:

    c4561e6b0f0a7c2b7146b976bca3563a.png


    其中,(u,v)是理想无畸变的像素坐标,(u,v)(u,v)是实际畸变后的像素坐标。(u0,v0)代表主点,(x,y)是理想无畸变的连续图像坐标,(x,y)(x,y)是实际畸变后的连续图像坐标。k1和k2为前两阶的畸变参数。

    0adbe15f6e7decee8d3321d0cbd0789f.png


    化作矩阵形式:

    7ca1ecb6c6a276372874ff07e127f5ae.png


    记做:Dk=d
    则可得:

    d9aac57d975a7d1c6ef483c651f6ca6d.png


    计算得到畸变系数k。
    使用最大似然的思想优化得到的结果,即像上一步一样,LM法计算下列函数值最小的参数值:

    c6a86ed9937c337775827c172974b1d4.png

    这里的K为相机内参矩阵A


    到此,张氏标定法介绍完毕。我们也得到了相机内参、外参和畸变系数。

    相机标定步骤

    • 打印一张棋盘格A4纸张(黑白间距已知),并贴在一个平板上

    • 针对棋盘格拍摄若干张图片(一般10-20张)

    • 在图片中检测特征点(Harris特征)

    • 利用解析解估算方法计算出5个内部参数,以及6个外部参数

    • 根据极大似然估计策略,设计优化目标并实现参数的refinement

         转自:https://www.jianshu.com/p/9d2fe4c2e3b7

    59fb66d326fd0defa384ade09c3ee3c8.gif End 59fb66d326fd0defa384ade09c3ee3c8.gif

    声明:部分内容来源于网络,仅供读者学习、交流之目的。文章版权归原作者所有。如有不妥,请联系删除。

    eb422a9c67bc7c1f18e48c883dc1e8ea.png

    展开全文
  • 张正友标定算法原理详解

    万次阅读 多人点赞 2016-10-19 16:04:03
    张正友标定算法原理详解

    张正友标定算法原理详解

    本人邮箱:sylvester0510@163.com,欢迎交流讨论,
    欢迎转载,转载请注明网址http://blog.csdn.net/u010128736/


    一、背景

      ”张正友标定”是指张正友教授1998年提出的单平面棋盘格的摄像机标定方法[1]。文中提出的方法介于传统标定法和自标定法之间,但克服了传统标定法需要的高精度标定物的缺点,而仅需使用一个打印出来的棋盘格就可以。同时也相对于自标定而言,提高了精度,便于操作。因此张氏标定法被广泛应用于计算机视觉方面。

    二、计算内参和外参的初值

    1、计算单应性矩阵H

      根据之前博客介绍的摄像机模型,设三维世界坐标的点为X=[X,Y,Z,1]T,二维相机平面像素坐标为m=[u,v,1]T,所以标定用的棋盘格平面到图像平面的单应性关系为:

    s0m=K[R,T]X

    其中s为尺度因子,K为摄像机内参数,R为旋转矩阵,T为平移向量。令
    K=α00γβ0u0v01

    注意,s对于齐次坐标来说,不会改变齐次坐标值。张氏标定法中,将世界坐标系狗仔在棋盘格平面上,令棋盘格平面为Z=0的平面。则可得
    suv1=K[r1r2r3t]XY01=K[r1r2t]XY1

    我们把K[r1, r2, t]叫做单应性矩阵H,即
    suv1=HXY1H=[h1 h2 h3]=λK[r1 r2 t]

    H是一个齐次矩阵,所以有8个未知数,至少需要8个方程,每对对应点能提供两个方程,所以至少需要四个对应点,就可以算出世界平面到图像平面的单应性矩阵H。

    2、计算内参数矩阵

    由上式可得

    λ=1sr1=1λK1h1r2=1λK1h2

      由于旋转矩阵是个酉矩阵,r1和r2正交,可得
    rT1r2=0||r1||=||r2||=1

    代入可得:
    hT1KTK1h2=0hT1KTK1h1=hT2KTK1h2

    即每个单应性矩阵能提供两个方程,而内参数矩阵包含5个参数,要求解,至少需要3个单应性矩阵。为了得到三个不同的单应性矩阵,我们使用至少三幅棋盘格平面的图片进行标定。通过改变相机与标定板之间的相对位置来得到三个不同的图片。为了方便计算,定义如下:
    B=KTK1=B11B21B31B12B22B32B13B23B33=1α2γα2βv0γu0βα2βγα2βγ2α2β2+1β2γ(v0γu0β)α2β2v0β2v0γu0βα2βγ(v0γu0β)α2β2v0β2(v0γu0β)2α2β2+v0β2+1

    可以看到,B是一个对称阵,所以B的有效元素为六个,让这六个元素写成向量b,即
    b=[B11B12B22B13B23B33]T

    可以推导得到
    hTiBhj=vTijbvij=[hi1hj1hi1hj2+hi2hj1hi2hj2hi3hj1+hi1hj3hi3hj2+hi2hj3hi3hj3]T

    利用约束条件可以得到:
    [vT12(v11v22)T]b=0

      通过上式,我们至少需要三幅包含棋盘格的图像,可以计算得到B,然后通过cholesky分解,得到相机的内参数矩阵K。

    3、计算外参数矩阵

      由之前的推导,可得

    λ=1s=1A1h1=1A1h2r1=1λK1h1r2=1λK1h2r3=r1×r2t=λK1h3

    三、最大似然估计

      上述的推导结果是基于理想情况下的解,但由于可能存在高斯噪声,所以使用最大似然估计进行优化。设我们采集了n副包含棋盘格的图像进行定标,每个图像里有棋盘格角点m个。令第i副图像上的角点Mj在上述计算得到的摄像机矩阵下图像上的投影点为:

    m^(K,Ri,ti,Mij)=K[R|t]Mij

    其中Ri和ti是第i副图对应的旋转矩阵和平移向量,K是内参数矩阵。则角点mij的概率密度函数为:
    f(mij)=12πe(m^(K,Ri,ti,Mij)mij)2σ2

    构造似然函数:
    L(A,Ri,ti,Mij)=i=1,j=1n,mf(mij)=12πeni=1mj=1(m^(K,Ri,ti,Mij)mij)2σ2

    让L取得最大值,即让下面式子最小。这里使用的是多参数非线性系统优化问题的Levenberg-Marquardt算法[2]进行迭代求最优解。
    i=1nj=1mm^(K,Ri,ti,Mij)mij2

    四、径向畸变估计

      张氏标定法只关注了影响最大的径向畸变。则数学表达式为:

    u^=u+(uu0)[k1(x2+y2)+k2(x2+y2)2]v^=v+(vv0)[k1(x2+y2)+k2(x2+y2)2]

    其中,(u,v)是理想无畸变的像素坐标,(u^,v^)是实际畸变后的像素坐标。(u0,v0)代表主点,(x,y)是理想无畸变的连续图像坐标,(x^,y^)是实际畸变后的连续图像坐标。k1和k2为前两阶的畸变参数。
    u^=u0+αx^+γy^v^=v0+βy^

    化作矩阵形式:
    [(uu0)(x2+y2)(vv0)(x2+y2)(uu0)(x2+y2)2(vv0)(x2+y2)2][k1k2]=[u^uv^v]

    记做:
    Dk=d

    则可得:
    k=[k1 k2]T=(DTD)1DTd

    计算得到畸变系数k。

      使用最大似然的思想优化得到的结果,即像上一步一样,LM法计算下列函数值最小的参数值:

    i=1nj=1mm^(K,k1,k2,Ri,ti,Mij)mij2

    到此,张氏标定法介绍完毕。我们也得到了相机内参、外参和畸变系数。

    参考

    1、Zhang, Zhengyou - 《IEEE Transactions on Pattern Analysis & Machine Intelligence》 - 2000
    2、J.More.Thelevenberg-marquardtalgorithm,implementationandtheory.InG.A.Watson,
    editor,NumericalAnalysis,LectureNotesinMathematics630.Springer-Verlag,1977.

    展开全文
  • 传统标定法的标定板是需要三维的,需要非常精确,这很难制作,而张正友教授提出的方法介于传统标定法和自标定法之间,但克服了传统标定法需要的高精度标定物的缺点,而仅需使用一个打印出来的棋盘格就可以。...

    点击上方新机器视觉”,选择加"星标"或“置顶

    重磅干货,第一时间送达7d121e15e8262057d3525a5dc976a628.png

    张正友相机标定法是张正友教授1998年提出的单平面棋盘格的相机标定方法。传统标定法的标定板是需要三维的,需要非常精确,这很难制作,而张正友教授提出的方法介于传统标定法和自标定法之间,但克服了传统标定法需要的高精度标定物的缺点,而仅需使用一个打印出来的棋盘格就可以。同时也相对于自标定而言,提高了精度,便于操作。因此张氏标定法被广泛应用于计算机视觉方面。

    d76c7230f292f8d3f3590e093ed82c5d.png     

    传统标定法的的标定板   

                8380ae657aac6f103f9da31e14ec6617.png                   

      张正友标定法的标定板

    今天,我们就来讲解一下张氏标定法的原理和实现,学会之后,我们就可以自己去制作一个棋盘标定板,然后拍照,标定自己手机相机的参数啦!

    今天,我们就来讲解一下张氏标定法的原理和实现,学会之后,我们就可以自己去制作一个棋盘标定板,然后拍照,标定自己手机相机的参数啦!

    一、相机标定介绍

    二、算法原理

    1.整体流程

    2.模型假设

    3.模型求解

    (1)内外参数求解

    (2)畸变系数求解

    (3)精度优化

    三、算法实现

    1.main.py

    2.homography.py

    4.extrinsics.py

    5.distortion.py

    6.refine_all.py

    7.结果

    一、相机标定介绍

    相机标定指建立相机图像像素位置与场景点位置之间的关系,根据相机成像模型,由特征点在图像中坐标与世界坐标的对应关系,求解相机模型的参数。相机需要标定的模型参数包括内部参数和外部参数。

    针孔相机成像原理其实就是利用投影将真实的三维世界坐标转换到二维的相机坐标上去,其模型示意图如下图所示:

    be6c72c6fa51b1bf591303de7e75c35f.png

     从图中我们可以看出,在世界坐标中的一条直线上的点在相机上只呈现出了一个点,其中发生了非常大的变化,同时也损失和很多重要的信息,这正是我们3D重建、目标检测与识别领域的重点和难点。实际中,镜头并非理想的透视成像,带有不同程度的畸变。理论上镜头的畸变包括径向畸变和切向畸变,切向畸变影响较小,通常只考虑径向畸变。

    径向畸变:径向畸变主要由镜头径向曲率产生(光线在远离透镜中心的地方比靠近中心的地方更加弯曲)。导致真实成像点向内或向外偏离理想成像点。其中畸变像点相对于理想像点沿径向向外偏移,远离中心的,称为枕形畸变;径向畸点相对于理想点沿径向向中心靠拢,称为桶状畸变。

    8010c33f6c261a3b1e574dc01437f6ce.png

    4acf8ef0aac0a8a115df9ec26dc5d469.png

    用数学公式来表示:

    fadd1a4946adfa08995fb9894f0d981f.png

    其中,X为相机中的坐标;X为真实世界坐标;K为内参矩阵;RT为外参矩阵 K为内参矩阵,是相机内部参数组成的一个3*3的矩阵,其中,代表焦距;S为畸变参数为da87ffde5f281e930458f0a84b2a15bd.png中心点坐标,a为纵横比例参数,我们可以默认设为1,所以   RT为外参矩阵,R是描述照相机方向的旋转矩阵,T是描述照相机中心位置的三维平移向量。

    二、算法原理

    1.整体流程

    a8b0eccfc380848386cafa392436e48d.png

    2.模型假设

    b70056e6b4a8cb82c7244ad06845a9ee.png

    1e3771387fdd42cac8452fb2bb59a0b6.png

    93a536b639e36355c1ca8399910d5020.png

    31ee7fef989c701357ca6f2f94c05f25.png

    3.模型求解

    (1)内外参数求解

    我们令b308fbc95778006e50c4b7b4eb2b3f34.png,则a13460bbaa876a2f01ef89eeca9a6f14.png

    其中,H为一个3*3的矩阵,并且有一个元素作为齐次坐标。因此,H有8个自由度。

    现在有8个自由度需要求解,所以需要四个对应点。也就是四个点就可以求出图像平面到世界平面的单应性矩阵H。

    我想,张氏标定法选用的棋盘格作为标定板的原因除了角点方便检测的另外一个原因可能就是这个吧。

    通过4个点,我们就可以可以获得单应性矩阵H。但是,H是内参阵和外参阵的合体。我们想要最终分别获得内参和外参。所以需要想个办法,先把内参求出来。然后外参也就随之解出了。观察一下这个式子:

    a13460bbaa876a2f01ef89eeca9a6f14.png

    我们可以知道以下约束条件:

              ①,R1R2  正交,也就是说  R1 R2=0。其实这个不难理解,因为 R1 R2 是分别绕x轴和y轴得到的,而x轴和y轴均垂直z轴。

             ②旋转向量的模为1,也就是说R1=R2=1,这是因为旋转不改变尺度。

    根据这两个约束条件,经过数学变换,我们可以得到:4c12fe17a3714da2541bc9e678aabcf0.png

    观察上面的两个式子,我们可以看出,由于H1和H2是通过单应性求解出来的,所以我们要求解的参数就变成A矩阵中未知的5个参数。我们可以通过三个单应性矩阵来求解这5个参数,利用三个单应性矩阵在两个约束下可以生成6个方程。其中,三个单应性矩阵可以通过三张对同一标定板不同角度和高度的照片获得。

    用数学公式来表达如下:

    bc7d3a9725dd1ad3732e5fb12872d5c3.png

    我们很容易发现B是一个对称阵,所以B的有效元素就剩下6个,即

    797dbf73d53071ebed74d9b9754fad02.png

    进一步化简:

    cdd0b34e7e6fc811b58ec5b2fffe95f1.png

    通过计算,我们可以得到

    a75e73cd91dc5677deffd16144472095.png

    利用上面提到的两个约束条件,我们可以得到下面的方程组:

    4d9344b4e56d70b58359b6665a2755d8.png

      这个方程组的本质和前面那两个用h和A组成的约束条件方程组是一样的。

    通过至少含一个棋盘格的三幅图像,应用上述公式我们就可以估算出B了。得到B后,我们通过cholesky分解 ,就可以得到摄相机机的内参阵A的六个自由度,即:

    7c18973ce4313159bef1197b795e966d.png

    再根据a13460bbaa876a2f01ef89eeca9a6f14.png化简可得外部参数,即:

    21c391b1b40401479038c4e3a5c3eada.png

    (2)畸变系数求解

    在文章的开始,我们就讲到真实的镜头并非理想的透视成像,而是带有不同程度的畸变。理论上镜头的畸变包括径向畸变和切向畸变,切向畸变影响较小,通常只考虑径向畸变,而且在径向畸变的求解中,仅考虑了起主导的二元泰勒级数展开的前两个系数。

    具体推导,参考https://blog.csdn.net/onthewaysuccess/article/details/40736177

    (3)精度优化

    在张正友标定法中,使用了两次极大似然估计策略,第一次是在不考虑畸变的情况下求解内参和外参,第二次是求解实际的畸变系数。

    极大似然参数估计 ,参考https://blog.csdn.net/onthewaysuccess/article/details/40717213

    三、算法实现

    1.main.py

    #!usr/bin/env/ python

    # _*_ coding:utf-8 _*_

    import cv2 as cv

    import numpy as np

    import os

    from step.homography import get_homography

    from step.intrinsics import get_intrinsics_param

    from step.extrinsics import get_extrinsics_param

    from step.distortion import get_distortion

    from step.refine_all import refinall_all_param

    def calibrate():

    #求单应矩阵

    H = get_homography(pic_points, real_points_x_y)

    #求内参

    intrinsics_param = get_intrinsics_param(H)

    #求对应每幅图外参

    extrinsics_param = get_extrinsics_param(H, intrinsics_param)

    #畸变矫正

    k = get_distortion(intrinsics_param, extrinsics_param, pic_points, real_points_x_y)

    #微调所有参数

    [new_intrinsics_param, new_k, new_extrinsics_param]  = refinall_all_param(intrinsics_param,

    k, extrinsics_param, real_points, pic_points)

    print("intrinsics_parm:\t", new_intrinsics_param)

    print("distortionk:\t", new_k)

    print("extrinsics_parm:\t", new_extrinsics_param)

    if __name__ == "__main__":

    file_dir = r'..\pic'

    # 标定所用图像

    pic_name = os.listdir(file_dir)

    # 由于棋盘为二维平面,设定世界坐标系在棋盘上,一个单位代表一个棋盘宽度,产生世界坐标系三维坐标

    cross_corners = [9, 6] #棋盘方块交界点排列

    real_coor = np.zeros((cross_corners[0] * cross_corners[1], 3), np.float32)

    real_coor[:, :2] = np.mgrid[0:9, 0:6].T.reshape(-1, 2)

    real_points = []

    real_points_x_y = []

    pic_points = []

    for pic in pic_name:

    pic_path = os.path.join(file_dir, pic)

    pic_data = cv.imread(pic_path)

    # 寻找到棋盘角点

    succ, pic_coor = cv.findChessboardCorners(pic_data, (cross_corners[0], cross_corners[1]), None)

    if succ:

    # 添加每幅图的对应3D-2D坐标

    pic_coor = pic_coor.reshape(-1, 2)

    pic_points.append(pic_coor)

    real_points.append(real_coor)

    real_points_x_y.append(real_coor[:, :2])

    calibrate()

    2.homography.py

    这是用于求解单应性矩阵的文件

    #!usr/bin/env/ python

    # _*_ coding:utf-8 _*_

    import numpy as np

    from scipy import optimize as opt

    #求输入数据的归一化矩阵

    def normalizing_input_data(coor_data):

    x_avg = np.mean(coor_data[:, 0])

    y_avg = np.mean(coor_data[:, 1])

    sx = np.sqrt(2) / np.std(coor_data[:, 0])

    sy = np.sqrt(2) / np.std(coor_data[:, 1])

    norm_matrix = np.matrix([[sx, 0, -sx * x_avg],

    [0, sy, -sy * y_avg],

    [0, 0, 1]])

    return norm_matrix

    #求取初始估计的单应矩阵

    def get_initial_H(pic_coor, real_coor):

    # 获得归一化矩阵

    pic_norm_mat = normalizing_input_data(pic_coor)

    real_norm_mat = normalizing_input_data(real_coor)

    M = []

    for i in range(len(pic_coor)):

    #转换为齐次坐标

    single_pic_coor = np.array([pic_coor[i][0], pic_coor[i][1], 1])

    single_real_coor = np.array([real_coor[i][0], real_coor[i][1], 1])

    #坐标归一化

    pic_norm = np.dot(pic_norm_mat, single_pic_coor)

    real_norm = np.dot(real_norm_mat, single_real_coor)

    #构造M矩阵

    M.append(np.array([-real_norm.item(0), -real_norm.item(1), -1,

    0, 0, 0,

    pic_norm.item(0) * real_norm.item(0), pic_norm.item(0) * real_norm.item(1), pic_norm.item(0)]))

    M.append(np.array([0, 0, 0,

    -real_norm.item(0), -real_norm.item(1), -1,

    pic_norm.item(1) * real_norm.item(0), pic_norm.item(1) * real_norm.item(1), pic_norm.item(1)]))

    #利用SVD求解M * h = 0中h的解

    U, S, VT = np.linalg.svd((np.array(M, dtype='float')).reshape((-1, 9)))

    # 最小的奇异值对应的奇异向量,S求出来按大小排列的,最后的最小

    H = VT[-1].reshape((3, 3))

    H = np.dot(np.dot(np.linalg.inv(pic_norm_mat), H), real_norm_mat)

    H /= H[-1, -1]

    return H

    #返回估计坐标与真实坐标偏差

    def value(H, pic_coor, real_coor):

    Y = np.array([])

    for i in range(len(real_coor)):

    single_real_coor = np.array([real_coor[i, 0], real_coor[i, 1], 1])

    U = np.dot(H.reshape(3, 3), single_real_coor)

    U /= U[-1]

    Y = np.append(Y, U[:2])

    Y_NEW = (pic_coor.reshape(-1) - Y)

    return Y_NEW

    #返回对应jacobian矩阵

    def jacobian(H, pic_coor, real_coor):

    J = []

    for i in range(len(real_coor)):

    sx = H[0]*real_coor[i][0] + H[1]*real_coor[i][1] +H[2]

    sy = H[3]*real_coor[i][0] + H[4]*real_coor[i][1] +H[5]

    w = H[6]*real_coor[i][0] + H[7]*real_coor[i][1] +H[8]

    w2 = w * w

    J.append(np.array([real_coor[i][0]/w, real_coor[i][1]/w, 1/w,

    0, 0, 0,

    -sx*real_coor[i][0]/w2, -sx*real_coor[i][1]/w2, -sx/w2]))

    J.append(np.array([0, 0, 0,

    real_coor[i][0]/w, real_coor[i][1]/w, 1/w,

    -sy*real_coor[i][0]/w2, -sy*real_coor[i][1]/w2, -sy/w2]))

    return np.array(J)

    #利用Levenberg Marquart算法微调H

    def refine_H(pic_coor, real_coor, initial_H):

    initial_H = np.array(initial_H)

    final_H = opt.leastsq(value,

    initial_H,

    Dfun=jacobian,

    args=(pic_coor, real_coor))[0]

    final_H /= np.array(final_H[-1])

    return final_H

    #返回微调后的H

    def get_homography(pic_coor, real_coor):

    refined_homographies =[]

    error = []

    for i in range(len(pic_coor)):

    initial_H = get_initial_H(pic_coor[i], real_coor[i])

    final_H = refine_H(pic_coor[i], real_coor[i], initial_H)

    refined_homographies.append(final_H)

    return np.array(refined_homographies)

    3.intrinsics.py

    这是用于求解内参矩阵的文件

    #!usr/bin/env/ python

    # _*_ coding:utf-8 _*_

    import numpy as np

    #返回pq位置对应的v向量

    def create_v(p, q, H):

    H = H.reshape(3, 3)

    return np.array([

    H[0, p] * H[0, q],

    H[0, p] * H[1, q] + H[1, p] * H[0, q],

    H[1, p] * H[1, q],

    H[2, p] * H[0, q] + H[0, p] * H[2, q],

    H[2, p] * H[1, q] + H[1, p] * H[2, q],

    H[2, p] * H[2, q]

    ])

    #返回相机内参矩阵A

    def get_intrinsics_param(H):

    #构建V矩阵

    V = np.array([])

    for i in range(len(H)):

    V = np.append(V, np.array([create_v(0, 1, H[i]), create_v(0, 0 , H[i])- create_v(1, 1 , H[i])]))

    #求解V*b = 0中的b

    U, S, VT = np.linalg.svd((np.array(V, dtype='float')).reshape((-1, 6)))

    #最小的奇异值对应的奇异向量,S求出来按大小排列的,最后的最小

    b = VT[-1]

    #求取相机内参

    w = b[0] * b[2] * b[5] - b[1] * b[1] * b[5] - b[0] * b[4] * b[4] + 2 * b[1] * b[3] * b[4] - b[2] * b[3] * b[3]

    d = b[0] * b[2] - b[1] * b[1]

    alpha = np.sqrt(w / (d * b[0]))

    beta = np.sqrt(w / d**2 * b[0])

    gamma = np.sqrt(w / (d**2 * b[0])) * b[1]

    uc = (b[1] * b[4] - b[2] * b[3]) / d

    vc = (b[1] * b[3] - b[0] * b[4]) / d

    return np.array([

    [alpha, gamma, uc],

    [0,     beta,  vc],

    [0,     0,      1]

    ])

    4.extrinsics.py

    这是用于求解外参矩阵的文件

    #!usr/bin/env/ python

    # _*_ coding:utf-8 _*_

    import numpy as np

    #返回每一幅图的外参矩阵[R|t]

    def get_extrinsics_param(H, intrinsics_param):

    extrinsics_param = []

    inv_intrinsics_param = np.linalg.inv(intrinsics_param)

    for i in range(len(H)):

    h0 = (H[i].reshape(3, 3))[:, 0]

    h1 = (H[i].reshape(3, 3))[:, 1]

    h2 = (H[i].reshape(3, 3))[:, 2]

    scale_factor = 1 / np.linalg.norm(np.dot(inv_intrinsics_param, h0))

    r0 = scale_factor * np.dot(inv_intrinsics_param, h0)

    r1 = scale_factor * np.dot(inv_intrinsics_param, h1)

    t = scale_factor * np.dot(inv_intrinsics_param, h2)

    r2 = np.cross(r0, r1)

    R = np.array([r0, r1, r2, t]).transpose()

    extrinsics_param.append(R)

    return extrinsics_param

    5.distortion.py

    这是用于求解畸变矫正系数的文件

    #!usr/bin/env/ python

    # _*_ coding:utf-8 _*_

    import numpy as np

    #返回畸变矫正系数k0,k1

    def get_distortion(intrinsic_param, extrinsic_param, pic_coor, real_coor):

    D = []

    d = []

    for i in range(len(pic_coor)):

    for j in range(len(pic_coor[i])):

    #转换为齐次坐标

    single_coor = np.array([(real_coor[i])[j, 0], (real_coor[i])[j, 1], 0, 1])

    #利用现有内参及外参求出估计图像坐标

    u = np.dot(np.dot(intrinsic_param, extrinsic_param[i]), single_coor)

    [u_estim, v_estim] = [u[0]/u[2], u[1]/u[2]]

    coor_norm = np.dot(extrinsic_param[i], single_coor)

    coor_norm /= coor_norm[-1]

    #r = np.linalg.norm((real_coor[i])[j])

    r = np.linalg.norm(coor_norm)

    D.append(np.array([(u_estim - intrinsic_param[0, 2]) * r ** 2, (u_estim - intrinsic_param[0, 2]) * r ** 4]))

    D.append(np.array([(v_estim - intrinsic_param[1, 2]) * r ** 2, (v_estim - intrinsic_param[1, 2]) * r ** 4]))

    #求出估计坐标与真实坐标的残差

    d.append(pic_coor[i][j, 0] - u_estim)

    d.append(pic_coor[i][j, 1] - v_estim)

    '''

               D.append(np.array([(pic_coor[i][j, 0] - intrinsic_param[0, 2]) * r ** 2, (pic_coor[i][j, 0] - intrinsic_param[0, 2]) * r ** 4]))

               D.append(np.array([(pic_coor[i][j, 1] - intrinsic_param[1, 2]) * r ** 2, (pic_coor[i][j, 1] - intrinsic_param[1, 2]) * r ** 4]))

               #求出估计坐标与真实坐标的残差

               d.append(u_estim - pic_coor[i][j, 0])

               d.append(v_estim - pic_coor[i][j, 1])

               '''

    D = np.array(D)

    temp = np.dot(np.linalg.inv(np.dot(D.T, D)), D.T)

    k = np.dot(temp, d)

    '''

       #也可利用SVD求解D * k = d中的k

       U, S, Vh=np.linalg.svd(D, full_matrices=False)

       temp_S = np.array([[S[0], 0],

                          [0, S[1]]])

       temp_res = np.dot(Vh.transpose(), np.linalg.inv(temp_S))

       temp_res_res = np.dot(temp_res, U.transpose())

       k = np.dot(temp_res_res, d)

       '''

    return k

    6.refine_all.py

    这是用于微调参数的文件

    #!usr/bin/env/ python

    # _*_ coding:utf-8 _*_

    import numpy as np

    import math

    from scipy import optimize as opt

    #微调所有参数

    def refinall_all_param(A, k, W, real_coor, pic_coor):

    #整合参数

    P_init = compose_paramter_vector(A, k, W)

    #复制一份真实坐标

    X_double = np.zeros((2 * len(real_coor) * len(real_coor[0]), 3))

    Y = np.zeros((2 * len(real_coor) * len(real_coor[0])))

    M = len(real_coor)

    N = len(real_coor[0])

    for i in range(M):

    for j in range(N):

    X_double[(i * N + j) * 2] = (real_coor[i])[j]

    X_double[(i * N + j) * 2 + 1] = (real_coor[i])[j]

    Y[(i * N + j) * 2] = (pic_coor[i])[j, 0]

    Y[(i * N + j) * 2 + 1] = (pic_coor[i])[j, 1]

    #微调所有参数

    P = opt.leastsq(value,

    P_init,

    args=(W, real_coor, pic_coor),

    Dfun=jacobian)[0]

    #raial_error表示利用标定后的参数计算得到的图像坐标与真实图像坐标点的平均像素距离

    error = value(P, W, real_coor, pic_coor)

    raial_error = [np.sqrt(error[2 * i]**2 + error[2 * i + 1]**2) for i in range(len(error) // 2)]

    print("total max error:\t", np.max(raial_error))

    #返回拆解后参数,分别为内参矩阵,畸变矫正系数,每幅图对应外参矩阵

    return decompose_paramter_vector(P)

    #把所有参数整合到一个数组内

    def compose_paramter_vector(A, k, W):

    alpha = np.array([A[0, 0], A[1, 1], A[0, 1], A[0, 2], A[1, 2], k[0], k[1]])

    P = alpha

    for i in range(len(W)):

    R, t = (W[i])[:, :3], (W[i])[:, 3]

    #旋转矩阵转换为一维向量形式

    zrou = to_rodrigues_vector(R)

    w = np.append(zrou, t)

    P = np.append(P, w)

    return P

    #分解参数集合,得到对应的内参,外参,畸变矫正系数

    def decompose_paramter_vector(P):

    [alpha, beta, gamma, uc, vc, k0, k1] = P[0:7]

    A = np.array([[alpha, gamma, uc],

    [0, beta, vc],

    [0, 0, 1]])

    k = np.array([k0, k1])

    W = []

    M = (len(P) - 7) // 6

    for i in range(M):

    m = 7 + 6 * i

    zrou = P[m:m+3]

    t = (P[m+3:m+6]).reshape(3, -1)

    #将旋转矩阵一维向量形式还原为矩阵形式

    R = to_rotation_matrix(zrou)

    #依次拼接每幅图的外参

    w = np.concatenate((R, t), axis=1)

    W.append(w)

    W = np.array(W)

    return A, k, W

    #返回从真实世界坐标映射的图像坐标

    def get_single_project_coor(A, W, k, coor):

    single_coor = np.array([coor[0], coor[1], coor[2], 1])

    #'''

    coor_norm = np.dot(W, single_coor)

    coor_norm /= coor_norm[-1]

    #r = np.linalg.norm(coor)

    r = np.linalg.norm(coor_norm)

    uv = np.dot(np.dot(A, W), single_coor)

    uv /= uv[-1]

    #畸变

    u0 = uv[0]

    v0 = uv[1]

    uc = A[0, 2]

    vc = A[1, 2]

    #u = (uc * r**2 * k[0] + uc * r**4 * k[1] - u0) / (r**2 * k[0] + r**4 * k[1] - 1)

    #v = (vc * r**2 * k[0] + vc * r**4 * k[1] - v0) / (r**2 * k[0] + r**4 * k[1] - 1)

    u = u0 + (u0 - uc) * r**2 * k[0] + (u0 - uc) * r**4 * k[1]

    v = v0 + (v0 - vc) * r**2 * k[0] + (v0 - vc) * r**4 * k[1]

    '''

       uv = np.dot(W, single_coor)

       uv /= uv[-1]

       # 透镜矫正

       x0 = uv[0]

       y0 = uv[1]

       r = np.linalg.norm(np.array([x0, y0]))

       k0 = 0

       k1 = 0

       x = x0 * (1 + r ** 2 * k0 + r ** 4 * k1)

       y = y0 * (1 + r ** 2 * k0 + r ** 4 * k1)

       #u = A[0, 0] * x + A[0, 2]

       #v = A[1, 1] * y + A[1, 2]

       [u, v, _] = np.dot(A, np.array([x, y, 1]))

       '''

    return np.array([u, v])

    #返回所有点的真实世界坐标映射到的图像坐标与真实图像坐标的残差

    def value(P, org_W, X, Y_real):

    M = (len(P) - 7) // 6

    N = len(X[0])

    A = np.array([

    [P[0], P[2], P[3]],

    [0, P[1], P[4]],

    [0, 0, 1]

    ])

    Y = np.array([])

    for i in range(M):

    m = 7 + 6 * i

    #取出当前图像对应的外参

    w = P[m:m + 6]

    # 不用旋转矩阵的变换是因为会有精度损失

    '''

           R = to_rotation_matrix(w[:3])

           t = w[3:].reshape(3, 1)

           W = np.concatenate((R, t), axis=1)

           '''

    W = org_W[i]

    #计算每幅图的坐标残差

    for j in range(N):

    Y = np.append(Y, get_single_project_coor(A, W, np.array([P[5], P[6]]), (X[i])[j]))

    error_Y  =  np.array(Y_real).reshape(-1) - Y

    return error_Y

    #计算对应jacobian矩阵

    def jacobian(P, WW, X, Y_real):

    M = (len(P) - 7) // 6

    N = len(X[0])

    K = len(P)

    A = np.array([

    [P[0], P[2], P[3]],

    [0, P[1], P[4]],

    [0, 0, 1]

    ])

    res = np.array([])

    for i in range(M):

    m = 7 + 6 * i

    w = P[m:m + 6]

    R = to_rotation_matrix(w[:3])

    t = w[3:].reshape(3, 1)

    W = np.concatenate((R, t), axis=1)

    for j in range(N):

    res = np.append(res, get_single_project_coor(A, W, np.array([P[5], P[6]]), (X[i])[j]))

    #求得x, y方向对P[k]的偏导

    J = np.zeros((K, 2 * M * N))

    for k in range(K):

    J[k] = np.gradient(res, P[k])

    return J.T

    #将旋转矩阵分解为一个向量并返回,Rodrigues旋转向量与矩阵的变换,最后计算坐标时并未用到,因为会有精度损失

    def to_rodrigues_vector(R):

    p = 0.5 * np.array([[R[2, 1] - R[1, 2]],

    [R[0, 2] - R[2, 0]],

    [R[1, 0] - R[0, 1]]])

    c = 0.5 * (np.trace(R) - 1)

    if np.linalg.norm(p) == 0:

    if c == 1:

    zrou = np.array([0, 0, 0])

    elif c == -1:

    R_plus = R + np.eye(3, dtype='float')

    norm_array = np.array([np.linalg.norm(R_plus[:, 0]),

    np.linalg.norm(R_plus[:, 1]),

    np.linalg.norm(R_plus[:, 2])])

    v = R_plus[:, np.where(norm_array == max(norm_array))]

    u = v / np.linalg.norm(v)

    if u[0] < 0 or (u[0] == 0 and u[1] < 0) or (u[0] == u[1] and u[0] == 0 and u[2] < 0):

    u = -u

    zrou = math.pi * u

    else:

    zrou = []

    else:

    u = p / np.linalg.norm(p)

    theata = math.atan2(np.linalg.norm(p), c)

    zrou = theata * u

    return zrou

    #把旋转矩阵的一维向量形式还原为旋转矩阵并返回

    def to_rotation_matrix(zrou):

    theta = np.linalg.norm(zrou)

    zrou_prime = zrou / theta

    W = np.array([[0, -zrou_prime[2], zrou_prime[1]],

    [zrou_prime[2], 0, -zrou_prime[0]],

    [-zrou_prime[1], zrou_prime[0], 0]])

    R = np.eye(3, dtype='float') + W * math.sin(theta) + np.dot(W, W) * (1 - math.cos(theta))

    return R

    7.结果

    拍摄的不同角度,不同高度的图像

    1daebcf2a611e25acaf337de3c1391d2.png

    运行结果:

    0f5c6465c233ea7cbe17d4d5b2e18fd2.png

    博主的手机是华为p9,后置摄像头是1200万像素。

    内部参数矩阵是为:

    [ 9.95397796e+02, -5.74043156e+00,  5.30659959e+02,
    0.00000000e+00,  1.04963119e+03,  6.55565437e+02,
    0.00000000e+00,  0.00000000e+00,  1.00000000e+00]

    因为代码是以一个方格为一个单位,没有考虑单位长度,所以要求真实的参数应该乘一个单位长度,博主采用的方格的尺寸是2.98cm的,自己拿excel画的,get了一个新技能~~

    转自:金凯博自动化

    ebe562181c7135e6a5f7348558b5748e.gif End ebe562181c7135e6a5f7348558b5748e.gif

    声明:部分内容来源于网络,仅供读者学术交流之目的。文章版权归原作者所有。如有不妥,请联系删除。

    2c754cc0df1fd601c08d16385f42cf21.png

    展开全文
  • 张正友标定数学原理推导 整体概述: 1.先求解单应性矩阵,单应性矩阵是从一个平面 到另一个平面的投影映射 2.通过单应性矩阵求解相机内参参数 3.求解外参参数 求解单应性矩阵 其实质对应空间坐标系旋转平移变换后...

    张正友标定数学原理推导

    整体概述:

    1.先求解单应性矩阵,单应性矩阵是从一个平面 到另一个平面的投影映射

    2.通过单应性矩阵求解相机内参参数

    3.求解外参参数

    4.几何解释

    求解单应性矩阵

    在这里插入图片描述其实质对应空间坐标系旋转平移变换后通过相机内参矩阵映射到像素坐标。

    在这里插入图片描述

    A称为相机的内参矩阵,内参矩阵取决于相机的内部参数。其中,ff 是通过欧拉积分为像距, dX,dYdX,dY分别表示X,YX,Y方向上的一个像素在相机感光板上的物理长度(即一个像素在感光板上是多少毫米),u0,v0u_0,v_0分别表示相机感光板中心在像素坐标系下的坐标,θ\theta表示感光板的横边和纵边之间的角度(90°90°表示无误差)。

    img

    preview

    我们的关注点不是定义在所有空间的坐标,只是定义在我们所观察的平面的坐标,我们可以选择物体平面为Z=0,

    在这里插入图片描述

    写为单应性矩阵形式

    在这里插入图片描述

    在opencv中提到单应性矩阵中只有8个自由参数,我们进行标准化使H33 = 1(通常是可行的,除了非常罕见的奇异情况H33=0)。单应性矩阵的缩放可以应用于第九个单应性矩阵的参数,但通常倾向于将整个单应性矩阵乘以比例因子来缩。

    我个人的理解就是把H33归一化为1,因为前面的比例因子不会对映射关系产生影响,可以将其提到比例因子中。

    将单应性矩阵拆分方程求解,将第三行乘上ui与第一行消去比例因子s,第二行与第一行操作相同得到

    在这里插入图片描述

    在这里插入图片描述

    对应的一组点有两个方程,所以棋盘格四个角点8个方程即可解的8个未知数。

    求解相机内参参数

    通过两个约束求解,r1和r2是单位正交向量,用h表示
    在这里插入图片描述
    令B为

    在这里插入图片描述

    令b为

    在这里插入图片描述

    B为对称矩阵,所以b的6维向量可以囊括所有B元素

    上面两个约束可以表示为通用形式

    在这里插入图片描述

    上面的一幅标定板图像取得的约束等式,假如有n幅图像,则
    Vb=0 Vb = 0
    n幅图即2n×6的矩阵,b有6个未知数用三幅图以上会得到6个以上方程即可求解。

    其中,V是一个2n×6的矩阵,bb是一个6维向量,所以

    • 当n≥3,可以得到bb的唯一解;
    • 当n=2,则可以假设扭曲参数γ=0γ=0作为额外的约束条件
    • 当n=1,则值能计算两个相机的内参数

    对于方程Vb=0可以使用SVD求得其最小二乘解。对VTV进行SVD分解,其最小特征值对应的特征向量就是Vb=0的最小二乘解,从而求得矩阵B。由于这里得到的B的估计值是在相差一个常量因子下得到的,所以有:
    B=λ(A)TA B=λ(A^-)^TA

    通过b也就知道了B,通过B可以提取内参参数

    在这里插入图片描述

    上述公式就是内参的解析解,内参参数获得后,外参矩阵便可以求解。

    求解外参矩阵

    利用上面H与A的关系,R矩阵的三向量为正交向量可得

    在这里插入图片描述

    且r1和r2是单位向量,所以
    在这里插入图片描述

    最大似然估计

    上面使用最小二乘法得到估计得到的解,并没有物理上的实际意义,。为了进一步增加标定结果的可靠性,可以使用最大似然估计(Maximum likelihood estimation)来优化上面估计得到的结果。

    假设同一相机从n个不同的角度的得到了n幅标定板的图像,每幅图像上有m个像点。Mij表示第ii幅图像上第j个像点对应的标定板上的三维点,则

    在这里插入图片描述

    一般图像噪声默认为高斯噪声,所以使用最大似然估计进行优化,角点mij的概率密度函数为
    f(mij)=12πe((^m)(K,Ri,ti,Mij))σ2 f(m_{ij})=\frac{1}{\sqrt{2\pi}}e^{\frac{-(\hat(m)(K, R_i, t_i, M_{ij}))}{\sigma^2}}
    构造似然函数

    L(A,Ri,ti,Mij)=i=1,j=1n,mf(mij)=12πei=1nj=1m(m^(K,Ri,ti,Mij)mij)2σ2L(A,R_i,t_i,M_{ij}) = \prod^{n,m}_{i=1,j=1}f(m_{ij})=\frac{1}{\sqrt{2\pi}}e^{\frac{-\sum^n_{i=1}\sum^m_{j=1}(\hat{m}(K,R_i,t_i,M_{ij})-m_{ij})^2}{\sigma^2}}
    为了能够让L取得最大值,需要最小化下面的值

    i=1nj=1mm(K,Ri,ti,Mij)mij2∑i=1n∑j=1m∥m^(K,Ri,ti,Mij)−mij∥2
    这是一个非线性优化问题,可以使用Levenberg-Marquardt的方法,利用上面得到的解作为初始值,迭代得到最优解。

    几何解释

    在张正友标定法原文中作者给出了几何解释,利用绝对圆锥曲线将两个旋转向量的约束关系联系起来。
    绝对圆锥曲线内容参考
    两个约束关系
    r1Tr2=0r_1^T\centerdot r_2 = 0
    r1Tr1=r2Tr2r_1^T\centerdot r_1 = r_2^T\centerdot r_2
    绝对圆锥曲线参考博客Absolute Conic
    在这里插入图片描述
    三维坐标点表示为齐次坐标为四维向量,平面方程表达式写为上式并用来表示相机坐标系
    在齐次坐标系中无穷远点收为同一个点,所以该平面与无穷远平面交于一条线,
    [r10][r20] \left[ \begin{matrix} r_1 \\ 0 \end{matrix} \right]与 \left[ \begin{matrix} r_2 \\ 0 \end{matrix} \right]
    是该相交直线上两个特殊的点,所以该直线上任何点可以用这两个点进行表示
    x=a[r10]+b[r20]=[ar1+br20]x_\infty = a\left[ \begin{matrix}r_1\\0 \end{matrix}\right]+b\left[ \begin{matrix}r_2\\0 \end{matrix}\right] = \left[\begin{matrix}ar_1+br_2\\0\end{matrix}\right]
    求该直线与绝对圆锥曲线的交点,xTx=0x_\infty^Tx_\infty = 0a2+b2=0a^2+b^2 = 0,求解可得
    x=a[r1±ir20]x_\infty = a\left[\begin{matrix}r_1\pm ir_2\\0\end{matrix}\right]
    这对复共轭点的意义在于它们对欧几里德变换是不变的。 它们在图像平面上的投影(由比例因子决定)为在这里插入图片描述
    该点在绝对圆锥曲线图上,描述为ATA1A^{-T}A^{-1},得到
    在这里插入图片描述
    这就要求上面的两个约束条件满足,这就是其几何意义。
    齐次坐标本来就是为了解决平移矩阵的加法问题,使其能够像旋转矩阵一样对坐标系进行乘法,本来的几何意义就比较抽象,对上文的解释也是自己的部分理解并不透彻,只能从齐次坐标中两平行线无穷远交汇于一点来扩充理解。

    展开全文
  • ...下面着重来讲一下著名的 张正友标定法 。 =&gt; 1. 预备知识 =&gt; 1.1. 从像素坐标系(u,v) 到 世界坐标系(Xw,Yw,Yw) 这里直接拿上篇博文的结果,中间省去了其它坐标系直接的关系,...
  • 张正友标定原理

    2019-06-01 16:44:59
    那就是 3张不同的标定平面的照片, 我们大多是通过改变摄像机与标定板间的相对位置来获得不同的标定照 3棋盘的排放 算法是基于2D模型的,如果棋盘摆放的不平整,肯定会造成很大的影像。 平整度的影像远远大于...
  • 前言”张正友标定”是指张正友教授1998年提出的单平面棋盘格的摄像机标定方法[1]。文中提出的方法介于传统标定法和自标定法之间,但克服了传统标定法需要的高精度标定物的缺点,而仅需使用一个打印出来的棋盘格就...
  • 击上方“新机器视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达前言”张正友标定”是指张正友教授1998年提出的单平面棋盘格的摄像机标定方法[1]。文中提出的方法介于传统标定法和自标定法之间,但克服了传统...
  • 张正友标定算法原理详解(一)

    万次阅读 2017-10-16 09:03:59
      ”张正友标定”是指张正友教授1998年提出的单平面棋盘格的摄像机标定方法[1]。文中提出的方法介于传统标定法和自标定法之间,但克服了传统标定法需要的高精度标定物的缺点,而仅需使用一个打印出来的棋盘格就...
  • 张正友标定原理及实验

    千次阅读 2019-09-18 13:25:17
    1.标定原理 将标定棋盘格放在不同位置和角度进行拍摄,采集的图片数不少于 3 张,一般选用15张左右。 1. 先通过图像处理获得棋盘格的角点,设其像素坐标为 ,设其世界坐标为X,Y,1,设 K 为相机内参矩阵,r...
  • 张正友标定法,又称为张氏标定法,是计算机视觉标定常用算法,常用于相机的内参标定中。
  • 张正友标定

    2012-04-11 15:01:58
    张正友标定的算法的原理详细介绍以及程序实例,
  • 张正友标定原理过程

    千次阅读 2017-12-25 00:28:22
    本文转载自:http://blog.csdn.net/u010128736/
  • 2.2 张正友标定原理 2.2.1 坐标系 2.2.2 内参矩阵计算 2.2.3 外参矩阵计算 2.2.4极大似然估计 2.2.5畸变矫正 2.3 张正友标定法算法步骤 三、用张正友标定法进行相机标定 3.1 实验数据说明 3.2 实验及分析...
  • 张正友标定算法原理详解(二)

    千次阅读 2017-10-16 08:52:18
    使用Opencv实现张正友法相机标定之前,有几个问题事先要确认一下,那就是相机为什么需要标定标定需要的输入和输出分别是哪些? 相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像...
  • 张正友标定处于什么水平,为啥提到相机标定,就不得不提他张博士的方法? 简单介绍一下张博士 他的方法优缺点,有没有替代方案? 他的方法输入输出是啥?利用工具包实现流程如何? 他的方法如何推导优化? 哪些因素...
  • 张正友标定法-完整学习笔记-从原理到实战 文章目录张正友标定法-完整学习笔记-从原理到实战(零)前言:1 为什么需要标定?2 相机标定的已知条件和待求解是什么?标定前的已知条件:待求信息:(一)概念介绍和成像...
  • 张正友平面标定原理

    千次阅读 2018-11-27 15:24:23
    摄像机标定成像原理 一、靶标平面与其图像平面之间的映射关系 在相机针孔成像模型下,假设点p 为靶标平面上的一点,点p在世界坐标系下的坐标为 M=(Xwi,Ywi,Zwi) ,其齐次坐标为 M’(Xwi,Ywi,Zwi,1) ,像点 p′在图像...
  • 张正友标定解释

    千次阅读 2014-03-12 16:57:35
    张正友标定算法解读  一直以来想写篇相机标定方面的东西,最近组会上也要讲标定方面东西,所以顺便写了。无论是OpenCV还是matlab标定箱,都是以张正友棋盘标定算法为核心实现的,这篇PAMI的文章>影响力极大,...
  • ...对于这四个坐标系中之间的关系还不太明白成像原理的同学需要先查一查学习一下。 这四个坐标系之间的转化关系为: 其中,为在世界坐标系下一点的物理坐标,为该点对应的在像素坐标系...
  • 相机标定(张正友标定算法)解读与实战一 相机标定(张正友标定算法)解读与实战二 前两篇文章偏重理论,介绍了针孔相机模型、镜头畸变模型和张氏标定的原理。今天主要讲解代码实现,虽然很多成熟视觉框架已经包含...
  • 张正友标定处于什么水平,为啥提到相机标定,就不得不提他张博士的方法?2 简单介绍张博士----张氏标定法发明人3【WHY:为什么要进行相机标定?】4【HOW:相机标定的原理】在这里我们先引入「棋盘」的概念:1.从世界...
  • 对于这四个坐标系中之间的关系还不太明白成像原理的同学需要先查一查学习一下。这四个坐标系之间的转化关系为:其中,为在世界坐标系下一点的物理坐标,为该点对应的在像素坐标系下的像素坐标,为尺度因子。我...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 181
精华内容 72
关键字:

张正友标定原理