OpenCV2410
棋盘角点图像像素坐标步骤如下:①提取棋盘格图像内角点-粗角点坐标;③对粗角点坐标进行亚像素角点提取;④在棋盘标定图上绘制找到的亚像素内角点(仅显示内角点);①棋盘格内角点提取函数findChessboardCorners:bool findChessboardCorners( InputArray image,Size patternSize, //内角点行列数OutputArray corners, int flags=CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE);第一个参数image,是8位灰度、彩色图像;第二个参数patternSize,每个棋盘图上内角点的行列数,一般情况下,行列数不要相同,便于后续标定程序识别标定板的方向;第三个参数corners,用于存储检测到的内角点图像坐标位置,一般用元素是Point2f的向量来表示:vector
棋盘角点世界坐标系坐标:以棋盘格左上角为世界坐标系原点,建立世界坐标系,则棋盘角点世界坐标系下的坐标计算,如下:/*棋盘三维信息*/ Size square_size = Size(10,10); /* 每个棋盘格真实尺寸 */ vector
相机标定计算相机内外参数;double calibrateCamera( InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, Size imageSize,InputOutputArray cameraMatrix, InputOutputArray distCoeffs, OutputArrayOfArrays rvecs,OutputArrayOfArrays tvecs, int flags=0,TermCriteria criteria= TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30,DBL_EPSILON) ); 第一个参数objectPoints,输入一个三维坐标点的向量的向量,即vector
相机标定结果评价projectPoints:以获取的相机内外参数为输入,计算空间三维点在图像上的重投影点坐标和亚像素角点坐标之间的偏差;偏差越小,标定结果越好;①对空间三维坐标点进行反向投影的函数是projectPoints; void projectPoints( InputArray objectPoints, InputArray rvec,InputArray tvec, InputArray cameraMatrix,InputArray distCoeffs, OutputArray imagePoints, //投影点 OutputArray jacobian=noArray(), double aspectRatio=0 ); 第一个参数objectPoints,为相机坐标系中的三维点坐标;第二个参数rvec为旋转向量,每一张图像都有自己的旋转向量;第三个参数tvec为平移向量,每一张图像都有自己的平移向量;第四个参数cameraMatrix为相机的内参数矩阵;第五个参数distCoeffs为相机的畸变矩阵;第六个参数imagePoints为每一个内角点对应的图像上的坐标点;第七个参数jacobian是雅可比行列式;第八个参数aspectRatio是跟相机传感器的感光单元有关的可选参数,如果设置为非0,则函数默认感光单元的dx/dy是固定的,会依此对雅可比矩阵进行调整; ②误差计算:以opencv里的norm把这里的两个通道分别分开来计算的(X1-X2)^2的值,然后统一求和,最后进行根号;double norm(InputArray src1, InputArray src2, int normType=NORM_L2,InputArray mask=noArray());以图片的亚像素角点坐标和根据标定结果把空间三维坐标点映射到图像坐标点的对比:
图像矫正:利用标定结果对图像进行矫正方法一:initUndistortRectifyMap和remap相结合实现。initUndistortRectifyMap计算畸变映射,remap把求得的畸变映射应用到图像上。void initUndistortRectifyMap(InputArray cameraMatrix, InputArray distCoeffs, InputArray R,InputArray newCameraMatrix, Size size,int m1type,OutputArray map1,OutputArray map2 ); 第一个参数cameraMatrix为之前求得的相机的内参矩阵;第二个参数distCoeffs为之前求得的相机畸变矩阵;第三个参数R,旋转矩阵;第四个参数newCameraMatrix,输入的校正后的3X3摄像机矩阵;第五个参数size,摄像机采集的无失真的图像尺寸;第六个参数m1type,定义map1的数据类型,可以是CV_32FC1或者CV_16SC2;第七个参数map1和第八个参数map2,输出的X/Y坐标重映射参数;void remap( InputArray src,OutputArray dst, InputArray map1,InputArray map2, int interpolation,int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar()); 第一个参数src,输入参数,代表畸变的原始图像;第二个参数dst,矫正后的输出图像,跟输入图像具有相同的类型和大小;第三个参数map1和第四个参数map2,X坐标和Y坐标的映射;第五个参数interpolation,定义图像的插值方式;第六个参数borderMode,定义边界填充方式; 方法二:undistort函数实现void undistort( InputArray src,OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, InputArray newCameraMatrix=noArray() ); 第一个参数src,输入参数,代表畸变的原始图像;第二个参数dst,矫正后的输出图像,跟输入图像具有相同的类型和大小;第三个参数cameraMatrix为之前求得的相机的内参矩阵;第四个参数distCoeffs为之前求得的相机畸变矩阵;第五个参数newCameraMatrix,默认跟cameraMatrix保持一致; 方法一相比方法二执行效率更高一些,推荐使用。矫正结果比较:
OpenCV标定程序完整版请私信!!!