前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >5_相机标定_3_calibrateCamera()例子

5_相机标定_3_calibrateCamera()例子

作者头像
用户5908113
发布2024-03-20 14:20:31
770
发布2024-03-20 14:20:31
举报
文章被收录于专栏:Pou光明Pou光明

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

程序中所用标准标定板。

一、图片预处理

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

代码语言:javascript
复制
 // 最小分辨率(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)...

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

cv::imread(pic)

cv::findCirclesGrid()

cv::find4QuadCornerSubpix()

②设置棋盘三维物理坐标

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

③调用calibrateCamera()接口

程序如下:

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

代码语言:javascript
复制
 std::vector imagePointBuf;  /* 缓存每幅图像上检测到的角点 */

    std::vector     <std::vector> imagePointSeq; /* 保存检测到的所有角点 */     </std::vector

    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; /* 保存标定板上角点的三维坐标 */     </std::vector

    /*内外参数*/

    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";

未完待续......

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Pou光明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档