5_相机标定_3_calibrateCamera()例子

上次介绍了calibrateCamera()接口参数,这次实际调用。

5942745cf7d6a6cb1de1e1864d86a0ea.png

程序中所用标准标定板。

一、图片预处理

使用的图片原像素是3072*2048,即600万像素,处理起来不快;改成了560*420,即20万像素。调用opencv接口如下:

// 最小分辨率(560x420像素)


    Size dsize = Size(560, 420);


    Mat shrink;


    resize(img, shrink, dsize, 0, 0, INTER_AREA);


          


    //保存


    stringstream str;


    str << "../opencv_/data/pic/11" <<  ".png";


    imwrite(str.str(), shrink);

二、相机标定流程

主要是objectPoints:世界坐标系中的点。使用标准棋盘,传入的是交叉点(不包括边角)的实际坐标,以物理实际尺度(如mm)为单位。写坐标时,保证z轴为0,按照先x变化,后y变化,从小到大的顺序来写。如果网格尺寸为12.5毫米,写作:(0,0,0),(12.5,0,0), (25,0,0)...    

0e25309ddf5a18c5d23fbf7009d0dd2d.png

①读取图片,找到角点,对粗角点精确化

cv::imread(pic)

cv::findCirclesGrid()

cv::find4QuadCornerSubpix()

②设置棋盘三维物理坐标

我使用的是标准圆网格,7*7=49个。

③调用calibrateCamera()接口

程序如下:

 程序中cv::Size2f(12.5,12.5)是两圆的中心距。  

std::vector imagePointBuf;  /* 缓存每幅图像上检测到的角点 */
std::vector imagePointSeq;  /* 保存检测到的所有角点 */   


    int imageCount=0;  /* 图像数量 */
    cv::Size boardSize = cv::Size(7,7);    /* 标定板上每行、列的角点数 */
    cv::Size imageSize;  /* 图像的尺寸 */


    for(int i=1; i<12; i++){


        std::string pic("../CalibrateCamera/data/pic/" + std::to_string(i) +".png" );

        cv::Mat imageInput = cv::imread(pic);

          

        //cv::findChessboardCorners(imageInput,boardSize,imagePointBuf);

        bool ret = cv::findCirclesGrid(imageInput,boardSize,imagePointBuf);    
        if(true == ret){


            qDebug() << "findChessboardCorners success " << i;

            imageCount++;


            if (1 == imageCount) {

                imageSize.width = imageInput.cols;
                imageSize.height =imageInput.rows;
            }          

            cv::Mat viewGray;
//          cv::cvtColor(imageInput,viewGray,CV_BGR2GRAY);

            cv::cvtColor(imageInput,viewGray,cv::COLOR_BGR2GRAY);

          
            /* 亚像素精确化 */


            cv::find4QuadCornerSubpix(viewGray,imagePointBuf,cv::Size(7,7)); //对粗提取的角点进行精确化


            imagePointSeq.push_back(imagePointBuf); //保存亚像素角点
          
//          cv::drawChessboardCorners(imageInput, boardSize, imagePointBuf, true);
//          cv::imshow("Camera Calibration",viewGray);//显示图片
        }else{
            qDebug() << "findChessboardCorners failed " << i;
        }
    }


    qDebug() << "角点提取完成!\n";
          
    //以下是摄像机标定
    qDebug() << "开始标定………………";
    /*棋盘三维信息 mm*/
    cv::Size2f squareSize = cv::Size2f(12.5,12.5);  /* 实际测量得到的标定板上每个棋盘格的大小 */    
    std::vector     <std::vector> objectPoints; /* 保存标定板上角点的三维坐标 */     

    /*内外参数*/
    cv::Mat cameraMatrix = cv::Mat(3,3,CV_32FC1,cv::Scalar::all(0)); /* 摄像机内参数矩阵 */

    std::vector pointCounts;  // 每幅图像中角点的数量
    cv::Mat distCoeffs = cv::Mat(1,5,CV_32FC1,cv::Scalar::all(0)); /* 摄像机的5个畸变系数:k1,k2,p1,p2,k3 */

    std::vector rotateMat;  /* 每幅图像的旋转向量 */
    std::vector transMat; /* 每幅图像的平移向量 */          

    int i,j,t;


    for (t=0;t
        std::vector tempPointSet;

        for (i=0;i     <boardSize.height;i++){< span>     </boardSize.height;i++){<>


            for (j=0;j     <boardSize.width;j++){< span>     </boardSize.width;j++){<>


                cv::Point3f realPoint;

                /* 假设标定板放在世界坐标系中z=0的平面上 */
                realPoint.x = i*squareSize.width;
                realPoint.y = j*squareSize.height;
                realPoint.z = 0;
                tempPointSet.push_back(realPoint);
            }

        }

        objectPoints.push_back(tempPointSet);

    }
    /* 初始化每幅图像中的角点数量,假定每幅图像中都可以看到完整的标定板 */

        for (i=0;i     <imageCount;i++){< span>     </imageCount;i++){<>
            pointCounts.push_back(boardSize.width*boardSize.height);
        }


        /* 开始标定 */    

        cv::calibrateCamera(objectPoints, imagePointSeq, imageSize,
                            cameraMatrix, distCoeffs, rotateMat, transMat, 0);

        qDebug() <<"标定完成!\n";

    未完待续......

def37d6e2779bce0b1befeca1ff61470.png

5_相机标定_1_标定板选取与角点绘制

5_相机标定2_calibrateCamera()与内外参        

如需修改像素程序可在后台留言“修改图片像素”.

相关推荐

  1. 相机标定详解

    2024-03-19 15:46:05       8 阅读
  2. 【C/C++】相机标定

    2024-03-19 15:46:05       10 阅读
  3. 相机标定

    2024-03-19 15:46:05       6 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-19 15:46:05       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-19 15:46:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-19 15:46:05       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-19 15:46:05       20 阅读

热门阅读

  1. linux命令学习之split 分割大文件 —— 筑梦之路

    2024-03-19 15:46:05       17 阅读
  2. 24计算机考研调剂 | 浙江科技大学

    2024-03-19 15:46:05       15 阅读
  3. 一文解读ISO26262安全标准:初步危害分析PHA

    2024-03-19 15:46:05       16 阅读
  4. 分享SQL的7种进阶用法

    2024-03-19 15:46:05       18 阅读
  5. codetop刷题笔记1——两数之和/iota/lambda表达式

    2024-03-19 15:46:05       20 阅读
  6. 【sql】初识 where EXISTS

    2024-03-19 15:46:05       21 阅读
  7. Bash Shell中单引号和双引号的区别详解

    2024-03-19 15:46:05       25 阅读
  8. Git速成

    Git速成

    2024-03-19 15:46:05      17 阅读
  9. openh264初探

    2024-03-19 15:46:05       15 阅读
  10. 工程化专栏目录

    2024-03-19 15:46:05       20 阅读