相机标定过程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了相机标定过程相关的知识,希望对你有一定的参考价值。

1. 摄像机标定的数学过程如下:

 技术分享

这里程序的实现是在opencv中,所以就用opencv的程序来说明具体的过程.注意各个版本的opencv之间的程序移植性并不好,以下程序是在opencv2.4.3下编制运行的,

注意

1.程序运行前需要插上摄像头,否则程序有可能不能正常运行


2.获取棋盘格图像

张正友论文中建议棋盘格数大于7*7,棋盘格在图像中所占面积在50%以上,其实这里是有问题的,因为原来遇到过球面相机将棋盘格放置大于50%以上反而出问题,这里还没有弄清楚怎么回事,所以以下的标定都是针对非球面相机的.

    for (int i=1; i<=19; i++)//输入左标定板图像
    {
        std::stringstream str;//声明输入输出流
        str << "./left"  << i << ".jpg";//以名字方式把图像输入到流
        std::cout << str.str() << std::endl;//.str("")清除内容 .clear()清空标记位
        leftFileList.push_back(str.str());//.push_back从容器后向前插入数据
        leftBoardImage = cv::imread(str.str(),0);//用来显示即时输入的图像
        cv::namedWindow("left chessboard image");
        cv::imshow("left chessboard image",leftBoardImage);
        cv::waitKey(10);
    }


3.定义棋盘格的角点数目

 cv::Size boardSize(14,10)


4.程序定位提取角点

这里建立的是世界坐标系(三维)和图像坐标系(二维)之间的关系

(1)首先声明两个坐标容器

    std::vector<cv::Point2f> imageCorners;//二位坐标点
    std::vector<cv::Point3f> objectCorners;//三维坐标点

(2)初始化棋盘角点,令其位置位于(x,y,z)=(i,j,0),一个棋盘格为一个坐标值

    for (int i=0; i<boardSize.height; i++)
    {
        for (int j=0; j<boardSize.width; j++)
        {
            objectCorners.push_back(cv::Point3f(i, j, 0.0f));
        }
    }

(3)直接使用opencv内函数找到二维角点坐标,并建立标定标定格子和实际坐标间的关系(像素级别)

这个函数使用时,当标定板是长方形时可以找到角点,但是标定板是正方形时,就找不到,原因还未知

cv::findChessboardCorners(image, boardSize, imageCorners);

(4)获得像素精度往往是不够的,还需要获得亚像素的精度

        cv::cornerSubPix(image,
            imageCorners,
            cv::Size(5,5),//搜索框的一半,表示在多大窗口定位角点
            cv::Size(-1,-1), //死区
            cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS,
            30,        // max number of iterations//迭代最大次数
            0.01));     // min accuracy//最小精度

以上是关于相机标定过程的主要内容,如果未能解决你的问题,请参考以下文章

opencv相机标定

工业相机需不需要标定?

相机标定

相机单独标定的实现过程[autoware标定]tmp文件的查看方式

计算机视觉——相机参数标定

OpenCV相机标定与畸变校正