码迷,mamicode.com
首页 > 其他好文 > 详细

单目标定:从理论到OpenCV实践

时间:2018-08-26 18:15:37      阅读:314      评论:0      收藏:0      [点我收藏+]

标签:人性   两种   init   眼镜   ane   结果   src   示例   参考文献   

单目标定:从理论到OpenCV实践

一、针 孔摄像机模型    2

1.1 优缺点    2

1.2 孔摄像机模型图与公式    2

1.2.1 理想情况    2

1.2.2 实际情况    2

1.3 基本投影几何    3

1.3.1 投影变换的定义    3

1.3.2 摄像机内参数矩阵    3

二、透镜摄像机    5

2.1 优缺点    5

2.2 透镜畸变    5

2.2.1 畸变产生原因    5

2.2.2 径向畸变    5

2.2.3 切向畸变    6

2.2.4 其他畸变    7

三、旋转矩阵和平移向量    8

四、摄像机内外参数总结    8

五、摄像机标定    9

5.1 标定目的    9

5.2 单应性矩阵    9

5.3 棋盘    10

5.3.1 棋盘大小    10

5.3.2 角点数量与棋盘图片数量要求    11

5.4 OpenCV的求解理论方法    11

六、矫正    11

七、OpenCV1.1主要相关函数    12

参考文献    13

 

 

 

一、针 孔摄像机模型

1.1 优缺点

优点:简单好用。

缺点:真实的针孔由于不能为快速曝光收集足够的光线,因此不是得到图像的好方法。

1.2 针 孔摄像机模型图与公式

1.2.1 理想情况

描述:芯片是正方形,芯片中心在光轴上

技术分享图片

技术分享图片

f:摄像机焦距

Z:摄像机到物体的距离

X:物理物体长度

x:图像上的物体长度

1.2.2 实际情况

描述:芯片是矩形(长宽不同),芯片中心不在光轴上

技术分享图片

实际上,芯片的中心通常不在光轴上,因此引入新的参数cx和cy;

物理世界中的点Q(X,Y,Z),以某些偏移的方式投影为点(x_srceen,y_srceen):

技术分享图片

技术分享图片

1.3 基本投影几何

1.3.1 投影变换的定义

技术分享图片

1.3.2 摄像机内参数矩阵

【重要概念】

定义摄像机的参数(fx,fy,cx,cy)重新排列为3X3的矩阵,称为摄像机内参数矩阵

技术分享图片

技术分享图片

技术分享图片

 

二、透镜摄像机

2.1 优缺点

优点:利用透镜收集更多的光线;

缺点:背离了针 孔几何模型,而且引入透镜的畸变

2.2 透镜畸变

2.2.1 畸变产生原因

畸变产生原因:理论上讲是可能定义一种透镜而不引入任何畸变的,然后现实世界没有完美的透镜。这主要是制造上的原因,因为制作一个"球形"透镜比制作一个数学上理想的透镜更容易。而且从机械方面也很难把透镜和成像仪保持平行

两种主要的畸变:径向畸变切向畸变

2.2.2 径向畸变

【重要概念】

径向畸变:来自于透镜形状;

技术分享图片

技术分享图片

技术分享图片

技术分享图片

2.2.3 切向畸变

【重要概念】

切向畸变:来自于整个摄像机的组装过程

技术分享图片

技术分享图片

技术分享图片

技术分享图片

2.2.4 其他畸变

技术分享图片

 

三、旋转矩阵和平移向量

【重要概念】

技术分享图片

技术分享图片技术分享图片

技术分享图片

四、摄像机内外参数总结

摄像机参数:一般一共15个相关参数:

(1)外参数6个:旋转3个参数;平移3个参数;

(2)内参数4个:fx,fy,cx,cy;

求解上述10个参数的前提是先假设每次的畸变参数为0;

(3)5个畸变参数:k1,k2,k3,p1,p2;

其中(2)和(3)都为摄像机内参数,其中k3在普通镜头不使用,鱼眼镜头要使用。

 

五、摄像机标定

5.1 标定目的

矫正因使用透镜而给针 孔模型带来的主要偏差。

