相机标定问题-实践操作流程

孤者浪人 提交于 2020-04-22 11:51:28

接上一篇文章讲解的相机标定的基本概念,这篇文章主要阐述一下如何使用Matlab或者Opencv等软件得的Camera内参之后,如何保存调用内参完成对应Camera的标定流程。

一、Matlab标定鱼眼镜头实践

1. 这里我使用的Camera是Jetson Nano专用的鱼眼摄像机,具体参数如下所示:

我使用的畸变较大的鱼眼镜头。

由于我采用的是红外夜视的Camera,结果在光线稍微不好的时候就会出现图片偏红色的情况(解决方案:微雪Camera-wiki

    如果大家没有必要的夜视应用场景,建议不要使用红外夜视的摄像头,如果在后期处理的过程中还要对畸变图像矫正,建议就不要使用广角鱼眼摄像头了,因为矫正之后的视野区域也会有所减少,这一点可以在后面矫正的程序中看到(在畸变矫正的过程中,也需要消耗部分CPU资源,这样对于嵌入式板卡来说也许就不划算了)

2. 基于JetsonNano板卡,读取CSI摄像头的Demo程序如下:

 1 import cv2
 2 import sys
 3 import glob
 4 import time
 5 import threading
 6 import numpy as np
 7 
 8 if len(sys.argv) == 1:
 9     print 'Please Choose the CSI-Camera id for image sample.Try again!'
10     exit(0)
11 
12 Camera_ID = int(sys.argv[1])
13 
14 def gstreamer_pipeline(
15     csi_camera_id = 0,
16     capture_width=1280,
17     capture_height=720,
18     display_width=1280,
19     display_height=720,
20     framerate=60,
21     flip_method=0,
22 ):
23     return (
24         "nvarguscamerasrc sensor_id=%d ! "
25         "video/x-raw(memory:NVMM), "
26         "width=(int)%d, height=(int)%d, "
27         "format=(string)NV12, framerate=(fraction)%d/1 ! "
28         "nvvidconv flip-method=%d ! "
29         "video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
30         "videoconvert ! "
31         "video/x-raw, format=(string)BGR ! appsink"
32         % (
33             csi_camera_id,
34             capture_width,
35             capture_height,
36             framerate,
37             flip_method,
38             display_width,
39             display_height,
40         )
41     )
42 
43 print 'Starting Capture...'
44 csi_pipeline_str = gstreamer_pipeline(csi_camera_id=Camera_ID,flip_method=0)
45 print csi_pipeline_str
46 cap = cv2.VideoCapture(csi_pipeline_str, cv2.CAP_GSTREAMER)
47 count = 0
48 while not cap.isOpened():
49     time.sleep(0.5)
50     print('Camera is Initialize...')
51     count += 1
52     if count == 10:
53         print 'CSICamera Initial Failed!'
54         cap.release()
55         exit(0)
56 
57 ret, frame = cap.read()
58 
59 Key_val = 0
60 
61 def Keybo_Moni():
62     count = 0
63     while True:
64         global Key_val, frame, process_flag, cap
65         if Key_val == ord('r'):
66             Key_val= 0
67             cv2.imwrite('CSICamera' + str(Camera_ID) + '-' + str(count) + '.jpg', frame)
68             count += 1
69             print('Get new pic %d' % count)
70         if Key_val == ord('q'):
71             break
72 
73 try:
74     Keybo_Moni_Thread = threading.Thread(target=Keybo_Moni, name='Keyboard-Thread')
75     Keybo_Moni_Thread.start()
76 except:
77     print('Error:uqnable to start the thread!')
78 
79 while True:
80     ret, frame = cap.read()
81     cv2.imshow('Video_Show', frame)
82     Key_val = cv2.waitKey(1)
83     if Key_val == ord('q'):
84         cv2.destroyAllWindows()
85         cap.release()
86         print('Pic Sample Finished!')
87         break
88 
89 print('Finished CalibrateCamera Image Sample...')

程序中涉及到了Gstreamer等多媒体pipeline框架内容,请参考这里,Python脚本的使用方法:

python CSICAM_Calibraton_Sample.py 1 # 采集CSI-Camera1摄像头的内容
python CSICAM_Calibraton_Sample.py 0 # 采集CSI-Camera0摄像头的内容

如果你使用的其他的USB Camera,可以参考使用如下程序:

 1 import cv2
 2 import glob
 3 import time
 4 import threading
 5 import numpy as np
 6 
 7 print('Starting Capture...')
 8 cap = cv2.VideoCapture(2)
 9 while not cap.isOpened():
10         time.sleep(100)
11         print('Camera is Initialize...')
12 
13 width = int(cap.get(3))
14 height = int(cap.get(4))
15 
16 frame = np.zeros((width,height,3),dtype=np.uint8)
17 ret, frame = cap.read()
18 
19 Key_val = 0
20 
21 def Keybo_Moni():
22         count = 0
23         while True:
24                 global Key_val, frame, process_flag, cap
25                 if Key_val == ord('r'):
26                         Key_val= 0
27                         cv2.imwrite('ResPic' + str(count) + '.jpg', frame)
28                         count += 1
29                         print('Get new pic %d' % count)
30                 if Key_val == ord('q'):
31                         Key_val = 'q'
32                         break;
33 
34 try:
35         Keybo_Moni_Thread = threading.Thread(target=Keybo_Moni, name='Keyboard-Thread')
36         Keybo_Moni_Thread.start()
37 except:
38         print('Error:uqnable to start the thread!')
39 
40 while True:
41         ret, frame = cap.read()
42         cv2.imshow('Video_Show', frame)
43         Key_val = cv2.waitKey(1)
44         if Key_val == ord('q'):
45                 cv2.destroyAllWindows()
46                 cap.release()
47                 print('Pic Sample Finished!')
48                 break
49 
50 print('Finished CalibrateCamera Image Sample...')
View Code

3. 接下来使用采集图像进行Matlab进行标定

能够看到,矫正之后的图像还是粉粉的...(问题待解决!)

具体matlab进行相机标定流程请参看我前一篇内容,下面是矫正前后的效果图:

从两图对比中,我们可以看出,section_a区域的部分以及Section_b的部分都发生了明显的变化,原来应该显示的内容由于图像在矫正的过程中根据内插法消失了,那么我们如何获取Camera的内参呢?

对于Matlab之前的版本直接参看上一篇教程,由于我使用的是2019b版本的Matlab,使用操作方式有所不同,在这里说明如下:

a) 点击工具栏位置的 Export Camera Parameters,这样会输出相机的基本内参以及外参到Matlab的工作空间中:

这样就会将相机参数保存在工作空间,名称为cameraParams。

在工作区中,可以找到cameraParams变量,单机右键,打开所选内容,如下所示:

将图中颜色标出的参数保存即可。

同时这里我们有必要将工作空间中cameraParams mat变量保存下来为下一次矫正的过程使用提供相机的内参数据,单机右键点击另存为,将相机的参数数据保存即可(参考.mat数据保存使用)。

b) 点击工具栏位置的 Export Camera Parameters下拉箭头,选择Generate Matalab script:

% Auto-generated by cameraCalibrator app on 15-Apr-2020
%-------------------------------------------------------


% Define images to process
imageFileNames = {'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-0.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-3.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-4.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-5.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-7.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-8.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-9.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-10.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-11.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-12.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-13.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-14.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-15.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-16.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-17.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-18.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-19.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-20.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-21.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-22.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-23.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-24.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-25.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-26.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-27.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-28.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-29.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-30.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-31.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-32.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-33.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-34.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-35.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-36.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-37.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-40.jpg',...
    'C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-41.jpg',...
    };
% Detect checkerboards in images
[imagePoints, boardSize, imagesUsed] = detectCheckerboardPoints(imageFileNames);
imageFileNames = imageFileNames(imagesUsed);

% Read the first image to obtain image size
originalImage = imread(imageFileNames{1});
[mrows, ncols, ~] = size(originalImage);

% Generate world coordinates of the corners of the squares
squareSize = 40;  % in units of 'millimeters'
worldPoints = generateCheckerboardPoints(boardSize, squareSize);

% Calibrate the camera
[cameraParams, imagesUsed, estimationErrors] = estimateCameraParameters(imagePoints, worldPoints, ...
    'EstimateSkew', false, 'EstimateTangentialDistortion', false, ...
    'NumRadialDistortionCoefficients', 2, 'WorldUnits', 'millimeters', ...
    'InitialIntrinsicMatrix', [], 'InitialRadialDistortion', [], ...
    'ImageSize', [mrows, ncols]);

% View reprojection errors
h1=figure; showReprojectionErrors(cameraParams);

% Visualize pattern locations
h2=figure; showExtrinsics(cameraParams, 'CameraCentric');

% Display parameter estimation errors
displayErrors(estimationErrors, cameraParams);

% For example, you can use the calibration data to remove effects of lens distortion.
undistortedImage = undistortImage(originalImage, cameraParams);

% See additional examples of how to use the calibration data.  At the prompt type:
% showdemo('MeasuringPlanarObjectsExample')
% showdemo('StructureFromMotionExample')
View Code

运行刚刚生成保存的代码,得到如下的结果:

            Standard Errors of Estimated Camera Parameters
            ----------------------------------------------
Intrinsics
----------
Focal length (pixels):   [  794.4361 +/- 1.3790      796.3933 +/- 1.3197  ]
Principal point (pixels):[  606.8329 +/- 0.8403      393.2514 +/- 0.9863  ]
Radial distortion:       [   -0.3111 +/- 0.0010        0.0837 +/- 0.0007  ]
Extrinsics
----------
Rotation vectors:
                         [   -0.2723 +/- 0.0024        0.0407 +/- 0.0022        0.0792 +/- 0.0005  ] ...
