相机标定

来源:互联网 发布:win7下怎么安装ubuntu 编辑:程序博客网 时间:2024/04/28 17:09

1. 概念

相机参数分为内参数和外参数:

  1. 内参数 对于给点的相机和透镜系统,内参数不变。
  2. 外参数 旋转和平移分量通常被称为外参数,不同的视角中外产生不同。

内参数也分成几个部份:

  1. 焦距 f
  2. 成像原点u0,v0
  3. 五个畸变参数

畸变参数也分成两部份:

  1. 径向畸变 由于光学透镜的特性,使得成像存在径向畸变(k1,k2,k3)。
  2. 切向畸变 由于装配方面的误差,传感器和光学镜头之间并非完全平行,因此成像存在切向畸变,可有两个参数p1,p2确定。

2. 径向畸变:

如下图所示:

这里写图片描述

校正:

这里写图片描述

其中(x,y)为校正前的坐标点;(xcorrected, ycorrected)为校正后的坐标点。

3. 切向畸变

如下图所示:

这里写图片描述

校正:

这里写图片描述

其中(x,y)为校正前的坐标点;(xcorrected, ycorrected)为校正后的坐标点。

4. 相机模型

空间中任何一点P在CCD上的成像位置可有用针孔相机模型表示,如下图所示:

