-
Notifications
You must be signed in to change notification settings - Fork 1
/
cameracalibrator.cpp
executable file
·103 lines (94 loc) · 3.82 KB
/
cameracalibrator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "cameracalibrator.h"
CameraCalibrator::CameraCalibrator() :
flag(0),
mustInitUndistort(true)
{
}
// open chessboard images and extract corner points
int CameraCalibrator::addChessboardPoints(const std::vector<Mat>& imageList, cv::Size & boardSize)
{
// points on the chessboard
vector<Point2f> imageCorners;
vector<Point3f> objectCorners;
// 3D Scene Points
// Initialize the chessboard corners in the chessboard reference frame.
// The corners are at 3D location (X,Y,Z)= (i,j,0)
for (int i=0; i<boardSize.height; i++)
for (int j=0; j<boardSize.width; j++)
objectCorners.push_back(Point3f(i, j, 0.0f));
// 2D Image Points
Mat image; // to contain the current chessboard image
int successes = 0;
// for all viewpoints
int listSize = (int) imageList.size();
for (int i=0; i<listSize; i++)
{
// get the image in grayscale
image = imageList[i];
cvtColor(image, image,CV_BGR2GRAY);
// get the chessboard corners
findChessboardCorners(image, boardSize, imageCorners);
// get subpixel accuracy on the corners
cv::cornerSubPix(
image,
imageCorners,
Size(5,5),
Size(-1,-1),
TermCriteria(
TermCriteria::MAX_ITER +
TermCriteria::EPS,
30, // max number of iterations
0.1) //min accuracy
);
// if we have a good board, add it to our data
if (imageCorners.size() == (unsigned int) boardSize.area()) {
// add image and scene points from one view
addPoints(imageCorners, objectCorners);
successes++;
}
}
return successes;
}
// add scene points and corresponding image points
void CameraCalibrator::addPoints(const vector<Point2f>& imageCorners, const vector<Point3f>& objectCorners)
{
// 2D image points from one view
imagePoints.push_back(imageCorners);
// corresponding 3D scene points
objectPoints.push_back(objectCorners);
}
// calibrate the camera and returns the re-projection error
double CameraCalibrator::calibrate(Size &imageSize)
{
// undistorter must be reinitialized
mustInitUndistort = true;
//Output rotations and translations vectors
vector<Mat> rvecs, tvecs;
// start calibration (you can use solvePnP instead of calibrateCamera)
return calibrateCamera(objectPoints, // the 3D points
imagePoints, // the image points
imageSize, // image size
cameraMatrix, // output camera matrix
distCoeffs, // output distortion matrix
rvecs, tvecs, // Rs, Ts
flag); // set options
}
// remove distortion in the image (after calibration)
Mat CameraCalibrator::remap(const Mat &image)
{
Mat undistorted;
if (mustInitUndistort) { // called once per calibration
initUndistortRectifyMap(
cameraMatrix, // computed camera matrix
distCoeffs, // computed distortion matrix
Mat(), // optional rectification (none)
Mat(), // camera matrix to generate undistorted
image.size(), // size of undistorted
CV_32FC1, // type of output map
map1, map2); // the x and y mapping functions
mustInitUndistort = false;
}
// apply mapping functions
cv::remap(image, undistorted, map1, map2, INTER_LINEAR); // interpolation type
return undistorted;
}