Translation vectors (millimeters):
                         [  -90.3841 +/- 0.5212     -121.9121 +/- 0.6037      485.5467 +/- 0.8995  ] ...

根据上述结果,我们可以得到此鱼眼相机的畸变参数为(k1=-0.3111 k2=0.0837),使用这个参数进行图像的畸变矫正即可。

4. 使用畸变参数对Camera采集的图像进行矫正:

将3步骤中保存下来的数据加载到Matlab当中:

load cameraParams

注意,此时必须添加cameraParams文件保存的文件空间到Matlab工作空间中来,加载完成之后就可以使用参数进行相机采集图片的矫正了:

I = imread('C:\Users\Administrator\Desktop\ImageData\CAM0\CSICamera0-41.jpg');
I_R = undistortImage(I, cameraParams);
figure,
imshow(I_R)
figure,
imshow(I)

运行结果如下所示:

至此,关于Matlab这端的图像畸变矫正过程就算是完成了,如何使用畸变以及相机内参完成畸变矫正参看下面链接:

相机畸变校正详解:https://blog.csdn.net/hanxiaoyong_/article/details/82888946

二、Cpp-Opencv标定鱼眼镜头实践

1. 依然使用之前采集的图片源,使用Opencv官方代码进行Camera的矫正:

首先下载官方源代码:https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/calib3d/camera_calibration

参考官方标定算法手册:https://docs.opencv.org/master/d4/d94/tutorial_camera_calibration.html

 下载很慢的可以直接拷贝我的程序:

