(结构光代码篇)相机标定+投影仪标定

主要关注操作

相机标定

利用OpenCV(单目)相机标定函数calibrateCamera(),仅需要已知角点的世界座标、角点的图片座标、图片的尺寸,代入函数即可得到相机的内外各类参数。

世界座标的获取

以棋盘格所在平面作为世界座标系的xoyxoy平面,原点可以选择为棋盘格的第一个角点(随便选)。
需要已知:

  1. 棋盘格中含有内角点的个数Size board_size=Size(13,7)
  2. 格子的真实尺寸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);
	}
}

一般xx轴对应width,yy轴对应height。

图片角点的获取

步骤如下:

  1. 提取角点,使用OpenCV中的findChessboardCorners()
  2. 若提取角点成功,则对角点进行亚像素精确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_pointsvector<vector<Points>>,与图片的张数对应。

投影仪标定

世界座标获取

投影仪的投影角点世界座标通过相机为媒介获得。上一篇讲到,采集图片的时候保证投影图片与打印图片在同一个平面,就是因为这个目的。
以相机已经标定为前提。
步骤:

  1. 通过相机采集的图片得到投影的角点vector<Point2f> pro_imgpointsfindChessboardCorners()
  2. 通过相机标定的参数计算上述角点的世界座标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()函数

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章