相机标定过程
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//最小精度
以上是关于相机标定过程的主要内容,如果未能解决你的问题,请参考以下文章