OpenCV+C++面阵相机标定函数的使用
1. FindChessboardCorners
找到标定板内角点位置(角点是指黑白色相接的方块定点部分;内角点是不与标定板边缘接触的内部角点)
函数试图确定输入图像是否是棋盘模式,并确定角点的位置。如果所有角点都被检测到且它们都被以一定顺序排布,函数返回非零值,否则在函数不能发现所有角点或者记录它们地情况下,函数返回0。例如一个正常地棋盘图右8x8个方块和7x7个内角点,内角点是黑色方块相互连通的位置。这个函数检测到的坐标只是一个大约的值,如果要精确地确定它们的位置,可以使用函数FindCornerSubPix。
函数形式:findChessboardCorners( // 如果找到角点则返回true
InputArray image, // 输入的棋盘格图像(8UC1或8UC3)
Size patternSize, // 棋盘格内部角点的行、列数
OutputArray corners, // 输出的棋盘格角点
int flags = CALIB_CB_ADAPTIVE_THRESH
| CALIB_CB_NORMALIZE_IMAGE);
参数说明
Image:输入的棋盘图,必须是8位的灰度或者彩色图像。
pattern_size:棋盘图中每行和每列角点的个数。
Corners:检测到的角点
Flags:用于指定在检测棋盘格角点的过程中所应用的一种或多种过滤方法,可以使用下面的一种或多种,如果都是用则使用OR:
CV_CALIB_CB_ADAPTIVE_THRESH -使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。
CV_CALIB_CB_NORMALIZE_IMAGE -在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。
CV_CALIB_CB_FILTER_QUADS -使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块。
2. find4QuadCornerSubpix
对初步提取到的角点进一步提取亚像素信息,用于提高标定精度,获取内角点的精确位置。
函数形式:find4QuadCornerSubpix(InputArray img, InputOutputArray corners, Size region_size);
img:输入的Mat矩阵,最好是8位灰度图像,检测效率更高;
corners:初始的角点坐标向量,同时作为亚像素坐标位置的输出,所以需要是浮点型数据,一般用元素是Pointf2f/Point2d的向量来表示:vector<Point2f/Point2d> imagePointsBuf;
region_size:角点搜索窗口的尺寸;
3. drawChessboardCorners
在棋盘标定图上绘制找到的内角点(仅用于显示)
函数形式:drawChessboardCorners( InputOutputArray image, Size patternSize, InputArray corners, bool patternWasFound );
image:8位灰度或者彩色图像;
patternSize:每张标定棋盘上内角点的行列数;
corners:初始的角点坐标向量,同时作为亚像素坐标位置的输出,所以需要是浮点型数据,一般用元素是Pointf2f/Point2d的向量来表示:vector<Point2f/Point2d> iamgePointsBuf;
patternWasFound:标志位,用来指示定义的棋盘内角点是否被完整的探测到,true表示别完整的探测到,函数会用直线依次连接所有的内角点,作为一个整体,false表示有未被探测到的内角点,这时候函数会以(红色)圆圈标记处检测到的内角点;
patternWasFound=ture时,依次连接各个内角点
patternWasFound=false时,以(红色)圆圈标记处角点位置
4. calibrateCamera
函数形式:calibrateCamera( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
CV_OUT InputOutputArray cameraMatrix,
CV_OUT InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
int flags=0,
TermCriteria criteria = TermCriteria( TermCriteria::COUNT+TermCriteria::EPS, 30,DBL_EPSILON) );
objectPoints:为世界坐标系中的三维点。在使用时,应该输入一个三维坐标点的向量的向量,即vector<vector> object_points。需要依据棋盘上单个黑白矩阵的大小,计算出(初始化)每一个内角点的世界坐标。
imagePoints:为每一个内角点对应的图像坐标点。和objectPoints一样,应该输入vector<vector> image_points_seq形式的变量;
imageSize:为图像的像素尺寸大小,在计算相机的内参和畸变矩阵时需要使用到该参数;
cameraMatrix:为相机的内参矩阵。输入一个Mat cameraMatrix即可,如Mat cameraMatrix=Mat(3,3,CV_32FC1,Scalar::all(0));
distCoeffs:为畸变矩阵。输入一个Mat distCoeffs=Mat(1,5,CV_32FC1,Scalar::all(0))即可;
rvecs:为旋转向量;应该输入一个Mat类型的vector,即vectorrvecs;
tvecs:为位移向量,和rvecs一样,应该为vector tvecs;
flags:为标定时所采用的算法。有如下几个参数:
参数 | 效果 |
CV_CALIB_USE_INTRINSIC_GUESS | 使用该参数时,在cameraMatrix矩阵中应该有fx,fy,u0,v0的估计值。否则的话,将初始化(u0,v0)图像的中心点,使用最小二乘估算出fx,fy |
CV_CALIB_FIX_PRINCIPAL_POINT | 在进行优化时会固定光轴点。当CV_CALIB_USE_INTRINSIC_GUESS参数被设置,光轴点将保持在中心或者某个输入的值 |
CV_CALIB_FIX_ASPECT_RATIO | 固定fx/fy的比值,只将fy作为可变量,进行优化计算。当CV_CALIB_USE_INTRINSIC_GUESS没有被设置,fx和fy将会被忽略。只有fx/fy的比值在计算中会被用到 |
CV_CALIB_ZERO_TANGENT_DIST | 设定切向畸变参数(p1,p2)为零 |
CV_CALIB_FIX_K1,…,CV_CALIB_FIX_K6 | 对应的径向畸变在优化中保持不变。 |
CV_CALIB_RATIONAL_MODEL | 计算k4,k5,k6三个畸变参数。如果没有设置,则只计算其它5个畸变参数。 |
criteria:是最优迭代终止条件设定。
5. projectPoints
对标定结果进行评价的方法是通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到空间三维点在图像上新的投影点的坐标,计算投影坐标和亚像素角点坐标之间的偏差,偏差越小,标定结果越好。
函数形式:projectPoints( InputArray _opoints,
InputArray _rvec,
InputArray _tvec,
InputArray _cameraMatrix,
InputArray _distCoeffs,
OutputArray _ipoints,
OutputArray _jacobian,
double aspectRatio )
_points:物体点的坐标,为3xN或者Nx3的矩阵,这儿N是视图中的所有所有点的数目。
_rvec:旋转向量,1x3或者3x1。
_tvec:平移向量,1x3或者3x1。
_cameraMatrix:摄像机内参数矩阵A:
_distCoeffs:形变参数向量,4x1或者1x4,为[k1,k2,p1,p2]。如果是NULL,所有形变系数都设为0。
_ipoints:输出数组,存储图像点坐标。大小为2xN或者Nx2,这儿N是视图中的所有点的数目。
_jacobian:可选参数,Nx10矩阵,从上到下分为4个部分。
参数 | 说明 |
dpdrot | 关于旋转向量部分的图像上点的导数,Nx3矩阵。 |
dpdt | 关于平移向量部分的图像上点的导数,Nx3矩阵。 |
dpdf | 关于fx和fy的图像上点的导数,Nx2矩阵。 |
dpdc | 关于cx和cy的图像上点的导数,Nx2矩阵。 |
aspectRatio | 可选参数,关于形变系数的图像上点的导数,Nx4矩阵。 |