最近,一直和相机标定纠缠不行,属于典型的看了就忘,所以决定把学到的东西全都记录下来,祈祷自己能够掌握~
首先我们有相机的坐标系模型(如下图,引自《Learning OpenCV》):

摄像机标定就是为了确定摄像机的内外参数,内参数构成了一个3X3的矩阵M,我们有q=MQ,即内参数矩阵可以实现物理点Q到投影平面的投影变换。外参数包括畸变系数和变换矩阵,变换矩阵是和图像相关的。OpenCV对相机的标定采用棋盘标定法,标定过程主要使用的函数是
1 void cvCalibrateCamera2(
2 CvMat* object_points,
3 CvMat* image_points,
4 int* piont_counts,
5 CvSize image_size,
6 CvMat* intrinsic_matrix,
7 CvMat* distortion_coeffs,
8 CvMat* rotation_vectors = NULL,
9 CvMat* translation_vectors = NULL,
10 int flags = 0
11 );
这个函数,用起来其实很麻烦,object_points需要自己构造,其存储的是在世界坐标系下特征点的三维坐标,为了方便起见,通常都以棋盘所在平面为Z平面,构造时候对坐标值的设置就决定了其它变量所采用的度量单位。image_points是cvFindChessBoardCorners()得到的棋盘特征点,注意是所有图像的特征点的集合。point_counts则记录了每幅图像的特征点数,image_size是标定图像的大小。intrinsic_matrix、distrotion_coeffs则是输出的内外参数,rotation_vectros、translation_vectors则是从摄像机坐标系到我们之前所定义的棋盘坐标系的变换矩阵,通常并不需要求出,最后一个flags变量,非常有学问,需要特殊说明一下。
由于对内外参数的标定实际上是个最优化的过程,因此设置初始值对结果的影响就很大。而对于flag的设置主要就是围绕初始值的估计和一些假设进行的。在此不一一列举了,一般使用的是CV_CALIB_FIX_ASPECT_RATIO,这时需要将fx、fy初始化。
那么标定好一个摄像机之后有什么用呢?首先第一个用处,就是我们给定一个物理三维坐标,就可以进行投影,得到其在图像中的图像坐标了。这里需要用的函数是:
1 void cvProjectPoints2(
2 const CvMat* object_points,
3 const CvMat* rotation_vector,
4 const CvMat* translation_vector,
5 const CvMat* intrinsic_matrix,
6 const CvMat* distortion_coeffs,
7 CvMat* image_points,
8 CvMat* dpdrot=NULL,
9 CvMat* dpdt=NULL,
10 CvMat* dpdf=NULL,
11 CvMat* dpdc=NULL,
12 CvMat* dpddist=NULL
13 );
14
具体参数的就不一一说明了,很多都和标定一致,object_points可以是任意的输入点了。需要注意的是object_points应该和image_points维数一致。
这里的标定是一个相机的标定,而在这次毕设的工作中需要进行一对相机的标定也即立体定标,关于立体标定以及OpenCV一些实现的问题下次coding完了再总结吧~~~