首先,先看看OpenCV提供的标定接口:
opencv函数:
double calibrateCamera(
InputArrayOfArrays objectPoints, //输入:目标点位 的集合的集合
InputArrayOfArrays imagePoints, //输入:图像点位 的集合的集合
Size imageSize, //输入:图像尺寸
InputOutputArray cameraMatrix, //输出:相机内参矩阵(fx,fy,cx,cy)
InputOutputArray distCoeffs, //输出:畸变矫正多项式(k1,k2,p1,p2,k3...)
OutputArrayOfArrays rvecs, //输出:旋转矩阵 的集合
OutputArrayOfArrays tvecs, //输出:平移矩阵 的集合
int flags = 0, //输入:对标定过程方法进行更精细的控制
TermCriteria criteria = //输入:迭代参数
TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON));
计算流程大概分为以下两步:
1.通过大量的对应点: 物体的目标点(现实世界)和 物体投影点(图片中)计算出内参矩阵和畸变矫正多项式
2.再以得到的内参矩阵和畸变矫正多项式和输入数据,进行迭代修正。得到更好的输出结果。
以下是参数详细解析:
参数一:InputArrayOfArrays:objectPoints,输入目标点的位置 的集合的集合。
其每个点位代表着物体的三维坐标。
参数类型可为 :vector
参数二:InputArrayOfArrays:imagePoints,图像点位 的集合的集合
其每个点,是objectPoints中的点投影在图片中成像的对应点。
参数类型可为 :vector
PS:objectPoints和imagePoints数组大小和每个数组的数组大小应该一致,且每个点一一对应。
参数三:Size:imageSize 图像尺寸
参数四:InputOutputArray: cameraMatrix 相机内参矩阵
如图:其中fx,fy分别为x/y方向的焦距,cx,cy为光轴对于投影平面坐标中心的偏移量
该参数固定以3x3双精度类Mat类型返回。
可配合cv::getOptimalNewCameraMatrix()函数使用,解决矫正后边缘像素为空问题
Ps1:当flags设置有固定中心(即:cv::CALIB_FIX_PRINCIPAL_POINT)时,固定光轴主点为图像中心。
Ps2:当flags设置有固定中心(即:cv::CALIB_FIX_PRINCIPAL_POINT | cv::CALIB_USE_INTRINSIC_GUESS)时,
直接使用传入光轴偏移量cx,cy计算。
Ps3:当flags设置有固定焦距(即:cv::CALIB_FIX_FOCAL_LENGTH)时,直接使用传入焦距fx,fy计算。
参数五:InputOutputArray distCoeffs 畸变矫正多项式(k1,k2,p1,p2,k3....k6)
其中k1,k2.....k6 为泰勒级数展开的系数 用于矫正透镜造成的径向畸变
p1,p2 用于矫正透镜切向畸变造成的畸变(可参考铅锤模型)
该参数固定以双精度类Mat类型返回。
默认返回k1,k2,p1,p2,k3。需要k4,k5,k6时可设置flags为:CV_CALIB_RATIONAL_MODEL(一般只用于鱼眼镜头)
ps::可通过设置cv::CALIB_FIX_Kn来固定对应的Kn在迭代修正过程中保持不变。
参数六:OutputArrayOfArrays rvecs 旋转矩阵 的集合
类型可为Vector
参数七:OutputArrayOfArrays tvecs 平移矩阵 的集合
类型可为Vector
参数七:int flags 对标定过程方法进行更精细的控制
除上述flags外还有:
CALIB_FIX_ASPECT_RATIO:修正过程中 fx,fy的比值不变。(若CV_CALIB_USE_INTRINSIC_GUESS被设置,则只更改fy值)
CALIB_ZERO_TANGENT_DIST:设置切向畸变为0;
参数八:TermCriteria criteria 迭代参数
TermCriteria 类有三个成员 (int type,int maxCount,double epsilon)
分别是 迭代类型(翻译为迭代终止条件更符合),最大迭代次数,期望精度
迭代类型有:COUNT, EPS or COUNT + EPS (满足次数,满足精度,或两者之一)
返回值:重投影的均方根误差