OPENCV3.0 單目攝像頭標定(使用官方自帶的標定圖片)

bbzz2發表於2017-07-17

[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版本的程式碼 註釋都在程式碼裡面

相關文章