camera_calibration.cpp (主程序文件,包括了图像输入,图像角点提取,图形标定,相机参数保存等功能模块)

  1 #include <iostream>
  2 #include <sstream>
  3 #include <string>
  4 #include <ctime>
  5 #include <cstdio>
  6 
  7 #include <opencv2/core.hpp>
  8 #include <opencv2/core/utility.hpp>
  9 #include <opencv2/imgproc.hpp>
 10 #include <opencv2/calib3d.hpp>
 11 #include <opencv2/imgcodecs.hpp>
 12 #include <opencv2/videoio.hpp>
 13 #include <opencv2/highgui.hpp>
 14 
 15 using namespace cv;
 16 using namespace std;
 17 
 18 class Settings
 19 {
 20 public:
 21     Settings() : goodInput(false) {}
 22     enum Pattern { NOT_EXISTING, CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID };
 23     enum InputType { INVALID, CAMERA, VIDEO_FILE, IMAGE_LIST };
 24 
 25     void write(FileStorage& fs) const                        //Write serialization for this class
 26     {
 27         fs << "{"
 28                   << "BoardSize_Width"  << boardSize.width
 29                   << "BoardSize_Height" << boardSize.height
 30                   << "Square_Size"         << squareSize
 31                   << "Calibrate_Pattern" << patternToUse
 32                   << "Calibrate_NrOfFrameToUse" << nrFrames
 33                   << "Calibrate_FixAspectRatio" << aspectRatio
 34                   << "Calibrate_AssumeZeroTangentialDistortion" << calibZeroTangentDist
 35                   << "Calibrate_FixPrincipalPointAtTheCenter" << calibFixPrincipalPoint
 36 
 37                   << "Write_DetectedFeaturePoints" << writePoints
 38                   << "Write_extrinsicParameters"   << writeExtrinsics
 39                   << "Write_gridPoints" << writeGrid
 40                   << "Write_outputFileName"  << outputFileName
 41 
 42                   << "Show_UndistortedImage" << showUndistorsed
 43 
 44                   << "Input_FlipAroundHorizontalAxis" << flipVertical
 45                   << "Input_Delay" << delay
 46                   << "Input" << input
 47            << "}";
 48     }
 49     void read(const FileNode& node)                          //Read serialization for this class
 50     {
 51         node["BoardSize_Width" ] >> boardSize.width;
 52         node["BoardSize_Height"] >> boardSize.height;
 53         node["Calibrate_Pattern"] >> patternToUse;
 54         node["Square_Size"]  >> squareSize;
 55         node["Calibrate_NrOfFrameToUse"] >> nrFrames;
 56         node["Calibrate_FixAspectRatio"] >> aspectRatio;
 57         node["Write_DetectedFeaturePoints"] >> writePoints;
 58         node["Write_extrinsicParameters"] >> writeExtrinsics;
 59         node["Write_gridPoints"] >> writeGrid;
 60         node["Write_outputFileName"] >> outputFileName;
 61         node["Calibrate_AssumeZeroTangentialDistortion"] >> calibZeroTangentDist;
 62         node["Calibrate_FixPrincipalPointAtTheCenter"] >> calibFixPrincipalPoint;
 63         node["Calibrate_UseFisheyeModel"] >> useFisheye;
 64         node["Input_FlipAroundHorizontalAxis"] >> flipVertical;
 65         node["Show_UndistortedImage"] >> showUndistorsed;
 66         node["Input"] >> input;
 67         node["Input_Delay"] >> delay;
 68         node["Fix_K1"] >> fixK1;
 69         node["Fix_K2"] >> fixK2;
 70         node["Fix_K3"] >> fixK3;
 71         node["Fix_K4"] >> fixK4;
 72         node["Fix_K5"] >> fixK5;
 73 
 74         validate();
 75     }
 76     void validate()
 77     {
 78         goodInput = true;
 79         if (boardSize.width <= 0 || boardSize.height <= 0)
 80         {
 81             cerr << "Invalid Board size: " << boardSize.width << " " << boardSize.height << endl;
 82             goodInput = false;
 83         }
 84         if (squareSize <= 10e-6)
 85         {
 86             cerr << "Invalid square size " << squareSize << endl;
 87             goodInput = false;
 88         }
 89         if (nrFrames <= 0)
 90         {
 91             cerr << "Invalid number of frames " << nrFrames << endl;
 92             goodInput = false;
 93         }
 94 
 95         if (input.empty())      // Check for valid input
 96                 inputType = INVALID;
 97         else
 98         {
 99             if (input[0] >= '0' && input[0] <= '9')
100             {
101                 stringstream ss(input);
102                 ss >> cameraID;
103                 inputType = CAMERA;
104             }
105             else
106             {
107                 if (isListOfImages(input) && readStringList(input, imageList))
108                 {
109                     inputType = IMAGE_LIST;
110                     nrFrames = (nrFrames < (int)imageList.size()) ? nrFrames : (int)imageList.size();
111                 }
112                 else
113                     inputType = VIDEO_FILE;
114             }
115             if (inputType == CAMERA)
116                 inputCapture.open(cameraID);
117             if (inputType == VIDEO_FILE)
118                 inputCapture.open(input);
119             if (inputType != IMAGE_LIST && !inputCapture.isOpened())
120                     inputType = INVALID;
121         }
122         if (inputType == INVALID)
123         {
124             cerr << " Input does not exist: " << input;
125             goodInput = false;
126         }
127 
128         flag = 0;
129         if(calibFixPrincipalPoint) flag |= CALIB_FIX_PRINCIPAL_POINT;
130         if(calibZeroTangentDist)   flag |= CALIB_ZERO_TANGENT_DIST;
131         if(aspectRatio)            flag |= CALIB_FIX_ASPECT_RATIO;
132         if(fixK1)                  flag |= CALIB_FIX_K1;
133         if(fixK2)                  flag |= CALIB_FIX_K2;
134         if(fixK3)                  flag |= CALIB_FIX_K3;
135         if(fixK4)                  flag |= CALIB_FIX_K4;
136         if(fixK5)                  flag |= CALIB_FIX_K5;
137 
138         if (useFisheye) {
139             // the fisheye model has its own enum, so overwrite the flags
140             flag = fisheye::CALIB_FIX_SKEW | fisheye::CALIB_RECOMPUTE_EXTRINSIC;
141             if(fixK1)                   flag |= fisheye::CALIB_FIX_K1;
142             if(fixK2)                   flag |= fisheye::CALIB_FIX_K2;
143             if(fixK3)                   flag |= fisheye::CALIB_FIX_K3;
144             if(fixK4)                   flag |= fisheye::CALIB_FIX_K4;
145             if (calibFixPrincipalPoint) flag |= fisheye::CALIB_FIX_PRINCIPAL_POINT;
146         }
147 
148         calibrationPattern = NOT_EXISTING;
149         if (!patternToUse.compare("CHESSBOARD")) calibrationPattern = CHESSBOARD;
150         if (!patternToUse.compare("CIRCLES_GRID")) calibrationPattern = CIRCLES_GRID;
151         if (!patternToUse.compare("ASYMMETRIC_CIRCLES_GRID")) calibrationPattern = ASYMMETRIC_CIRCLES_GRID;
152         if (calibrationPattern == NOT_EXISTING)
153         {
154             cerr << " Camera calibration mode does not exist: " << patternToUse << endl;
155             goodInput = false;
156         }
157         atImageList = 0;
158 
159     }
160     Mat nextImage()
161     {
162         Mat result;
163         if( inputCapture.isOpened() )
164         {
165             Mat view0;
166             inputCapture >> view0;
167             view0.copyTo(result);
168         }
169         else if( atImageList < imageList.size() )
170             result = imread(imageList[atImageList++], IMREAD_COLOR);
171 
172         return result;
173     }
174 
175     static bool readStringList( const string& filename, vector<string>& l )
176     {
177         l.clear();
178         FileStorage fs(filename, FileStorage::READ);
179         if( !fs.isOpened() )
180             return false;
181         FileNode n = fs.getFirstTopLevelNode();
182         if( n.type() != FileNode::SEQ )
183             return false;
184         FileNodeIterator it = n.begin(), it_end = n.end();
185         for( ; it != it_end; ++it )
186             l.push_back((string)*it);
187         return true;
188     }
189 
190     static bool isListOfImages( const string& filename)
191     {
192         string s(filename);
193         // Look for file extension
194         if( s.find(".xml") == string::npos && s.find(".yaml") == string::npos && s.find(".yml") == string::npos )
195             return false;
196         else
197             return true;
198     }
199 public:
200     Size boardSize;              // The size of the board -> Number of items by width and height
201     Pattern calibrationPattern;  // One of the Chessboard, circles, or asymmetric circle pattern
202     float squareSize;            // The size of a square in your defined unit (point, millimeter,etc).
203     int nrFrames;                // The number of frames to use from the input for calibration
204     float aspectRatio;           // The aspect ratio
205     int delay;                   // In case of a video input
206     bool writePoints;            // Write detected feature points
207     bool writeExtrinsics;        // Write extrinsic parameters
208     bool writeGrid;              // Write refined 3D target grid points
209     bool calibZeroTangentDist;   // Assume zero tangential distortion
210     bool calibFixPrincipalPoint; // Fix the principal point at the center
211     bool flipVertical;           // Flip the captured images around the horizontal axis
212     string outputFileName;       // The name of the file where to write
213     bool showUndistorsed;        // Show undistorted images after calibration
214     string input;                // The input ->
215     bool useFisheye;             // use fisheye camera model for calibration
216     bool fixK1;                  // fix K1 distortion coefficient
217     bool fixK2;                  // fix K2 distortion coefficient
218     bool fixK3;                  // fix K3 distortion coefficient
219     bool fixK4;                  // fix K4 distortion coefficient
220     bool fixK5;                  // fix K5 distortion coefficient
221 
222     int cameraID;
223     vector<string> imageList;
224     size_t atImageList;
225     VideoCapture inputCapture;
226     InputType inputType;
227     bool goodInput;
228     int flag;
229 
230 private:
231     string patternToUse;
232 
233 
234 };
235 
236 static inline void read(const FileNode& node, Settings& x, const Settings& default_value = Settings())
237 {
238     if(node.empty())
239         x = default_value;
240     else
241         x.read(node);
242 }
243 
244 enum { DETECTION = 0, CAPTURING = 1, CALIBRATED = 2 };
245 
246 bool runCalibrationAndSave(Settings& s, Size imageSize, Mat&  cameraMatrix, Mat& distCoeffs,
247                            vector<vector<Point2f> > imagePoints, float grid_width, bool release_object);
248 
249 int main(int argc, char* argv[])
250 {
251     const String keys
252         = "{help h usage ? |           | print this message            }"
253           "{@settings      |default.xml| input setting file            }"
254           "{d              |           | actual distance between top-left and top-right corners of "
255           "the calibration grid }"
256           "{winSize        | 11        | Half of search window for cornerSubPix }";
257     CommandLineParser parser(argc, argv, keys);
258     parser.about("This is a camera calibration sample.\n"
259                  "Usage: camera_calibration [configuration_file -- default ./default.xml]\n"
260                  "Near the sample file you'll find the configuration file, which has detailed help of "
261                  "how to edit it. It may be any OpenCV supported file format XML/YAML.");
262     if (!parser.check()) {
263         parser.printErrors();
264         return 0;
265     }
266 
267     if (parser.has("help")) {
268         parser.printMessage();
269         return 0;
270     }
271 
272     //! [file_read]
273     Settings s;
274     const string inputSettingsFile = parser.get<string>(0);
275     FileStorage fs(inputSettingsFile, FileStorage::READ); // Read the settings
276     if (!fs.isOpened())
277     {
278         cout << "Could not open the configuration file: \"" << inputSettingsFile << "\"" << endl;
279         parser.printMessage();
280         return -1;
281     }
282     fs["Settings"] >> s;
283     fs.release();                                         // close Settings file
284     //! [file_read]
285 
286     //FileStorage fout("settings.yml", FileStorage::WRITE); // write config as YAML
287     //fout << "Settings" << s;
288 
289     if (!s.goodInput)
290     {
291         cout << "Invalid input detected. Application stopping. " << endl;
292         return -1;
293     }
294 
295     int winSize = parser.get<int>("winSize");
296 
297     float grid_width = s.squareSize * (s.boardSize.width - 1);
298     bool release_object = false;
299     if (parser.has("d")) {
300         grid_width = parser.get<float>("d");
301         release_object = true;
302     }
303 
304     vector<vector<Point2f> > imagePoints;
305     Mat cameraMatrix, distCoeffs;
306     Size imageSize;
307     int mode = s.inputType == Settings::IMAGE_LIST ? CAPTURING : DETECTION;
308     clock_t prevTimestamp = 0;
309     const Scalar RED(0,0,255), GREEN(0,255,0);
310     const char ESC_KEY = 27;
311 
312     //! [get_input]
313     for(;;)
314     {
315         Mat view;
316         bool blinkOutput = false;
317 
318         view = s.nextImage();
319 
320         //-----  If no more image, or got enough, then stop calibration and show result -------------
321         if( mode == CAPTURING && imagePoints.size() >= (size_t)s.nrFrames )
322         {
323           if(runCalibrationAndSave(s, imageSize,  cameraMatrix, distCoeffs, imagePoints, grid_width,
324                                    release_object))
325               mode = CALIBRATED;
326           else
327               mode = DETECTION;
328         }
329         if(view.empty())          // If there are no more images stop the loop
330         {
331             // if calibration threshold was not reached yet, calibrate now
332             if( mode != CALIBRATED && !imagePoints.empty() )
333                 runCalibrationAndSave(s, imageSize,  cameraMatrix, distCoeffs, imagePoints, grid_width,
334                                       release_object);
335             break;
336         }
337         //! [get_input]
338 
339         imageSize = view.size();  // Format input image.
340         if( s.flipVertical )    flip( view, view, 0 );
341 
342         //! [find_pattern]
343         vector<Point2f> pointBuf;
344 
345         bool found;
346 
347         int chessBoardFlags = CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE;
348 
349         if(!s.useFisheye) {
350             // fast check erroneously fails with high distortions like fisheye
351             chessBoardFlags |= CALIB_CB_FAST_CHECK;
352         }
353 
354         switch( s.calibrationPattern ) // Find feature points on the input format
355         {
356         case Settings::CHESSBOARD:
357             found = findChessboardCorners( view, s.boardSize, pointBuf, chessBoardFlags);
358             break;
359         case Settings::CIRCLES_GRID:
360             found = findCirclesGrid( view, s.boardSize, pointBuf );
361             break;
362         case Settings::ASYMMETRIC_CIRCLES_GRID:
363             found = findCirclesGrid( view, s.boardSize, pointBuf, CALIB_CB_ASYMMETRIC_GRID );
364             break;
365         default:
366             found = false;
367             break;
368         }
369         //! [find_pattern]
370         //! [pattern_found]
371         if ( found)                // If done with success,
372         {
373               // improve the found corners' coordinate accuracy for chessboard
374                 if( s.calibrationPattern == Settings::CHESSBOARD)
375                 {
376                     Mat viewGray;
377                     cvtColor(view, viewGray, COLOR_BGR2GRAY);
378                     cornerSubPix( viewGray, pointBuf, Size(winSize,winSize),
379                         Size(-1,-1), TermCriteria( TermCriteria::EPS+TermCriteria::COUNT, 30, 0.0001 ));
380                 }
381 
382                 if( mode == CAPTURING &&  // For camera only take new samples after delay time
383                     (!s.inputCapture.isOpened() || clock() - prevTimestamp > s.delay*1e-3*CLOCKS_PER_SEC) )
384                 {
385                     imagePoints.push_back(pointBuf);
386                     prevTimestamp = clock();
387                     blinkOutput = s.inputCapture.isOpened();
388                 }
389 
390                 // Draw the corners.
391                 drawChessboardCorners( view, s.boardSize, Mat(pointBuf), found );
392         }
393         //! [pattern_found]
394         //----------------------------- Output Text ------------------------------------------------
395         //! [output_text]
396         string msg = (mode == CAPTURING) ? "100/100" :
397                       mode == CALIBRATED ? "Calibrated" : "Press 'g' to start";
398         int baseLine = 0;
399         Size textSize = getTextSize(msg, 1, 1, 1, &baseLine);
400         Point textOrigin(view.cols - 2*textSize.width - 10, view.rows - 2*baseLine - 10);
401 
402         if( mode == CAPTURING )
403         {
404             if(s.showUndistorsed)
405                 msg = format( "%d/%d Undist", (int)imagePoints.size(), s.nrFrames );
406             else
407                 msg = format( "%d/%d", (int)imagePoints.size(), s.nrFrames );
408         }
409 
410         putText( view, msg, textOrigin, 1, 1, mode == CALIBRATED ?  GREEN : RED);
411 
412         if( blinkOutput )
413             bitwise_not(view, view);
414         //! [output_text]
415         //------------------------- Video capture  output  undistorted ------------------------------
416         //! [output_undistorted]
417         if( mode == CALIBRATED && s.showUndistorsed )
418         {
419             Mat temp = view.clone();
420             if (s.useFisheye)
421               cv::fisheye::undistortImage(temp, view, cameraMatrix, distCoeffs);
422             else
423               undistort(temp, view, cameraMatrix, distCoeffs);
424         }
425         //! [output_undistorted]
426         //------------------------------ Show image and check for input commands -------------------
427         //! [await_input]
428         imshow("Image View", view);
429         char key = (char)waitKey(s.inputCapture.isOpened() ? 50 : s.delay);
430 
431         if( key  == ESC_KEY )
432             break;
433 
434         if( key == 'u' && mode == CALIBRATED )
435            s.showUndistorsed = !s.showUndistorsed;
436 
437         if( s.inputCapture.isOpened() && key == 'g' )
438         {
439             mode = CAPTURING;
440             imagePoints.clear();
441         }
442         //! [await_input]
443     }
444 
445     // -----------------------Show the undistorted image for the image list ------------------------
446     //! [show_results]
447     if( s.inputType == Settings::IMAGE_LIST && s.showUndistorsed )
448     {
449         Mat view, rview, map1, map2;
450 
451         if (s.useFisheye)
452         {
453             Mat newCamMat;
454             fisheye::estimateNewCameraMatrixForUndistortRectify(cameraMatrix, distCoeffs, imageSize,
455                                                                 Matx33d::eye(), newCamMat, 1);
456             fisheye::initUndistortRectifyMap(cameraMatrix, distCoeffs, Matx33d::eye(), newCamMat, imageSize,
457                                              CV_16SC2, map1, map2);
458         }
459         else
460         {
461             initUndistortRectifyMap(
462                 cameraMatrix, distCoeffs, Mat(),
463                 getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0), imageSize,
464                 CV_16SC2, map1, map2);
465         }
466 
467         for(size_t i = 0; i < s.imageList.size(); i++ )
468         {
469             view = imread(s.imageList[i], IMREAD_COLOR);
470             if(view.empty())
471                 continue;
472             remap(view, rview, map1, map2, INTER_LINEAR);
473             imshow("Image View", rview);
474             char c = (char)waitKey();
475             if( c  == ESC_KEY || c == 'q' || c == 'Q' )
476                 break;
477         }
478     }
479     //! [show_results]
480 
481     return 0;
482 }
483 
484 //! [compute_errors]
485 static double computeReprojectionErrors( const vector<vector<Point3f> >& objectPoints,
486                                          const vector<vector<Point2f> >& imagePoints,
487                                          const vector<Mat>& rvecs, const vector<Mat>& tvecs,
488                                          const Mat& cameraMatrix , const Mat& distCoeffs,
489                                          vector<float>& perViewErrors, bool fisheye)
490 {
491     vector<Point2f> imagePoints2;
492     size_t totalPoints = 0;
493     double totalErr = 0, err;
494     perViewErrors.resize(objectPoints.size());
495 
496     for(size_t i = 0; i < objectPoints.size(); ++i )
497     {
498         if (fisheye)
499         {
500             fisheye::projectPoints(objectPoints[i], imagePoints2, rvecs[i], tvecs[i], cameraMatrix,
501                                    distCoeffs);
502         }
503         else
504         {
505             projectPoints(objectPoints[i], rvecs[i], tvecs[i], cameraMatrix, distCoeffs, imagePoints2);
506         }
507         err = norm(imagePoints[i], imagePoints2, NORM_L2);
508 
509         size_t n = objectPoints[i].size();
510         perViewErrors[i] = (float) std::sqrt(err*err/n);
511         totalErr        += err*err;
512         totalPoints     += n;
513     }
514 
515     return std::sqrt(totalErr/totalPoints);
516 }
517 //! [compute_errors]
518 //! [board_corners]
519 static void calcBoardCornerPositions(Size boardSize, float squareSize, vector<Point3f>& corners,
520                                      Settings::Pattern patternType /*= Settings::CHESSBOARD*/)
521 {
522     corners.clear();
523 
524     switch(patternType)
525     {
526     case Settings::CHESSBOARD:
527     case Settings::CIRCLES_GRID:
528         for( int i = 0; i < boardSize.height; ++i )
529             for( int j = 0; j < boardSize.width; ++j )
530                 corners.push_back(Point3f(j*squareSize, i*squareSize, 0));
531         break;
532 
533     case Settings::ASYMMETRIC_CIRCLES_GRID:
534         for( int i = 0; i < boardSize.height; i++ )
535             for( int j = 0; j < boardSize.width; j++ )
536                 corners.push_back(Point3f((2*j + i % 2)*squareSize, i*squareSize, 0));
537         break;
538     default:
539         break;
540     }
541 }
542 //! [board_corners]
543 static bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs,
544                             vector<vector<Point2f> > imagePoints, vector<Mat>& rvecs, vector<Mat>& tvecs,
545                             vector<float>& reprojErrs,  double& totalAvgErr, vector<Point3f>& newObjPoints,
546                             float grid_width, bool release_object)
547 {
548     //! [fixed_aspect]
549     cameraMatrix = Mat::eye(3, 3, CV_64F);
550     if( s.flag & CALIB_FIX_ASPECT_RATIO )
551         cameraMatrix.at<double>(0,0) = s.aspectRatio;
552     //! [fixed_aspect]
553     if (s.useFisheye) {
554         distCoeffs = Mat::zeros(4, 1, CV_64F);
555     } else {
556         distCoeffs = Mat::zeros(8, 1, CV_64F);
557     }
558 
559     vector<vector<Point3f> > objectPoints(1);
560     calcBoardCornerPositions(s.boardSize, s.squareSize, objectPoints[0], s.calibrationPattern);
561     objectPoints[0][s.boardSize.width - 1].x = objectPoints[0][0].x + grid_width;
562     newObjPoints = objectPoints[0];
563 
564     objectPoints.resize(imagePoints.size(),objectPoints[0]);
565 
566     //Find intrinsic and extrinsic camera parameters
567     double rms;
568 
569     if (s.useFisheye) {
570         Mat _rvecs, _tvecs;
571         rms = fisheye::calibrate(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, _rvecs,
572                                  _tvecs, s.flag);
573 
574         rvecs.reserve(_rvecs.rows);
575         tvecs.reserve(_tvecs.rows);
576         for(int i = 0; i < int(objectPoints.size()); i++){
577             rvecs.push_back(_rvecs.row(i));
578             tvecs.push_back(_tvecs.row(i));
579         }
580     } else {
581         int iFixedPoint = -1;
582         if (release_object)
583             iFixedPoint = s.boardSize.width - 1;
584         rms = calibrateCameraRO(objectPoints, imagePoints, imageSize, iFixedPoint,
585                                 cameraMatrix, distCoeffs, rvecs, tvecs, newObjPoints,
586                                 s.flag | CALIB_USE_LU);
587     }
588 
589     if (release_object) {
590         cout << "New board corners: " << endl;
591         cout << newObjPoints[0] << endl;
592         cout << newObjPoints[s.boardSize.width - 1] << endl;
593         cout << newObjPoints[s.boardSize.width * (s.boardSize.height - 1)] << endl;
594         cout << newObjPoints.back() << endl;
595     }
596 
597     cout << "Re-projection error reported by calibrateCamera: "<< rms << endl;
598 
599     bool ok = checkRange(cameraMatrix) && checkRange(distCoeffs);
600 
601     objectPoints.clear();
602     objectPoints.resize(imagePoints.size(), newObjPoints);
603     totalAvgErr = computeReprojectionErrors(objectPoints, imagePoints, rvecs, tvecs, cameraMatrix,
604                                             distCoeffs, reprojErrs, s.useFisheye);
605 
606     return ok;
607 }
608 
609 // Print camera parameters to the output file
610 static void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs,
611                               const vector<Mat>& rvecs, const vector<Mat>& tvecs,
612                               const vector<float>& reprojErrs, const vector<vector<Point2f> >& imagePoints,
613                               double totalAvgErr, const vector<Point3f>& newObjPoints )
614 {
615     FileStorage fs( s.outputFileName, FileStorage::WRITE );
616 
617     time_t tm;
618     time( &tm );
619     struct tm *t2 = localtime( &tm );
620     char buf[1024];
621     strftime( buf, sizeof(buf), "%c", t2 );
622 
623     fs << "calibration_time" << buf;
624 
625     if( !rvecs.empty() || !reprojErrs.empty() )
626         fs << "nr_of_frames" << (int)std::max(rvecs.size(), reprojErrs.size());
627     fs << "image_width" << imageSize.width;
628     fs << "image_height" << imageSize.height;
629     fs << "board_width" << s.boardSize.width;
630     fs << "board_height" << s.boardSize.height;
631     fs << "square_size" << s.squareSize;
632 
633     if( s.flag & CALIB_FIX_ASPECT_RATIO )
634         fs << "fix_aspect_ratio" << s.aspectRatio;
635 
636     if (s.flag)
637     {
638         std::stringstream flagsStringStream;
639         if (s.useFisheye)
640         {
641             flagsStringStream << "flags:"
642                 << (s.flag & fisheye::CALIB_FIX_SKEW ? " +fix_skew" : "")
643                 << (s.flag & fisheye::CALIB_FIX_K1 ? " +fix_k1" : "")
644                 << (s.flag & fisheye::CALIB_FIX_K2 ? " +fix_k2" : "")
645                 << (s.flag & fisheye::CALIB_FIX_K3 ? " +fix_k3" : "")
646                 << (s.flag & fisheye::CALIB_FIX_K4 ? " +fix_k4" : "")
647                 << (s.flag & fisheye::CALIB_RECOMPUTE_EXTRINSIC ? " +recompute_extrinsic" : "");
648         }
649         else
650         {
651             flagsStringStream << "flags:"
652                 << (s.flag & CALIB_USE_INTRINSIC_GUESS ? " +use_intrinsic_guess" : "")
653                 << (s.flag & CALIB_FIX_ASPECT_RATIO ? " +fix_aspectRatio" : "")
654                 << (s.flag & CALIB_FIX_PRINCIPAL_POINT ? " +fix_principal_point" : "")
655                 << (s.flag & CALIB_ZERO_TANGENT_DIST ? " +zero_tangent_dist" : "")
656                 << (s.flag & CALIB_FIX_K1 ? " +fix_k1" : "")
657                 << (s.flag & CALIB_FIX_K2 ? " +fix_k2" : "")
658                 << (s.flag & CALIB_FIX_K3 ? " +fix_k3" : "")
659                 << (s.flag & CALIB_FIX_K4 ? " +fix_k4" : "")
660                 << (s.flag & CALIB_FIX_K5 ? " +fix_k5" : "");
661         }
662         fs.writeComment(flagsStringStream.str());
663     }
664 
665     fs << "flags" << s.flag;
666 
667     fs << "fisheye_model" << s.useFisheye;
668 
669     fs << "camera_matrix" << cameraMatrix;
670     fs << "distortion_coefficients" << distCoeffs;
671 
672     fs << "avg_reprojection_error" << totalAvgErr;
673     if (s.writeExtrinsics && !reprojErrs.empty())
674         fs << "per_view_reprojection_errors" << Mat(reprojErrs);
675 
676     if(s.writeExtrinsics && !rvecs.empty() && !tvecs.empty() )
677     {
678         CV_Assert(rvecs[0].type() == tvecs[0].type());
679         Mat bigmat((int)rvecs.size(), 6, CV_MAKETYPE(rvecs[0].type(), 1));
680         bool needReshapeR = rvecs[0].depth() != 1 ? true : false;
681         bool needReshapeT = tvecs[0].depth() != 1 ? true : false;
682 
683         for( size_t i = 0; i < rvecs.size(); i++ )
684         {
685             Mat r = bigmat(Range(int(i), int(i+1)), Range(0,3));
686             Mat t = bigmat(Range(int(i), int(i+1)), Range(3,6));
687 
688             if(needReshapeR)
689                 rvecs[i].reshape(1, 1).copyTo(r);
690             else
691             {
692                 //*.t() is MatExpr (not Mat) so we can use assignment operator
693                 CV_Assert(rvecs[i].rows == 3 && rvecs[i].cols == 1);
694                 r = rvecs[i].t();
695             }
696 
697             if(needReshapeT)
698                 tvecs[i].reshape(1, 1).copyTo(t);
699             else
700             {
701                 CV_Assert(tvecs[i].rows == 3 && tvecs[i].cols == 1);
702                 t = tvecs[i].t();
703             }
704         }
705         fs.writeComment("a set of 6-tuples (rotation vector + translation vector) for each view");
706         fs << "extrinsic_parameters" << bigmat;
707     }
708 
709     if(s.writePoints && !imagePoints.empty() )
710     {
711         Mat imagePtMat((int)imagePoints.size(), (int)imagePoints[0].size(), CV_32FC2);
712         for( size_t i = 0; i < imagePoints.size(); i++ )
713         {
714             Mat r = imagePtMat.row(int(i)).reshape(2, imagePtMat.cols);
715             Mat imgpti(imagePoints[i]);
716             imgpti.copyTo(r);
717         }
718         fs << "image_points" << imagePtMat;
719     }
720 
721     if( s.writeGrid && !newObjPoints.empty() )
722     {
723         fs << "grid_points" << newObjPoints;
724     }
725 }
726 
727 //! [run_and_save]
728 bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,
729                            vector<vector<Point2f> > imagePoints, float grid_width, bool release_object)
730 {
731     vector<Mat> rvecs, tvecs;
732     vector<float> reprojErrs;
733     double totalAvgErr = 0;
734     vector<Point3f> newObjPoints;
735 
736     bool ok = runCalibration(s, imageSize, cameraMatrix, distCoeffs, imagePoints, rvecs, tvecs, reprojErrs,
737                              totalAvgErr, newObjPoints, grid_width, release_object);
738     cout << (ok ? "Calibration succeeded" : "Calibration failed")
739          << ". avg re projection error = " << totalAvgErr << endl;
740 
741     if (ok)
742         saveCameraParams(s, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, reprojErrs, imagePoints,
743                          totalAvgErr, newObjPoints);
744     return ok;
745 }
746 //! [run_and_save]
View Code

