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

代码如下:

#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; } 
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值