(单目)相机标定算法:张正友的算法
paper:http://research.microsoft.com/~zhang/Papers/TR98-71.pdf
主页:http://research.microsoft.com/en-us/um/people/zhang/Calib/
一些帖子对摄像头畸变原理的总结:
http://blog.sina.com.cn/s/blog_5e3213f30101g2t5.html
《学习OpenCV》一书中对摄像头标定有详尽说明:第11章——“摄像机标定”一节 P422
VC下实现相机标定,主要分两步:matlab中计算标定参数、利用opencv的接口对输入图像进行标定
matlab工具箱:Camera Calibration Toolbox for Matlab,主页:http://www.vision.caltech.edu/bouguetj/calib_doc/index.html#examples
主要看以下内容:
1、工具箱的详细使用方法:http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/example.html
2、标定参数说明:http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/parameters.html
这一步关键是采集一系列不同角度拍摄的棋盘格图像。实践发现,棋盘格的制作是有讲究的,格子尽量面积小,保证有足够多的正方形,也就有足够多的角点,让整个视野区域都布满角点,计算校正矩阵的时候,从中心到远离中心的每个位置都能够考虑进去。如果格子太大,校正的精度就会下降,会使校正结果出现误差。这是因为,每个角点之间的距离越大,这段距离之间的可能发生畸变的点越多,但却没有体现在棋盘格中(作为角点标出),因此标定算法计算校正矩阵时就会漏掉越多畸变位置,其校正精确度将越差。
opencv的标定相关函数如下:(基于opencv 3.0)
void initUndistortRectifyMap(InputArray cameraMatrix, InputArray distCoeffs, InputArray R, InputArray newCameraMatrix, Size size, int m1type, OutputArray map1, OutputArray map2)
用于获得标定时的变换矩阵,参数说明:
cameraMatrix,内参数矩阵,A = [ fx, 0, cx ; 0, fy, cy; 0, 0, 1],大小3*3,其中与matlab工具箱计算结果的对应关系为:fx、fy对应fc的两项,cx、cy对应cc的两项
distCoeffs,外参数(失真参数)矩阵, distortion coefficients,包含4, 5, or 8 元素的一维矩阵,对应matlab计算结果的kc
R,矫正矩阵,用于双目摄像头,这里设为空矩阵即可
newCameraMatrix,同样是双目时用到,这里输入cameraMatrix即可
size,输入图像尺寸
m1type,map1的类型,设为CV_32F
map1、map2,X、Y方向的变换矩阵
void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
按两个变换矩阵对输入图像进行变换
interpolation为插值算法,设为cv::INTER_NEAREST即可
void undistort(InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, InputArray newCameraMatrix=noArray() )
一个整合版函数,包括以上两个函数
效果:
原始
校正后
注意:如果相机的畸变比较严重时,校正后的图像中,目标物可能会超出图像区域,此时如果想让校正图像包含目标物整体,则需要在校正之前扩充图像的大小