VID5.xml (外部配置文件,包括了待标定相机采集图像的绝对路径或者相对路径)

<?xml version="1.0"?>
<opencv_storage>
<images>
images/CameraCalibraation/VID5/xx1.jpg
images/CameraCalibraation/VID5/xx2.jpg
images/CameraCalibraation/VID5/xx3.jpg
images/CameraCalibraation/VID5/xx4.jpg
images/CameraCalibraation/VID5/xx5.jpg
images/CameraCalibraation/VID5/xx6.jpg
images/CameraCalibraation/VID5/xx7.jpg
images/CameraCalibraation/VID5/xx8.jpg
</images>
</opencv_storage>
View Code

in_VID5.xml (标定基本参数配置,包括了标定的模式,图像样本的获取方式等等)

<?xml version="1.0"?>
<opencv_storage>
<Settings>
  <!-- Number of inner corners per a item row and column. (square, circle) -->
  <BoardSize_Width> 9</BoardSize_Width>
  <BoardSize_Height>6</BoardSize_Height>
  
  <!-- The size of a square in some user defined metric system (pixel, millimeter)-->
  <Square_Size>50</Square_Size>
  
  <!-- The type of input used for camera calibration. One of: CHESSBOARD CIRCLES_GRID ASYMMETRIC_CIRCLES_GRID -->
  <Calibrate_Pattern>"CHESSBOARD"</Calibrate_Pattern>
  
  <!-- The input to use for calibration. 
        To use an input camera -> give the ID of the camera, like "1"
        To use an input video  -> give the path of the input video, like "/tmp/x.avi"
        To use an image list   -> give the path to the XML or YAML file containing the list of the images, like "/tmp/circles_list.xml"
        -->
  <Input>"images/CameraCalibration/VID5/VID5.xml"</Input>
  <!--  If true (non-zero) we flip the input images around the horizontal axis.-->
  <Input_FlipAroundHorizontalAxis>0</Input_FlipAroundHorizontalAxis>
  
  <!-- Time delay between frames in case of camera. -->
  <Input_Delay>100</Input_Delay>    
  
  <!-- How many frames to use, for calibration. -->
  <Calibrate_NrOfFrameToUse>25</Calibrate_NrOfFrameToUse>
  <!-- Consider only fy as a free parameter, the ratio fx/fy stays the same as in the input cameraMatrix. 
       Use or not setting. 0 - False Non-Zero - True-->
  <Calibrate_FixAspectRatio> 1 </Calibrate_FixAspectRatio>
  <!-- If true (non-zero) tangential distortion coefficients  are set to zeros and stay zero.-->
  <Calibrate_AssumeZeroTangentialDistortion>1</Calibrate_AssumeZeroTangentialDistortion>
  <!-- If true (non-zero) the principal point is not changed during the global optimization.-->
  <Calibrate_FixPrincipalPointAtTheCenter> 1 </Calibrate_FixPrincipalPointAtTheCenter>
  
  <!-- The name of the output log file. -->
  <Write_outputFileName>"out_camera_data.xml"</Write_outputFileName>
  <!-- If true (non-zero) we write to the output file the feature points.-->
  <Write_DetectedFeaturePoints>1</Write_DetectedFeaturePoints>
  <!-- If true (non-zero) we write to the output file the extrinsic camera parameters.-->
  <Write_extrinsicParameters>1</Write_extrinsicParameters>
  <!-- If true (non-zero) we write to the output file the refined 3D target grid points.-->
  <Write_gridPoints>1</Write_gridPoints>
  <!-- If true (non-zero) we show after calibration the undistorted images.-->
  <Show_UndistortedImage>1</Show_UndistortedImage>
  <!-- If true (non-zero) will be used fisheye camera model.-->
  <Calibrate_UseFisheyeModel>0</Calibrate_UseFisheyeModel>
  <!-- If true (non-zero) distortion coefficient k1 will be equals to zero.-->
  <Fix_K1>0</Fix_K1>
  <!-- If true (non-zero) distortion coefficient k2 will be equals to zero.-->
  <Fix_K2>0</Fix_K2>
  <!-- If true (non-zero) distortion coefficient k3 will be equals to zero.-->
  <Fix_K3>0</Fix_K3>
  <!-- If true (non-zero) distortion coefficient k4 will be equals to zero.-->
  <Fix_K4>1</Fix_K4>
  <!-- If true (non-zero) distortion coefficient k5 will be equals to zero.-->
  <Fix_K5>1</Fix_K5>