标定的过程既给出摄像机几何模型、也给出透镜的畸变模型,即求解上述的15个相关参数。

技术分享图片

5.2 单应性矩阵

【重要概念】

单应性矩阵主要解决外参数和内参数矩阵,且假设畸变参数为0。

在计算机视觉中,平面的单应性被定义为从一个平面到另一个平面的投影映射。

技术分享图片

技术分享图片

技术分享图片

技术分享图片

 

5.3 棋盘

5.3.1 棋盘大小

(1)标准

一个标准象棋棋盘,格子为7X7。

(2)非标准

技术分享图片

技术分享图片

(3)最小要求

最少需要4个点(3X3的棋盘点)

技术分享图片

(4)格子多的好处

技术分享图片

5.3.2 角点数量与棋盘图片数量要求

技术分享图片

技术分享图片

5.4 OpenCV求解标定的理论方法

5.4.1 摄像机标定的理论方法简介

(1)传统标定法

传统标定技术在定标的时候,需要在摄像机前放置一个特定的标定物,并认为地提供一组已知坐标的特征基元,摄像机通过寻找标定物上这些已知的特征基元来实现定标。它用到了很多射影几何方面的理论,是一种直接计算摄像机模型的方法。

(2)自标定法

自标定技术则更为灵活,它不需要特定的参照物来实现定标,是一种对环境具有很强适应性的定标技术,也是目前研究的热点。它利用环境的刚体性,通过对比多幅图像中的对应点来计算摄像机模型,但就目前的研究来看,其定标精度还无法与传统定标技术相比。

(3)张正友标定法

技术分享图片

5.4.1 OpenCV采用的理论方法

技术分享图片

5.4.2 张正友标定相关理论资料

(1)精简版8页《Flexible Camera Calibration by Viewing a Plane from Unknown Orientations》- Zhang1999

网址:http://www.vision.caltech.edu/bouguetj/calib_doc/papers/zhan99.pdf

(2)完整版22页《A Flexible New Technique for Camera Calibration.rar》- Zhang2000

网址:http://research.microsoft.com/~zhang/Papers/TR98-71.pdf

(3)张正友主页:

网址:http://research.microsoft.com/en-us/um/people/zhang/

(3)张正友主页中的相机标定页:

网址:http://research.microsoft.com/en-us/um/people/zhang/Calib/

5.4.3 Brown论文资料

网址:http://www.ifp.uni-stuttgart.de/lehre/vorlesungen/Aero/Brown71.pdf

六、矫正

利用棋盘标定的结果可进行畸变矫正。

 

七、OpenCV1.1主要相关函数

7.1 单目标定流程与对应主要函数

(1)查找棋盘角点:cvFindChessboardCorners;

(2)亚像素角点:cvFindCornerSubPix;

(3)显示角点结果:cvDrawChessboardCorners;

(4)单目标定:

[A]方式一:获取摄像机内外参数:cvCalibrateCamera2(内部包含

cvFindExtrinsicCameraParams2);

[B]方式二:根据摄像机内参数求取外参数:cvFindExtrinsicCameraParams2

注意:上述两种方式输出的是旋转向量和平移向量,如果需要转换为矩阵使用函数cvRodrigues2,该函数可以将向量和矩阵进行互转。

(5)图像畸变矫正:

[A]单目图像畸变矫正方式一(效率低):cvUndistort2;

[B]单目图像畸变矫正方式二(效率高):cvInitUndistortMap+cvRemap;

[C]双目点畸变矫正:cvUndistortPoints(注意:输入输出为点坐标,只能在双目标定中使用)。

(6)统计单目标定误差(计算3D点在图像上的投影坐标与棋盘点坐标的差值):

cvProjectPoints2+cvNorm。

注意:cvProjectPoints2输入的是旋转向量和平移向量。

7.2 主要相关函数详解

7.2.1 cvCalibrateCamera2详解

(1)函数原型

void cvCalibrateCamera2(const CvMat* object_points,

const CvMat* image_points,

const CvMat* point_counts,

CvSize image_size,

CvMat* intrinsic_matrix,//[output]

CvMat* distortion_coeffs,//[output]

CvMat* rotation_vectors=NULL,//[output]

CvMat* translation_vectors=NULL,//[output]

int flags=0

);

