OPENCV3.0 单目摄像头标定(使用官方自带的标定图片)

来源:互联网 发布:阿里云隐藏域名信息 编辑:程序博客网 时间:2024/05/16 06:16

[cpp] view plain copy
  1. // opencv_test.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include <opencv2/opencv.hpp>  
  6. #include <highgui.hpp>  
  7. #include "cv.h"  
  8. #include <cv.hpp>  
  9. #include <iostream>  
  10.   
  11. using namespace std;  
  12. using namespace cv;  
  13.   
  14. const int imageWidth = 640;                             //摄像头的分辨率  
  15. const int imageHeight = 480;  
  16. const int boardWidth = 9;                               //横向的角点数目  
  17. const int boardHeight = 6;                              //纵向的角点数据  
  18. const int boardCorner = boardWidth * boardHeight;       //总的角点数据  
  19. const int frameNumber = 13;                             //相机标定时需要采用的图像帧数  
  20. const int squareSize = 20;                              //标定板黑白格子的大小 单位mm  
  21. const Size boardSize = Size(boardWidth, boardHeight);   //  
  22.       
  23. Mat intrinsic;                                          //相机内参数  
  24. Mat distortion_coeff;                                   //相机畸变参数  
  25. vector<Mat> rvecs;                                        //旋转向量  
  26. vector<Mat> tvecs;                                        //平移向量  
  27. vector<vector<Point2f>> corners;                        //各个图像找到的角点的集合 和objRealPoint 一一对应  
  28. vector<vector<Point3f>> objRealPoint;                   //各副图像的角点的实际物理坐标集合  
  29.   
  30.   
  31. vector<Point2f> corner;                                   //某一副图像找到的角点  
  32.   
  33. Mat rgbImage, grayImage;  
  34.   
  35. /*计算标定板上模块的实际物理坐标*/  
  36. void calRealPoint(vector<vector<Point3f>>& obj, int boardwidth,int boardheight, int imgNumber, int squaresize)  
  37. {  
  38. //  Mat imgpoint(boardheight, boardwidth, CV_32FC3,Scalar(0,0,0));  
  39.     vector<Point3f> imgpoint;  
  40.     for (int rowIndex = 0; rowIndex < boardheight; rowIndex++)  
  41.     {  
  42.         for (int colIndex = 0; colIndex < boardwidth; colIndex++)  
  43.         {  
  44.         //  imgpoint.at<Vec3f>(rowIndex, colIndex) = Vec3f(rowIndex * squaresize, colIndex*squaresize, 0);  
  45.             imgpoint.push_back(Point3f(rowIndex * squaresize, colIndex * squaresize, 0));  
  46.         }  
  47.     }  
  48.     for (int imgIndex = 0; imgIndex < imgNumber; imgIndex++)  
  49.     {  
  50.         obj.push_back(imgpoint);  
  51.     }  
  52. }  
  53.   
  54. /*设置相机的初始参数 也可以不估计*/  
  55. void guessCameraParam(void )  
  56. {  
  57.     /*分配内存*/  
  58.     intrinsic.create(3, 3, CV_64FC1);  
  59.     distortion_coeff.create(5, 1, CV_64FC1);  
  60.   
  61.     /* 
  62.     fx 0 cx 
  63.     0 fy cy 
  64.     0 0  1 
  65.     */  
  66.     intrinsic.at<double>(0,0) = 256.8093262;   //fx         
  67.     intrinsic.at<double>(0, 2) = 160.2826538;   //cx  
  68.     intrinsic.at<double>(1, 1) = 254.7511139;   //fy  
  69.     intrinsic.at<double>(1, 2) = 127.6264572;   //cy  
  70.   
  71.     intrinsic.at<double>(0, 1) = 0;  
  72.     intrinsic.at<double>(1, 0) = 0;  
  73.     intrinsic.at<double>(2, 0) = 0;  
  74.     intrinsic.at<double>(2, 1) = 0;  
  75.     intrinsic.at<double>(2, 2) = 1;  
  76.   
  77.     /* 
  78.     k1 k2 p1 p2 p3 
  79.     */  
  80.     distortion_coeff.at<double>(0, 0) = -0.193740;  //k1  
  81.     distortion_coeff.at<double>(1, 0) = -0.378588;  //k2  
  82.     distortion_coeff.at<double>(2, 0) = 0.028980;   //p1  
  83.     distortion_coeff.at<double>(3, 0) = 0.008136;   //p2  
  84.     distortion_coeff.at<double>(4, 0) = 0;          //p3  
  85. }  
  86.   
  87. void outputCameraParam(void )  
  88. {  
  89.     /*保存数据*/  
  90.     //cvSave("cameraMatrix.xml", &intrinsic);  
  91.     //cvSave("cameraDistoration.xml", &distortion_coeff);  
  92.     //cvSave("rotatoVector.xml", &rvecs);  
  93.     //cvSave("translationVector.xml", &tvecs);  
  94.     /*输出数据*/  
  95.     cout << "fx :" << intrinsic.at<double>(0, 0) << endl << "fy :" << intrinsic.at<double>(1, 1) << endl;  
  96.     cout << "cx :" << intrinsic.at<double>(0, 2) << endl << "cy :" << intrinsic.at<double>(1, 2) << endl;  
  97.   
  98.     cout << "k1 :" << distortion_coeff.at<double>(0, 0) << endl;  
  99.     cout << "k2 :" << distortion_coeff.at<double>(1, 0) << endl;  
  100.     cout << "p1 :" << distortion_coeff.at<double>(2, 0) << endl;  
  101.     cout << "p2 :" << distortion_coeff.at<double>(3, 0) << endl;  
  102.     cout << "p3 :" << distortion_coeff.at<double>(4, 0) << endl;  
  103. }  
  104.   
  105.   
  106. int _tmain(int argc, _TCHAR* argv[])  
  107. {  
  108.     Mat img;  
  109.     int goodFrameCount = 0;  
  110.     namedWindow("chessboard");  
  111.     cout << "按Q退出 ..." << endl;  
  112.     while (goodFrameCount < frameNumber)  
  113.     {  
  114.         char filename[100];  
  115.         sprintf_s(filename,"image\\left%02d.jpg", goodFrameCount + 1);  
  116.     //  cout << filename << endl;  
  117.         rgbImage = imread(filename, CV_LOAD_IMAGE_COLOR);  
  118.         cvtColor(rgbImage, grayImage, CV_BGR2GRAY);  
  119.         imshow("Camera", grayImage);  
  120.           
  121.         bool isFind = findChessboardCorners(rgbImage, boardSize, corner,0);  
  122.         if (isFind == true//所有角点都被找到 说明这幅图像是可行的  
  123.         {  
  124.             /* 
  125.             Size(5,5) 搜索窗口的一半大小 
  126.             Size(-1,-1) 死区的一半尺寸 
  127.             TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1)迭代终止条件 
  128.             */  
  129.             cornerSubPix(grayImage, corner, Size(5,5), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1));  
  130.             drawChessboardCorners(rgbImage, boardSize, corner, isFind);  
  131.             imshow("chessboard", rgbImage);  
  132.             corners.push_back(corner);  
  133.             //string filename = "res\\image\\calibration";  
  134.             //filename += goodFrameCount + ".jpg";  
  135.             //cvSaveImage(filename.c_str(), &IplImage(rgbImage));       //把合格的图片保存起来  
  136.             goodFrameCount++;  
  137.             cout << "The image is good" << endl;  
  138.         }  
  139.         else  
  140.         {  
  141.             cout << "The image is bad please try again" << endl;  
  142.         }  
  143.     //  cout << "Press any key to continue..." << endl;  
  144.     //  waitKey(0);  
  145.   
  146.        if (waitKey(10) == 'q')  
  147.         {  
  148.             break;  
  149.         }  
  150.     //  imshow("chessboard", rgbImage);  
  151.     }  
  152.   
  153.     /* 
  154.     图像采集完毕 接下来开始摄像头的校正 
  155.     calibrateCamera() 
  156.     输入参数 objectPoints  角点的实际物理坐标 
  157.              imagePoints   角点的图像坐标 
  158.              imageSize     图像的大小 
  159.     输出参数 
  160.              cameraMatrix  相机的内参矩阵 
  161.              distCoeffs    相机的畸变参数 
  162.              rvecs         旋转矢量(外参数) 
  163.              tvecs         平移矢量(外参数) 
  164.     */  
  165.       
  166.     /*设置实际初始参数 根据calibrateCamera来 如果flag = 0 也可以不进行设置*/  
  167.     guessCameraParam();           
  168.     cout << "guess successful" << endl;  
  169.     /*计算实际的校正点的三维坐标*/  
  170.     calRealPoint(objRealPoint, boardWidth, boardHeight,frameNumber, squareSize);  
  171.     cout << "cal real successful" << endl;  
  172.     /*标定摄像头*/  
  173.     calibrateCamera(objRealPoint, corners, Size(imageWidth, imageHeight), intrinsic, distortion_coeff, rvecs, tvecs, 0);  
  174.     cout << "calibration successful" << endl;  
  175.     /*保存并输出参数*/  
  176.     outputCameraParam();  
  177.     cout << "out successful" << endl;  
  178.       
  179.     /*显示畸变校正效果*/  
  180.     Mat cImage;  
  181.     undistort(rgbImage, cImage, intrinsic, distortion_coeff);  
  182.     imshow("Corret Image", cImage);  
  183.     cout << "Correct Image" << endl;  
  184.     cout << "Wait for Key" << endl;  
  185.     waitKey(0);  
  186.     system("pause");  
  187.     return 0;  
  188. }  

OPENCV3.0版本跟2.x版本是有一点差距的,这个程序在2.4.11版本里面跑不起来。

找了很久都没有找到错误,主要是在calibrateCamera()函数的时候出错。

也参考了官方的calibration例程,但还是找不到错误在什么地方。

下面是3.0版本的代码 注释都在代码里面

原创粉丝点击