</Settings>
</opencv_storage>
View Code

out_camera_data.yml (主程序输出保存的相机基本参数,以方便下次相机的使用)

%YAML:1.0
calibration_Time: "08/19/11 20:44:38"
nrOfFrames: 8
image_Width: 640
image_Height: 480
board_Width: 9
board_Height: 6
square_Size: 50.
FixAspectRatio: 1.
# flags:  +fix_aspectRatio +fix_principal_point +zero_tangent_dist
flagValue: 14
Camera_Matrix: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [ 6.5746697810243404e+002, 0., 3.1950000000000000e+002, 0.,
       6.5746697810243404e+002, 2.3950000000000000e+002, 0., 0., 1. ]
Distortion_Coefficients: !!opencv-matrix
   rows: 5
   cols: 1
   dt: d
   data: [ -4.1802327018241026e-001, 5.0715243805833121e-001, 0., 0.,
       -5.7843596847939704e-001 ]
Avg_Reprojection_Error: 3.8441346462381665e-001
Per_View_Reprojection_Errors: !!opencv-matrix
   rows: 8
   cols: 1
   dt: f
   data: [ 5.04357755e-001, 4.85754758e-001, 3.99563968e-001,
       4.13829178e-001, 3.53570908e-001, 3.21116358e-001,
       2.74473161e-001, 2.39761785e-001 ]