![Alt text](http://www.muzichao.com/wp-content/uploads/2014/11/pin-hole camera.png)

  • 空间中一点P(X,Y,Z)
  • 主点(u0,v0)
  • 焦距 f
  • 像素宽度px
  • 像素高度py

则,用像素表示的焦距为:(fx = f/px, fy = f/py),由此可以得到完整的投影等式:

这里写图片描述

针孔相机的矩阵形式可以表示为:

这里写图片描述

用三维向量来表示2D点,用思维向量来表示3D点,额外的一个坐标是任意的缩放因子。

其中,上式的第一个矩阵为相机的内参矩阵,第二个矩阵[R|T]为投影矩阵,包含旋转分量R和平移分量T(通常被称为相机的外参数)。

如果没有旋转,则R为单位矩阵;如果没有平移,则T为0向量,则上式公式可以改写为:

这里写图片描述

5. 综述

  1. 内参矩阵与视场无关,一次测量后可以反复使用
  2. 旋转平移矩阵[R|T]与视场角有关,称为外参数,相机固定,则外惨固定
  3. 参数

    1. P(X,Y,Z)表示世界坐标系中的一个3D点
    2. (u,v)表示投影点在CCD上的像素坐标
    3. A表示相机矩阵
    4. (u0,v0)表示CCD上主点(投影中心)
    5. fx,fy为用像素表示的焦距
    6. k1,k2,k3,k4,k5,k6是径向畸变参数
    7. p1,p2是切向畸变参数
  4. 计算公式(未引入畸变)

这里写图片描述

  1. 计算公式(引入畸变)

这里写图片描述

6. 相机标定流程

  1. 产生棋盘文件列表 一般用多副不同位姿的标定图像(10-20副)进行标定,图像越多,精度越高。
  2. 输入棋盘角点大小 如下图所示6*5的棋盘,角点大小为(5,4),即不包含边缘
  3. 分别打开图像并提取角点
  4. 相机标定,得到相机矩阵,畸变参数
  5. 根据相机标定得出的相机参数进行图像去畸变

这里写图片描述

7. 提取角点流程

棋盘角点提取中有两种角点,imageCorners 和 objectCorners,其中imageCorners对应图像角点(x,y);objectCorners 对应世界坐标角点(i,j,0),每一个棋盘图像都有一个 imageCorners 和 objectCorners。

提取角点流程:

  1. 初始化世界棋盘点坐标 objectCorners。 如下图所示:P点的 objectCorners 为(0, 0, 0);Q点的objectCorners 为(3, 4, 0)
  2. 循环所有图像
    1. 读入图像
    2. 得到棋盘角点(imageCorners),使用 findChessboardCorners 函数。
    3. 利用迭代法提高角点坐标精度,使用 cornerSubPix 函数。
    4. 如果全部角点找到,则存储世界坐标角点 objectCorners 和找到的图像角点 imageCorners。
    5. 绘制角点

这里写图片描述

8. findChessboardCorners函数

作用:查找棋盘图像内点的位置

bool findChessboardCorners(InputArray image,                            Size patternSize,                            OutputArray corners,                           int flags=CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE)
  • image:输入的棋盘图像,必须是8位的灰度或者彩色图像
  • patternSize:棋盘中每行每列的角点个数
  • corners:检测到的角点
  • flags:各种操作标准

9. cornerSubPix函数

作用:通过迭代获取更精确的角点位置

void cornerSubPix(InputArray image,                   InputOutputArray corners,                   Size winSize,                   Size zeroZone,                   TermCriteria criteria)
  • image:输入图像,,必须是8位的灰度或者彩色图像
  • corners:输入角点的初始化坐标,也存储精确的输出角点坐标
  • winSize:搜索窗口的一半尺度,如winSize=(5,5),则使用(2x5+1, 2x5+1)=(11,11)的搜索窗
  • zeroZone:死区的一半尺寸,死区为不对搜索区做求和运算的区域,当值为(-1,-1)时,表示没有死区

10. calibrateCamera函数

作用:相机标定,输出相机矩阵,畸变系数,旋转矩阵,平移矩阵。

double calibrateCamera(InputArrayOfArrays objectPoints,                        InputArrayOfArrays imagePoints,                        Size imageSize,                        InputOutputArray cameraMatrix,                        InputOutputArray distCoeffs,                        OutputArrayOfArrays rvecs,                        OutputArrayOfArrays tvecs,                        int flags=0,                        TermCriteria criteria=TermCriteria( TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) )
  • objectPoints:世界坐标点,3D点
  • imagePoints:图像上角点坐标
  • imageSize:图像大小
  • cameraMatrix:相机矩阵A
  • distCoeffs:畸变系数(k1,k2,p1,p2[,k3[,k4,k5,k6])
  • rvecs:旋转矩阵R
  • tvecs:平移向量T
  • flags:附加选项

11. initUndistortRectifyMap函数

作用:计算去畸变和校正的映射坐标

void initUndistortRectifyMap(InputArray cameraMatrix,                              InputArray distCoeffs,                              InputArray R,                             InputArray newCameraMatrix,                              Size size,                              int m1type,                              OutputArray map1,                              OutputArray map2)
  • cameraMatrix:相机矩阵
  • distCoeffs:畸变系数
  • R:光学校正矩阵
  • newCameraMatrix:新的相机矩阵A’
  • size:去畸变图像的大小
  • m1type输出畸变图像的类型,CV_32FC1或CV_16SC2
  • map1:第一个输出映射(x,y)点或仅x
  • map2:第二个输出映射空或者仅y

12. remap函数

作用:根据映射关系对一个图像进行几何变换

void remap(InputArray src,            OutputArray dst,            InputArray map1,            InputArray map2,            int interpolation,            int borderMode=BORDER_CONSTANT,            const Scalar& borderValue=Scalar())
  • src:原始图像
  • dst:输出图像
  • map1:第一个输出映射(x,y)点或仅x
  • map2:第二个输出映射空或者仅y

dst(x, y) = src(mapx(x,y), mapy(x,y))

13. 参考文献

  1. 求解焦距和成像原点(张正友 :A Flexible New Technique for Camera Calibration)
  2. 求解畸变参数(Brown :Close-Range Camera Calibration)
  3. OpenCV 2 计算机视觉编程手册
  4. opencv tutorials(2.4.9)
  5. opencv 2 refman(2.4.9)
  6. CSDN

14. 代码

GitHub

1 0