(2)参数注释(9个)

  • object_points

定标点的世界坐标,为3xN或者Nx3的矩阵,这里N是所有视图中点的总数。

http://www.360doc.com/content/14/0410/14/10724725_367762917.shtml

 

  • image_points

定标点的图像坐标,为2xN或者Nx2的矩阵,这里N是所有视图中点的总数。

  • point_counts

向量,指定不同视图里点的数目,1xM或者Mx1向量,M是视图数目。

  • image_size

图像大小,只用在初始化内参数时。

  • intrinsic_matrix

输出内参矩阵(A) 技术分享图片,如果指定

CV_CALIB_USE_INTRINSIC_GUESS和(或)CV_CALIB_FIX_ASPECT_RATIONfx fy cxcy部分或者全部必须被初始化。

  • distortion_coeffs

输出大小为4x1或者1x4的向量,里面为形变参数[k1, k2, p1, p2]

  • rotation_vectors

输出大小为3xM或者Mx3的矩阵,里面为旋转向量(旋转矩阵的紧凑表示方式,具体参考函数cvRodrigues2

  • translation_vectors

    输出大小为3xMMx3的矩阵,里面为平移向量。

  • flags【重点】

不同的标志,可以是0(默认),或者下面值的组合:

  • CV_CALIB_USE_INTRINSIC_GUESS(1):内参数矩阵包含fxfycxcy的初始值。否则,(cx, cy)被初始化到图像中心(这儿用到图像大小),焦距用最小平方差方式计算得到。注意,如果内部参数已知,没有必要使用这个函数,使用cvFindExtrinsicCameraParams2则可。
  • CV_CALIB_FIX_ASPECT_RATIO2):优化过程中认为fxfy中只有一个独立变量,保持比例fx/fy不变,fx/fy的值跟内参数矩阵初始化时的值一样。在这种情况下,(fx, fy)的实际初始值或者从输入内存矩阵中读取(当CV_CALIB_USE_INTRINSIC_GUESS被指定时),或者采用估计值(后者情况中fxfy可能被设置为任意值,只有比值被使用)。
  • CV_CALIB_FIX_PRINCIPAL_POINT(4):主点在全局优化过程中不变,一直在中心位置或者在其他指定的位置(当CV_CALIB_USE_INTRINSIC_GUESS设置的时候)。
  • CV_CALIB_ZERO_TANGENT_DIST(8):切向形变参数(p1, p2)被设置为0,其值在优化过程中保持为0
  • CV_CALIB_FIX_FOCAL_LENGTH(16):该标志在优化的时候,直接使用intrinsic_matrix传递过来的
  • CV_CALIB_FIX_K1(32):固定径向畸变k1。径向畸变参数可以通过组合这些标志设置为任意值。
  • CV_CALIB_FIX_K2(64):固定径向畸变k2。径向畸变参数可以通过组合这些标志设置为任意值。
  • CV_CALIB_FIX_K3(128):固定径向畸变k3。径向畸变参数可以通过组合这些标志设置为任意值,通常设置为0。