# a set of 6-tuples (rotation vector + translation vector) for each view
Extrinsic_Parameters: !!opencv-matrix
   rows: 8
   cols: 6
   dt: d
   data: [ -7.8704123655486097e-002, -1.5922384772614945e-001,
       3.1166227207451498e+000, 2.4224388101960471e+002,
       1.1795590397660339e+002, 6.2576484126093249e+002,
       -1.4117480285164308e-001, -1.7917415443804836e-002,
       3.1333182268743949e+000, 2.5943034781849354e+002,
       1.4039780562976958e+002, 6.3848706527260981e+002,
       7.2230525186138789e-002, -7.5445981266787754e-002,
       1.5712860749221762e+000, 1.7426560451795339e+002,
       -1.9309240362258871e+002, 7.0891416556762647e+002,
       2.0367310600105853e-002, 6.8565520026996951e-002,
       -5.4313033031644169e-004, -2.0146314940404827e+002,
       -1.3305643514116997e+002, 7.4933554744027231e+002,
       -3.4468530027734055e-002, 2.1921265175331925e-002,
       -1.5731053528054522e+000, -1.1155718744299284e+002,
       2.0307615364261443e+002, 8.4915903914333899e+002,
       3.7425562109513817e-002, 7.4883169379022230e-002,
       -3.6031632305130512e-002, -2.0094505419395196e+002,
       -1.1627359108310560e+002, 9.2021583518760133e+002,
       6.8105689976949157e-002, 6.4426739692440949e-002,
       -7.0967130057087435e-002, -1.9233852871740035e+002,
       -1.0334652096641923e+002, 1.0755293563503658e+003,
       -5.8017546499862287e-002, -1.6909812666033443e-003,
       -1.5876137659782963e+000, -1.0242234847115104e+002,
       2.2583088401423066e+002, 1.1125972190244058e+003 ]
