主要关注操作
相机标定
利用OpenCV(单目)相机标定函数calibrateCamera()
,仅需要已知角点的世界座标、角点的图片座标、图片的尺寸,代入函数即可得到相机的内外各类参数。
世界座标的获取
以棋盘格所在平面作为世界座标系的平面,原点可以选择为棋盘格的第一个角点(随便选)。
需要已知:
- 棋盘格中含有内角点的个数
Size board_size=Size(13,7)
- 格子的真实尺寸
Size square_size=Size(28.13,28.13)
,单位是mm
以此分配角点的世界座标
vector<Point3f> world_points;
for(int i=0;i<board_size.width;i++)
{
for(int j=0;j<board_size.hegight;j++)
{
Point3f Wpoint;
Wpoint.x=i*square_size.width;
Wpoint.y=j*square_size.height;
Wpoint.z=0;
world_points.pushback(Wpoint);
}
}
一般轴对应width,轴对应height。
图片角点的获取
步骤如下:
- 提取角点,使用OpenCV中的
findChessboardCorners()
- 若提取角点成功,则对角点进行亚像素精确
connerSubPix()
Mat image=read(" ");
if(0==findChessboardCorners(image,board_size,image_points,3))
{
cout<<"can not find conners"<<endl;
return;
}
else
{
Mat gray_img;
if(image.channels()>1)
cvtColor(image,gray_img,CV_RGB2GRAY);
else image.copyTo(gray_img);
connerSubPix(gray_img,image_points,Size(5,5),Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
}
标定
得到多组(12-20组)图片的角点以及对应的世界座标之后,即可调用函数cameraCalibrate()
cameraCalibrate(World_Points,image_points,image_size,camera_matrix,distcoeffs,R,T,0);
只需要注意,World_Points,image_points
是vector<vector<Points>>
,与图片的张数对应。
投影仪标定
世界座标获取
投影仪的投影角点世界座标通过相机为媒介获得。上一篇讲到,采集图片的时候保证投影图片与打印图片在同一个平面,就是因为这个目的。
以相机已经标定为前提。
步骤:
- 通过相机采集的图片得到投影的角点
vector<Point2f> pro_imgpoints
,findChessboardCorners()
- 通过相机标定的参数计算上述角点的世界座标
vector<Point3f> pro_wordpoints
vector<Point2f> pro_imgpoints;
if(0==findChessboardCorners(image,pro_board_size,pro_imgpoints,3))
return;
else
{
Mat gray_img;
if(image.channels()>1)
cvtColor(image,gray_img,CV_RGB2GRAY);
else image.copyTo(gray_img);
connerSubPix(gray_img,pro_imgpoints,Size(5,5),Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
}
///
Mat h(3, 3, CV_32FC1);
h = findHomography(image_points, world_points, RANSAC);
Mat homo=Mat(3,3,cv_32FC1,Scalar(0));
h.copyTo(homo);
homo.convertTo(homo,CV_32FC1);
for(int i=0;i<pro_imgpoints.size();i++)
{
Point3f pro_wpoint,pro_img_point1;
pro_img_point1.x=pro_imgpoints[i].x;
pro_img_point1.y=pro_imgpoints[i].y;
pro_img_point1.z=1;//齐次座标
pro_wpoint=homo*pro_img_point1;
pro_wpoint.x=pro_wpoint.x/pro_wpoint.z;
pro_wpoint.y=pro_wpoint.y/pro_wpoint.z;
pro_wpoint.z=0;
pro_worldpoints.pushback(pro_wpoint);
}
图片角点的获取
用于投影的图片相当于投影仪“采集”的图片,直接求其角点座标即可。
标定
同相机标定,调用cameraCalibrate()
函数