对相机标定,然后对视频进行校正

代码如下:

#include 
#include 
using namespace std;
using namespace cv;

int main()
{
	ifstream fin("calibdata.txt");  //标定所用图像文件的路径 
	ofstream fout("caliberation_result.txt");  //保存定标结果的文件

    //读取每一幅图像,从中提取出角点,然后对角点进行亚像素精确化
											  
	cout << "开始提取角点………………" << endl;
	int image_count = 9;                    //图像数量 
	Size image_size;                         //图像的尺寸 
	Size board_size = Size(6, 7);            //定标板上每行、列的角点数 
	vector corners;                  //缓存每幅图像上检测到的角点   
	vector>  corners_Seq;    //保存检测到的所有角点 
	vector  image_Seq;


	int count = 0;
	for (int i = 0; i != image_count; i++)
	{
		cout << "Frame #" << i + 1 << "..." << endl;
		string imageFileName;
		std::stringstream StrStm;
		StrStm << i + 1;
		StrStm >> imageFileName;
		imageFileName += ".jpg";
		cv::Mat image = imread("img" + imageFileName);
		image_size = image.size();
		//image_size = Size(image.cols , image.rows);
		/* 提取角点 */
		Mat imageGray;
		cvtColor(image, imageGray, CV_RGB2GRAY);
		bool patternfound = findChessboardCorners(image, board_size, corners, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE +
			CALIB_CB_FAST_CHECK);
		if (!patternfound)
		{
			cout << "can not find chessboard corners!\n";
			exit(1);
		}
		else
		{
			//亚像素精确化 
			cornerSubPix(imageGray, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
			count = count + corners.size();
			corners_Seq.push_back(corners);
		}
		image_Seq.push_back(image);
	}
	cout << "角点提取完成!\n";
	 
	//摄像机定标
	cout << "开始定标………………" << endl;
	Size square_size = Size(20, 20);                                      //实际测量得到的定标板上每个棋盘格的大小 
	vector>  object_Points;                                      //保存定标板上角点的三维坐标 


	Mat image_points = Mat(1, count, CV_32FC2, Scalar::all(0));          //保存提取的所有角点 
	vector  point_counts;                                          //每幅图像中角点的数量
	Mat intrinsic_matrix = Mat(3, 3, CV_32FC1, Scalar::all(0));                //摄像机内参数矩阵
	Mat distortion_coeffs = Mat(1, 4, CV_32FC1, Scalar::all(0));            //摄像机的4个畸变系数:k1,k2,p1,p2
	vector rotation_vectors;                                      //每幅图像的旋转向量
	vector translation_vectors;                                  //每幅图像的平移向量

																		  //初始化定标板上角点的三维坐标 
	for (int t = 0;t tempPointSet;
		for (int i = 0;i  image_points2;             //保存重新计算得到的投影点    

	cout << "每幅图像的定标误差:" << endl;
	cout << "每幅图像的定标误差:" << endl << endl;
	for (int i = 0; i tempPointSet = object_Points[i];
		
		//通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点 
		projectPoints(tempPointSet, rotation_vectors[i], translation_vectors[i], intrinsic_matrix, distortion_coeffs, image_points2);
		//计算新的投影点和旧的投影点之间的误差
		vector tempImagePoint = corners_Seq[i];
		Mat tempImagePointMat = Mat(1, tempImagePoint.size(), CV_32FC2);
		Mat image_points2Mat = Mat(1, image_points2.size(), CV_32FC2);
		for (size_t i = 0; i != tempImagePoint.size(); i++)
		{
			image_points2Mat.at(0, i) = Vec2f(image_points2[i].x, image_points2[i].y);
			tempImagePointMat.at(0, i) = Vec2f(tempImagePoint[i].x, tempImagePoint[i].y);
		}
		err = norm(image_points2Mat, tempImagePointMat, NORM_L2);
		total_err += err /= point_counts[i];
		cout << "第" << i + 1 << "幅图像的平均误差:" << err << "像素" << endl;
		fout << "第" << i + 1 << "幅图像的平均误差:" << err << "像素" << endl;
	}
	cout << "总体平均误差:" << total_err / image_count << "像素" << endl;
	fout << "总体平均误差:" << total_err / image_count << "像素" << endl << endl;
	cout << "评价完成!" << endl;

	//保存定标结果

	cout << "开始保存定标结果………………" << endl;
	Mat rotation_matrix = Mat(3, 3, CV_32FC1, Scalar::all(0)); //保存每幅图像的旋转矩阵 

	fout << "相机内参数矩阵:" << endl;
	fout << intrinsic_matrix << endl;
	fout << "畸变系数:\n";
	fout << distortion_coeffs << endl;
	for (int i = 0; i> imageFileName;
		imageFileName += "_d.jpg";
		imwrite(imageFileName, t);
	}
	cout << "保存结束" << endl;


	//测试一张图片
 	cout << "TestImage ..." << endl;
	Mat newCameraMatrix = Mat(3, 3, CV_32FC1, Scalar::all(0));

	VideoCapture captrue("calibration.avi");
	//检测是否正常打开:成功打开时,isOpened返回ture
	if (!captrue.isOpened())
		cout << "fail to open!" << endl;
	//获取整个帧数  
	long totalFrameNumber = captrue.get(CV_CAP_PROP_FRAME_COUNT);
	cout << "整个视频共" << totalFrameNumber << "帧" << endl;

	//获取帧率  
	double rate = captrue.get(CV_CAP_PROP_FPS);
	cout << "帧率为:" << rate << endl;

	//定义一个用来控制读取视频循环结束的变量  
	bool stop = false;
	//承载每一帧的图像  
	Mat frame;
	//显示每一帧的窗口  
	namedWindow("Extracted frame");
	//两帧间的间隔时间:  
	//int delay = 1000/rate;  
	int delay = 1000 / rate;

	long currentFrame = 1;

	while (!stop)
	{
		//读取下一帧  
		if (!captrue.read(frame))
		{
			cout << "读取视频失败" << endl;
			return -1;
		} 

		//矫正  
		imshow("Extracted frame", frame);
		initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, R, intrinsic_matrix, image_size, CV_32FC1, mapx, mapy);
		Mat t = frame.clone();
		cv::remap(frame, t, mapx, mapy, INTER_LINEAR);

		imshow("after filter", t);
		cout << "正在读取第" << currentFrame << "帧" << endl;  


		int c = waitKey(delay);
		//按下ESC或者到达指定的结束帧后退出读取视频  
		if ((char)c == 27 || currentFrame > totalFrameNumber-1)
		{
			stop = true;
		}
		//按下按键后会停留在当前帧,等待下一次按键  
		if (c >= 0)
		{
			waitKey(0);
		}

		VideoWriter write;
		string outFlie = "the video of calibration.avi";
		write.write(t);
		write.write(t);
		write.write(t);

		currentFrame++;

	}
	//关闭视频文件  
	captrue.release();
	waitKey(0);
	return 0;
}

你可能感兴趣的:(对相机标定,然后对视频进行校正)