Image_points: !!opencv-matrix
   rows: 8
   cols: 54
   dt: "2f"
   data: [ 5.58494690e+002, 3.55650085e+002, 5.13314697e+002,
       3.59107666e+002, 4.65728333e+002, 3.62133911e+002,
       4.15701111e+002, 3.65026459e+002, 3.64399353e+002,
       3.67339203e+002, 3.12101196e+002, 3.69211914e+002,
       2.59208405e+002, 3.70413513e+002, 2.07456192e+002,
       3.71175995e+002, 1.56619507e+002, 3.72176544e+002,
       5.60868713e+002, 3.08104828e+002, 5.15191772e+002,
       3.10485626e+002, 4.67032959e+002, 3.12660004e+002,
       4.16112152e+002, 3.14887177e+002, 3.64010712e+002,
       3.16825775e+002, 3.10712372e+002, 3.18640808e+002,
       2.56853943e+002, 3.20017365e+002, 2.04168182e+002,
       3.20908417e+002, 1.52469528e+002, 3.22105377e+002,
       5.62328369e+002, 2.58646881e+002, 5.16396301e+002,
       2.59919281e+002, 4.67907654e+002, 2.61257874e+002,
       4.16463440e+002, 2.62675537e+002, 3.63546570e+002,
       2.64064117e+002, 3.09528137e+002, 2.65489990e+002,
       2.54765533e+002, 2.66862030e+002, 2.01299225e+002,
       2.67997345e+002, 1.48913437e+002, 2.69627167e+002,
       5.63098022e+002, 2.08423523e+002, 5.16782654e+002,
       2.08424667e+002, 4.68059296e+002, 2.08661697e+002,
       4.16216431e+002, 2.09268982e+002, 3.62888763e+002,
       2.10013397e+002, 3.08458557e+002, 2.11074738e+002,
       2.53267990e+002, 2.12496582e+002, 1.99121384e+002,
       2.14005814e+002, 1.46551376e+002, 2.15851318e+002,
       5.62997437e+002, 1.57966492e+002, 5.16406494e+002,
       1.56580688e+002, 4.67334900e+002, 1.55756500e+002,
       4.15378235e+002, 1.55492874e+002, 3.62096710e+002,
       1.55498734e+002, 3.07522827e+002, 1.56133240e+002,
       2.52235214e+002, 1.57516571e+002, 1.97876328e+002,
       1.59318787e+002, 1.45078247e+002, 1.61638428e+002,
       5.62097168e+002, 1.07469536e+002, 5.15766846e+002,
       1.04902527e+002, 4.66562866e+002, 1.03045807e+002,
       4.14651459e+002, 1.01924713e+002, 3.61240662e+002,
       1.01357826e+002, 3.06746613e+002, 1.01582802e+002,
       2.51568024e+002, 1.02920105e+002, 1.97343307e+002,
       1.04941299e+002, 1.44756821e+002, 1.07737488e+002,
       5.68062500e+002, 3.73591125e+002, 5.25272644e+002,
       3.77019318e+002, 4.79870941e+002, 3.80086578e+002,
       4.31823730e+002, 3.83036652e+002, 3.81995758e+002,
       3.85271759e+002, 3.30728729e+002, 3.86998779e+002,
       2.78071167e+002, 3.88151031e+002, 2.26231567e+002,
       3.88669586e+002, 1.74855331e+002, 3.89197998e+002,
       5.69792542e+002, 3.27097382e+002, 5.26866028e+002,
       3.29362366e+002, 4.81278229e+002, 3.31532928e+002,
       4.32783203e+002, 3.33552185e+002, 3.82408234e+002,
       3.35186554e+002, 3.30427399e+002, 3.36404053e+002,
       2.77138519e+002, 3.37450958e+002, 2.24525131e+002,
       3.37957092e+002, 1.72285507e+002, 3.38503540e+002,
       5.70942749e+002, 2.79243713e+002, 5.27789307e+002,
       2.80073486e+002, 4.82146576e+002, 2.81226410e+002,
       4.33247375e+002, 2.82237427e+002, 3.82503662e+002,
       2.83062286e+002, 3.30138885e+002, 2.83794434e+002,
       2.76433228e+002, 2.84549286e+002, 2.23158783e+002,
       2.84981049e+002, 1.70520218e+002, 2.85720886e+002,
       5.71001953e+002, 2.30928329e+002, 5.27846863e+002,
       2.30519928e+002, 4.82114563e+002, 2.30268906e+002,
       4.33114563e+002, 2.30243515e+002, 3.82384857e+002,
       2.30311340e+002, 3.29870392e+002, 2.30454620e+002,
       2.76012634e+002, 2.30882156e+002, 2.22529434e+002,
       2.31355362e+002, 1.69742065e+002, 2.32063004e+002,
       5.70199036e+002, 1.82609772e+002, 5.27030884e+002,
       1.80973267e+002, 4.81193573e+002, 1.79573792e+002,
       4.32409821e+002, 1.78475616e+002, 3.81855530e+002,
       1.77680283e+002, 3.29641937e+002, 1.77092087e+002,
       2.75895782e+002, 1.77155502e+002, 2.22438889e+002,
       1.77605667e+002, 1.69884583e+002, 1.78365585e+002,
       5.69026245e+002, 1.34654831e+002, 5.26171570e+002,
       1.31798691e+002, 4.80653503e+002, 1.29171509e+002,
       4.31869904e+002, 1.27280067e+002, 3.81419739e+002,
       1.25591202e+002, 3.29466644e+002, 1.24407089e+002,
       2.76225342e+002, 1.24174736e+002, 2.23024109e+002,
       1.24463333e+002, 1.70838898e+002, 1.25398903e+002,
       4.73812897e+002, 6.94673386e+001, 4.74245453e+002,
       1.12387466e+002, 4.74243347e+002, 1.56034164e+002,
       4.73834778e+002, 2.00523651e+002, 4.72891602e+002,
       2.44457306e+002, 4.71412811e+002, 2.87981171e+002,
       4.69708252e+002, 3.30783173e+002, 4.67558228e+002,
       3.71818420e+002, 4.65495667e+002, 4.11996979e+002,
       4.31027649e+002, 6.75546722e+001, 4.31269440e+002,
       1.10960022e+002, 4.31185486e+002, 1.55113556e+002,
       4.30830139e+002, 2.00061066e+002, 4.30168427e+002,
       2.44456863e+002, 4.29107544e+002, 2.88479645e+002,
       4.27829071e+002, 3.31813507e+002, 4.26131653e+002,
       3.73071228e+002, 4.24718811e+002, 4.13476563e+002,
       3.86868805e+002, 6.61982269e+001, 3.86895416e+002,
       1.09904411e+002, 3.86690216e+002, 1.54396423e+002,
       3.86368591e+002, 1.99800369e+002, 3.85792206e+002,
       2.44538574e+002, 3.85117279e+002, 2.88826447e+002,
       3.84405273e+002, 3.32408020e+002, 3.83303772e+002,
       3.74074097e+002, 3.82477448e+002, 4.14638977e+002,
       3.41941437e+002, 6.54462357e+001, 3.41628204e+002,
       1.09383698e+002, 3.41402344e+002, 1.54105545e+002,
       3.41168854e+002, 1.99655045e+002, 3.40816681e+002,
       2.44469910e+002, 3.40516937e+002, 2.88975800e+002,
       3.40365662e+002, 3.32670990e+002, 3.39935211e+002,
       3.74465759e+002, 3.39847626e+002, 4.14742279e+002,
       2.96694000e+002, 6.56859589e+001, 2.96075226e+002,
       1.09505333e+002, 2.95704895e+002, 1.54202652e+002,
       2.95653107e+002, 1.99734131e+002, 2.95589661e+002,
       2.44549530e+002, 2.95629547e+002, 2.88889496e+002,
       2.96138733e+002, 3.32610931e+002, 2.96520905e+002,
       3.74608551e+002, 2.96987091e+002, 4.14774902e+002,
       2.51414978e+002, 6.65755463e+001, 2.50681854e+002,
       1.10189331e+002, 2.50183380e+002, 1.54658005e+002,
       2.50331161e+002, 2.00073761e+002, 2.50590790e+002,
       2.44719513e+002, 2.51083817e+002, 2.88868286e+002,
       2.52134262e+002, 3.32266937e+002, 2.53097809e+002,
       3.74022491e+002, 2.54404007e+002, 4.14018066e+002,
       1.49524078e+002, 1.27699501e+002, 1.89511658e+002,
       1.25816605e+002, 2.31050888e+002, 1.24260918e+002,
       2.74076721e+002, 1.23023209e+002, 3.17643005e+002,
       1.22288109e+002, 3.61785889e+002, 1.22105164e+002,
       4.06142670e+002, 1.22401566e+002, 4.49623962e+002,
       1.23246025e+002, 4.92677216e+002, 1.24087708e+002,
       1.48706085e+002, 1.69077423e+002, 1.88827805e+002,
       1.67750443e+002, 2.30439865e+002, 1.66769333e+002,
       2.73830933e+002, 1.65871170e+002, 3.17596741e+002,
       1.65410919e+002, 3.61983459e+002, 1.65327866e+002,
       4.06748322e+002, 1.65463974e+002, 4.50450226e+002,
       1.66126526e+002, 4.93614655e+002, 1.66970413e+002,
       1.48312607e+002, 2.11499451e+002, 1.88574097e+002,
       2.10860214e+002, 2.30130676e+002, 2.10261612e+002,
       2.73557709e+002, 2.09837143e+002, 3.17542572e+002,
       2.09633057e+002, 3.62091248e+002, 2.09732620e+002,
       4.06934570e+002, 2.09926758e+002, 4.50914612e+002,
       2.10320221e+002, 4.94044495e+002, 2.10900925e+002,
       1.48613831e+002, 2.53997177e+002, 1.88797791e+002,
       2.53912842e+002, 2.30240204e+002, 2.53975067e+002,
       2.73746704e+002, 2.54010208e+002, 3.17718262e+002,
       2.54106003e+002, 3.62188965e+002, 2.54205475e+002,
       4.06908783e+002, 2.54317505e+002, 4.50824951e+002,
       2.54539490e+002, 4.93825714e+002, 2.54753876e+002,
       1.49541687e+002, 2.96404175e+002, 1.89357727e+002,
       2.97117523e+002, 2.30807007e+002, 2.97805603e+002,
       2.74325470e+002, 2.97966522e+002, 3.18042206e+002,
       2.98304535e+002, 3.62105774e+002, 2.98552643e+002,
       4.06672272e+002, 2.98572418e+002, 4.50363068e+002,
       2.98569550e+002, 4.93109894e+002, 2.98516205e+002,
       1.50883698e+002, 3.38493195e+002, 1.90633621e+002,
       3.39862610e+002, 2.31920990e+002, 3.40869415e+002,
       2.74971252e+002, 3.41453766e+002, 3.18235229e+002,
       3.41952637e+002, 3.62063477e+002, 3.42314026e+002,
       4.06098938e+002, 3.42221802e+002, 4.49477386e+002,
       3.42063812e+002, 4.91864716e+002, 3.41727600e+002,
       2.36129852e+002, 3.92798004e+002, 2.34999939e+002,
       3.56118683e+002, 2.34376099e+002, 3.18607025e+002,
       2.33822159e+002, 2.80400696e+002, 2.33565445e+002,
       2.42213104e+002, 2.33583069e+002, 2.03937286e+002,
       2.34028824e+002, 1.65756607e+002, 2.34613373e+002,
       1.28586639e+002, 2.35190308e+002, 9.18279037e+001,
       2.73031616e+002, 3.93267242e+002, 2.72295166e+002,
       3.56342743e+002, 2.71799347e+002, 3.18847412e+002,
       2.71418854e+002, 2.80287872e+002, 2.71161469e+002,
       2.41881134e+002, 2.71248962e+002, 2.03348145e+002,
       2.71379303e+002, 1.64895874e+002, 2.71946045e+002,
       1.27450935e+002, 2.72322418e+002, 9.06900787e+001,
       3.10670715e+002, 3.93568848e+002, 3.10389160e+002,
       3.56545959e+002, 3.10084625e+002, 3.18814514e+002,
       3.09801544e+002, 2.80242737e+002, 3.09678711e+002,
       2.41574814e+002, 3.09779663e+002, 2.02989838e+002,
       3.09842712e+002, 1.64338043e+002, 3.10076782e+002,
       1.26870911e+002, 3.10243286e+002, 8.98413315e+001,
       3.48618134e+002, 3.93563202e+002, 3.48617065e+002,
       3.56472382e+002, 3.48608795e+002, 3.18855621e+002,
       3.48544556e+002, 2.80011017e+002, 3.48556396e+002,
       2.41388168e+002, 3.48585388e+002, 2.02692429e+002,
       3.48435089e+002, 1.64099731e+002, 3.48442902e+002,
       1.26549957e+002, 3.48338043e+002, 8.98002014e+001,
       3.86625610e+002, 3.93188599e+002, 3.87047729e+002,
       3.56377594e+002, 3.87306274e+002, 3.18714752e+002,
       3.87337799e+002, 2.79868896e+002, 3.87402740e+002,
       2.41228760e+002, 3.87295166e+002, 2.02695313e+002,
       3.87030273e+002, 1.64203415e+002, 3.86741211e+002,
       1.26606262e+002, 3.86337311e+002, 8.99655075e+001,
       4.24534088e+002, 3.92702545e+002, 4.25310822e+002,
       3.55900452e+002, 4.25869019e+002, 3.18160614e+002,
       4.25909790e+002, 2.79615753e+002, 4.25977295e+002,
       2.41165100e+002, 4.25826477e+002, 2.02876389e+002,
       4.25331665e+002, 1.64527618e+002, 4.24775787e+002,
       1.27097328e+002, 4.23985138e+002, 9.08176651e+001,
       1.79142670e+002, 1.58573654e+002, 2.12791580e+002,
       1.56291031e+002, 2.47140106e+002, 1.54265656e+002,
       2.82607300e+002, 1.52373688e+002, 3.18175507e+002,
       1.50692184e+002, 3.54185852e+002, 1.49404175e+002,
       3.90455200e+002, 1.48229370e+002, 4.26106689e+002,
       1.47507843e+002, 4.61576141e+002, 1.46712479e+002,
       1.80388336e+002, 1.93027603e+002, 2.14026459e+002,
       1.91128204e+002, 2.48376541e+002, 1.89414978e+002,
       2.83795807e+002, 1.87720856e+002, 3.19472473e+002,
       1.86192383e+002, 3.55483826e+002, 1.84929199e+002,
       3.91970764e+002, 1.83747040e+002, 4.27654572e+002,
       1.82931534e+002, 4.63295227e+002, 1.81977234e+002,
       1.81914261e+002, 2.27955460e+002, 2.15291260e+002,
       2.26512482e+002, 2.49628265e+002, 2.25067520e+002,
       2.85066406e+002, 2.23593185e+002, 3.20846680e+002,
       2.22337708e+002, 3.56862885e+002, 2.21191040e+002,
       3.93279907e+002, 2.19905640e+002, 4.29202271e+002,
       2.18870361e+002, 4.64728424e+002, 2.17972977e+002,
       1.83496948e+002, 2.62963226e+002, 2.16930527e+002,
       2.61755219e+002, 2.51115829e+002, 2.60777222e+002,
       2.86553406e+002, 2.59500336e+002, 3.22299896e+002,
       2.58380737e+002, 3.58307648e+002, 2.57236694e+002,
       3.94551819e+002, 2.56009125e+002, 4.30358948e+002,
       2.54925797e+002, 4.65684998e+002, 2.54021484e+002,
       1.85461685e+002, 2.97687378e+002, 2.18712234e+002,
       2.96999207e+002, 2.52770218e+002, 2.96270752e+002,
       2.88213776e+002, 2.95168213e+002, 3.23698334e+002,
       2.94233032e+002, 3.59477722e+002, 2.93170715e+002,
       3.95647766e+002, 2.91897400e+002, 4.31309845e+002,
       2.90856995e+002, 4.66494110e+002, 2.89726410e+002,
       1.87661331e+002, 3.32186188e+002, 2.20767746e+002,
       3.31906250e+002, 2.54839096e+002, 3.31398651e+002,
       2.89963745e+002, 3.30524139e+002, 3.25207642e+002,
       3.29771820e+002, 3.60686035e+002, 3.28762695e+002,
       3.96576447e+002, 3.27542206e+002, 4.31994415e+002,
       3.26294189e+002, 4.66894653e+002, 3.24949921e+002,
       2.03543015e+002, 1.77473557e+002, 2.32777847e+002,
       1.74712509e+002, 2.62628723e+002, 1.72331970e+002,
       2.93045898e+002, 1.69686768e+002, 3.23527618e+002,
       1.67496246e+002, 3.54206787e+002, 1.65446075e+002,
       3.85180176e+002, 1.63360580e+002, 4.15484253e+002,
       1.61536423e+002, 4.45720947e+002, 1.59896164e+002,
       2.05864395e+002, 2.07228104e+002, 2.35242096e+002,
       2.04699326e+002, 2.64853973e+002, 2.02407455e+002,
       2.95353882e+002, 1.99972321e+002, 3.25811890e+002,
       1.97671921e+002, 3.56471252e+002, 1.95763168e+002,
       3.87280548e+002, 1.93597977e+002, 4.17615814e+002,
       1.91867371e+002, 4.48018677e+002, 1.90067413e+002,
       2.08421249e+002, 2.37166977e+002, 2.37513824e+002,
       2.34982773e+002, 2.67261261e+002, 2.32802841e+002,
       2.97555817e+002, 2.30466080e+002, 3.28118103e+002,
       2.28462463e+002, 3.58699707e+002, 2.26417038e+002,
       3.89468842e+002, 2.24356827e+002, 4.19895996e+002,
       2.22421921e+002, 4.50077850e+002, 2.20683517e+002,
       2.11095444e+002, 2.66940186e+002, 2.40241348e+002,
       2.64970093e+002, 2.69563019e+002, 2.63153290e+002,
       2.99863464e+002, 2.60983551e+002, 3.30282440e+002,
       2.58911560e+002, 3.60724792e+002, 2.56935730e+002,
       3.91487915e+002, 2.54799423e+002, 4.21789093e+002,
       2.52929688e+002, 4.51818481e+002, 2.51059357e+002,
       2.13829117e+002, 2.96591217e+002, 2.42742859e+002,
       2.94884583e+002, 2.72209076e+002, 2.93215668e+002,
       3.02402985e+002, 2.91230591e+002, 3.32536072e+002,
       2.89165192e+002, 3.62860901e+002, 2.87413605e+002,
       3.93481842e+002, 2.85199615e+002, 4.23728851e+002,
       2.83277496e+002, 4.53453094e+002, 2.81229309e+002,
       2.16799316e+002, 3.25975220e+002, 2.45605515e+002,
       3.24619904e+002, 2.74777344e+002, 3.22958679e+002,
       3.04762817e+002, 3.21008057e+002, 3.34797150e+002,
       3.19291443e+002, 3.65005798e+002, 3.17295044e+002,
       3.95311981e+002, 3.15296021e+002, 4.25312592e+002,
       3.13086945e+002, 4.54931152e+002, 3.11027130e+002,
       2.60550232e+002, 3.70739563e+002, 2.59674011e+002,
       3.42115936e+002, 2.58910492e+002, 3.13278015e+002,
       2.58195618e+002, 2.84013580e+002, 2.57727173e+002,
       2.55017166e+002, 2.57326263e+002, 2.25760986e+002,
       2.57096619e+002, 1.96577972e+002, 2.57031860e+002,
       1.68026199e+002, 2.56873383e+002, 1.39550308e+002,
       2.89019318e+002, 3.70481354e+002, 2.88355560e+002,
       3.41833252e+002, 2.87601471e+002, 3.12872925e+002,
       2.87057190e+002, 2.83485535e+002, 2.86599762e+002,
       2.54255096e+002, 2.86174438e+002, 2.25023285e+002,
       2.85775940e+002, 1.95715347e+002, 2.85577087e+002,
       1.66989502e+002, 2.85395477e+002, 1.38597382e+002,
       3.18072754e+002, 3.70118317e+002, 3.17432709e+002,
       3.41398743e+002, 3.16917267e+002, 3.12476044e+002,
       3.16284363e+002, 2.83001587e+002, 3.15799072e+002,
       2.53725845e+002, 3.15411957e+002, 2.24337708e+002,
       3.15070374e+002, 1.95034119e+002, 3.14736847e+002,
       1.66195313e+002, 3.14439789e+002, 1.37797058e+002,
       3.47083588e+002, 3.69678101e+002, 3.46717987e+002,
       3.40949524e+002, 3.46185303e+002, 3.12009857e+002,
       3.45728088e+002, 2.82454071e+002, 3.45226624e+002,
       2.53109863e+002, 3.44883606e+002, 2.23839539e+002,
       3.44373535e+002, 1.94399933e+002, 3.43879852e+002,
       1.65690643e+002, 3.43438629e+002, 1.37252930e+002,
       3.76341522e+002, 3.68972321e+002, 3.76086884e+002,
       3.40412842e+002, 3.75708893e+002, 3.11398376e+002,
       3.75143494e+002, 2.81901520e+002, 3.74762970e+002,
       2.52577988e+002, 3.74223969e+002, 2.23348221e+002,
       3.73600891e+002, 1.93979538e+002, 3.72983917e+002,
       1.65201294e+002, 3.72517273e+002, 1.36871033e+002,
       4.05512115e+002, 3.68243225e+002, 4.05366333e+002,
       3.39678650e+002, 4.05090027e+002, 3.10679108e+002,
       4.04612366e+002, 2.81203522e+002, 4.04152649e+002,
       2.52051605e+002, 4.03539703e+002, 2.22930420e+002,
       4.02903351e+002, 1.93625381e+002, 4.02272827e+002,
       1.65004440e+002, 4.01353333e+002, 1.36796814e+002 ]