(3)单目定标函数cvCalibrateCamera2采用怎样的 flags 比较合适?(来自[文献4]

由于一般镜头只需要计算k1,k2,p1,p2四个参数,所以我们首先要设置 CV_CALIB_FIX_K3;其次,如果所用的摄像头不是高端的、切向畸变系数非常少的,则不要设置 CV_CALIB_ZERO_TANGENT_DIST,否则单目校正误差会很大;如果事先知道摄像头内参的大概数值,并且cvCalibrateCamera2函数的第五个参数intrinsic_matrix非空,则也可设置 CV_CALIB_USE_INTRINSIC_GUESS ,以输入的intrinsic_matrix为初始估计值来加快内参的计算;其它的 flag 一般都不需要设置,对单目定标的影响不大。

7.2.2 cvFindExtrinsicCameraParams2详解

(1)函数原型

void cvFindExtrinsicCameraParams2( const CvMat* object_points,

const CvMat* image_points,

const CvMat* intrinsic_matrix,

const CvMat* distortion_coeffs,

CvMat* rotation_vector,//[output]

CvMat* translation_vector//[output]

);

(2)参数注释(6个)

  • object_points

定标点的坐标,为3xN或者Nx3的矩阵,这里N是视图中的个数。

  • image_points

定标点在图像内的坐标,为2xN或者Nx2的矩阵,这里N是视图中的个数。

  • intrinsic_matrix

内参矩阵(A) 技术分享图片

  • distortion_coeffs

大小为4x1或者1x4的向量,里面为形变参数[k1,k2,p1,p2]。如果是NULL,所有的形变系数都为0

  • rotation_vector

输出大小为3x1或者1x3的矩阵,里面为旋转向量(旋转矩阵的紧凑表示方式,具体参考函数cvRodrigues2)。

  • translation_vector

大小为3x11x3的矩阵,里面为平移向量。

7.3 单目标定示例代码

http://blog.sina.com.cn/s/blog_73ef08a80100vi49.html

 

 

八、单目标定效果不好的原因分析

(1)问题来自[文献3]):OpenCV中用cvCalibrateCamera2 进行相机标定的精度差,标定结果不稳定

分析:可能原因有:

A.夹角太小会导致误差较大

可能是在标定的时候标定板所在平面与成像平面(image plane)之间的夹角太小,张正友论文里的仿真数据(有噪声的数据)说明当两者夹角太小误差会很大,从张正友的论文里给出的5幅图中(http://research.microsoft.com/~zhang/Calib/),其中标定平面与成像平面的夹角分别为:8.8947、11.2325、24.4875、10.8535、9.5829(单位:度)。而且张正友的论文中也提到两幅标定板之间的位置平行放置的话,相关相当于一幅,因此在实际标定中平行放置的情况最好避免,可能有时你无形之中就犯了这个错误。

B.标定时拍摄的图片太少

虽然张正友的论文里只用了5幅图片,但是建议用10来幅左右还是必要的,因为我们实际中可能标定板用A4的纸打印出来贴在一块板上的,标定板上的世界坐标精度就不是特别高,多拍摄几幅图像能减少这方面带来的误差,而且多个角度拍摄也可能解决了问题一:标定板和成像平面夹角小的问题。

有个例子是用20幅图片进行标定的:

http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/example.html

C.图像上角点提取的不准确

用cvFindChessboardCorners函数找角点不是很好,假如拍到的图像不是完整的棋盘格的时候肯定会有问题的,而且也不少人反应用这个函数提取不出角点,建议可以用其他工具 比如:

OpenCV and MatLab Camera Calibration Toolboxes Enhancement:

http://graphics.cs.msu.ru/en/research/calibration/

Camera Calibration Toolbox for Matlab(强烈推荐):

http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/example.html

 

(2)建议用其他标定方法(比如Tsai)或其他标定工具进行对比

强烈推荐 用这个matlab标定工具箱来进行标定,可以和OpenCV做对比,它也是基于张正友的平面标定方法的,做得非常人性化,有误差分析、标定结果三维重建、重投影计算角点等功能 。

Camera Calibration Toolbox for Matlab:

http://www.vision.caltech.edu/bouguetj/calib_doc/

 

(3)使用OpenCV进行摄像机定标虽然方便,但是定标结果往往不够准确和稳定,最好是使用 Matlab标定工具箱 来进行定标,再将定标结果取回来用于立体匹配和视差计算。

 

参考文献

  1. [书籍]学习OpenCV:第十一章 摄像机模型与标定。
  2. [书籍]基于OpenCV的计算机视觉技术实现

http://blog.csdn.net/zhazhiqiang/article/details/50593677

http://blog.csdn.net/zhazhiqiang/article/details/50593730

  1. [书籍]学习OpenCV:第十一章5。
  2. [书籍]学习OpenCV:第十一章。
  3. [书籍]学习OpenCV:第十一章2

 

 

单目标定:从理论到OpenCV实践

标签:人性   两种   init   眼镜   ane   结果   src   示例   参考文献   

原文地址:https://www.cnblogs.com/zhazhiqiang2018/p/9537663.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!