当前位置:网站首页 > 创业 > 正文

OpenCV:相机标定函数和程序

0 张子豪 张子豪 2025-10-15 02:08 1

绪:

OpenCV相机标心猿意马采用张正友标心猿意马法,

以棋盘格为东西,

以棋盘角点图像像素坐标和棋盘角点宿世界坐标系坐标为输入,

输出相机的内参、外参。

本经验本家儿要介绍:

(1)棋盘角点图像像素坐标系坐标;

(2)棋盘角点宿世界坐标系坐标;

(3)相机标心猿意马;

(4)相机标心猿意马成果评价;

(5)图像畸变矫正;

(6)标心猿意马法式;

东西/原料

  • OpenCV2410

方式/步调

  1. 1

    棋盘角点图像像素坐标

    步调如下:

    ①提取棋盘格图像内角点-粗角点坐标;

    ③对粗角点坐标进行亚像素角点提取;

    ④在棋盘标心猿意马图上绘制找到的亚像素内角点(仅显示内角点);

    ①棋盘格内角点提取函数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<Point2f> image_points_buf;

    第四个参数flags:用于界说棋盘图上内角点查找的分歧处置体例,有默认值。

    ②提取亚像素角点信息:

    为了提高标心猿意马精度,在提取的角点信息长进一步提取亚像素信息,降低相机标心猿意马误差;

    两种方式;一种方式cornerSubPix;另一种方式find4QuadCornerSubpix函数;

    void cornerSubPix( InputArray image,

    InputOutputArray corners, 

                    Size winSize,

    Size zeroZone, 

                    TermCriteria criteria ); 

    第一个参数image,是8位灰度图像;

    第二个参数corners,输入初始的角点坐标标的目的量,输出亚像素坐标位置,浮点型数据,一般用元素是Pointf2f/Point2d的标的目的量来暗示:vector<Point2f/Point2d> imagePointsBuf;

    第三个参数winSize,巨细为搜刮窗口的一半;

    第四个参数zeroZone,死区的一半尺寸,死区为不合错误搜刮区的中心位置做乞降运算的区域。它是用来避免自相关矩阵呈现某些可能的奇异性。当值为(-1,-1)时暗示没有死区;

    第五个参数criteria,迭代过程的终止前提,可觉得迭代次数和角点精度两者的组合;

    bool find4QuadCornerSubpix(InputArray img,

    InputOutputArray corners,

    Size region_size); 

    第一个参数img,是8位灰度图像;

    第二个参数corners,输入初始的角点坐标标的目的量,输出亚像素坐标位置,浮点型数据,一般用元素是Pointf2f/Point2d的标的目的量来暗示:vector<Point2f/Point2d> imagePointsBuf;

    第三个参数region_size,角点搜刮窗口的尺寸;

    对比cornerSubPix和find4QuadCornerSubpix:

    在标心猿意马图上别离运行cornerSubPix和find4QuadCornerSubpix寻找亚像素角点,

    两者定位到的亚像素角点坐标别离为:

    固然两者有必然差距,但误差根基都节制在0.5个像素之内。

    ③在图像上绘制内角点drawChessboardCorners用于绘制被当作功标心猿意马的角点

    void drawChessboardCorners( InputOutputArray image,

    Size patternSize, 

                             InputArray corners,//亚像素角点

    bool patternWasFound ); 

    第一个参数image,8位灰度或者彩色图像;

    第二个参数patternSize,每张标心猿意马棋盘上内角点的行列数;

    第三个参数corners,输入亚像素坐标位置,浮点型数据,一般用元素是Pointf2f/Point2d的标的目的量来暗示:vector<Point2f/Point2d> iamgePointsBuf;

    第四个参数patternWasFound,标记位,用来指示界说的棋盘内角点是否被完整的探测到,true暗示别完整的探测到,函数会用直线依次毗连所有的内角点,作为一个整体,false暗示有未被探测到的内角点,这时辰函数会以圆圈标识表记标帜处检测到的内角点;

    patternWasFound设置为true和false时内角点的绘制结果:ture时,依次毗连各个内角点;false圆圈暗示;

  2. 2

    棋盘角点宿世界坐标系坐标:

    以棋盘格左上角为宿世界坐标系原点,成立宿世界坐标系,

    则棋盘角点宿世界坐标系下的坐标计较,如下:

    /*棋盘三维信息*/ 

    Size square_size = Size(10,10);  /* 每个棋盘格真实尺寸 */ 

    vector<vector<Point3f>> object_points; /* 标心猿意马板上角点的三维坐标 */ 

    /* 初始化标心猿意马板上角点的三维坐标 */ 

    int i,j,t; 

    for (t=0;t<image_count;t++)  

       vector<Point3f> tempPointSet; 

       for (i=0;i<board_size.height;i++)  

       { 

          for (j=0;j<board_size.width;j++)  

          { 

             Point3f realPoint;   /* 假设标心猿意马板放活着界坐标系中z=0的平面上 */ 

             realPoint.x = i*square_size.width;  //hang

             realPoint.y = j*square_size.height; //lie

             realPoint.z = 0; 

             tempPointSet.push_back(realPoint); 

           } 

        } 

        object_points.push_back(tempPointSet); 

  3. 3

    相机标心猿意马计较相机表里参数;

    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<vector<Point3f>> object_points。依据棋盘上单个口角矩阵的巨细,计较出每一个内角点的宿世界坐标。

    第二个参数imagePoints,输入每一个内角点对应的图像坐标点,vector<vector<Point2f>> 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,即vector<Mat>rvecs;

    第七个参数tvecs为位移标的目的量,和rvecs一样,应该为vector<Mat> 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是最优迭代终止前提设心猿意马。

    在利用该函数进行标心猿意马运算之前,需要对棋盘上每一个内角点的空间坐标系的位置坐标进行初始化,标心猿意马的成果是生当作相机的内参矩阵cameraMatrix、相机的5个畸变系数distCoeffs,别的每张图像城市生当作属于本身的平移标的目的量和扭转标的目的量。

  4. 4

    相机标心猿意马成果评价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());

    以图片的亚像素角点坐标和按照标心猿意马成果把空间三维坐标点映射到图像坐标点的对比:

  5. 5

    图像矫正:操纵标心猿意马成果对图像进行矫正

    方式一: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标心猿意马法式完整版请私信!!!

来源:百闻(微信/QQ号:9397569),转载请保留出处和链接!


本文链接:https://www.ibaiwen.com/web/282815.html

张子豪

张子豪

TA很懒,啥都没写...

@百闻娱乐 本站部分内容转自互联网,若有侵权等问题请及时与本站联系,我们将在第一时间删除处理。 | 粤ICP备2024343649号 | (地图