View Code

(注:我这里使用的是最新版本Opencv4.x,其他版本的标定文件不一定兼容,例如我使用Opencv3中的camera_calibration.cpp在Opencv4.x环境下就无法编译通过)

编译方式采用Cmake,CMakeLists.txt脚本如下:

1 cmake_minimum_required(VERSION 2.8)
2 
3 project(main_calibration)
4 
5 find_package(OpenCV REQUIRED)
6 include_directories(${OpenCV_INCLUDE_DIRS})
7 
8 add_executable(main_calibration camera_calibration.cpp)
9 target_link_libraries(main_calibration ${OpenCV_LIBS})

编译流程如下:

Step1:本地主程序camera_calibration.cpp文件目录下新建编译临时文件夹build.(CMakeLists.txt和主程序文件在同一目录下).

Step2:切换目录到build文件夹下,使用cmake命令生成对应的Makefile以及预编译临时文件.

Step3:使用make命令进行编译,编译完成后自动在build文件夹下生成可执行文件main_calibration.

mkdir build
cd build
cmake ..
make

接下来修改可执行文件main_calibration可执行文件的参数文件in_VID5.xml

Line5: <BoardSize_Width>8</BoardSize_Width> # 设置Chess标定板宽度方向角点数.(注意是inner方块的角点数)
Line6: <BoardSize_Height>6</BoardSize_Height> # 设置Chess标定板高度方向角点数.(注意inner角点表示出了最外侧一圈方格的部分)
Line9: <Square_Size>40</Square_Size> # 实际物理棋盘上方块的边长(Units:mm)
Line12: <Calibration_Pattern>"CHESSBARD"</Calibration_Pattern> # 一般这里都设置为棋盘,如果你的是其他标定板请使用其他参数.
Line19:<Input>"absolute_path/VID5.xml"</Input> # 这里如果设置为1表示使用Camera来现场采集图片进行标定,一般来说可以设置VID5.xml文件路径,程序将会通过VID5.xml文件中标定图片路径读取图片,这里需要配置好VID5.xml文件.
Line24:<Input_Delay>100</Input_Delay> # 如果使用Camera来实时采集标定图像,则这个参数用来设定两次采集动作之间的时间间隔,如果不采用Camera则不用设置.
Line27:<Calibrate_NrOfFrameToUse><Calibrate_NrOfFrameToUse> # 设置用来标定的有效图像数量,25表示使用能够找到角点并满足角点要求的25张标定图进行相机标定.
Line37: <Write_outputFileName>"out_camera_data.yml"</Write_outputFileName> # 设置标定完成后参数保存的路径以及文件,注意文件后缀名为.yml.
Line47: <Calibrate_UseFisheyeModel>1</Calibrate_UseFishModel> # 如果需要标定的为鱼眼镜头,则需要设置为1.

根据in_VID5.xml中的设置,如果选用已经拍摄好的照片则需要修改VID5.xml文件内容,添加标定图像的绝对路径:

如图上所示,一般需要采集足够多的图像,以保证能够找到足够用来标定Camera的图像,如果不满足要求则会出现如下错误(请调整光照等条件重新采集图像):

完成基本参数文件设置之后开始运行:

./main_calibration ../in_VID5.xml

运行过程截图如下:

 

 如上左图表示图像角点提取的情况,右图表示矫正之后的结果。

三、使用标定结果矫正畸变

###

四、参考资料

以上代码打包Baidu-Pan下载地址:https://pan.baidu.com/s/1icrwvNws2N1j7b7bjGxPNA  提取码:6koe 

Matlab标定工具箱使用官方参考教程:http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/example.html

图像矫正及畸变参数使用:https://blog.csdn.net/weixin_38009585/article/details/82356022

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!