20 #include <opencv2/core/base.hpp>
21 #include <opencv2/imgproc.hpp>
22 #include <opencv2/calib3d.hpp>
23 #include "iCub/stereoVision/camera.h"
26 FileStorage fs(intrinsicFilePath.c_str(), FileStorage::READ);
29 printf(
"Failed to open file %s\n", intrinsicFilePath.c_str());
32 fs[
"camera_matrix"] >> K;
33 fs[
"distortion_coefficients"] >> Dist;
39 void Camera::printMatrix(Mat &matrix) {
44 for(
int i = 0; i < matrix.rows; i++)
46 const double* Mi = matrix.ptr<
double>(i);
47 for(
int j = 0; j < matrix.cols; j++)
53 void Camera::calibrate(vector<string> imageList,
int boardWidth,
int boardHeight) {
54 vector<vector<Point2f> > imagePoints;
55 Size boardSize, imageSize;
56 boardSize.width=boardWidth;
57 boardSize.height=boardHeight;
61 float squareSize = 1.f, aspectRatio = 1.f;
65 for(i = 0; i<(int)imageList.size();i++)
68 view = cv::imread(imageList[i], 1);
69 imageSize = view.size();
70 vector<Point2f> pointbuf;
71 cvtColor(view, viewGray, cv::COLOR_BGR2GRAY);
73 bool found = findChessboardCorners( view, boardSize, pointbuf,
74 cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_FAST_CHECK + cv::CALIB_CB_NORMALIZE_IMAGE);
78 drawChessboardCorners( view, boardSize, Mat(pointbuf), found );
79 imagePoints.push_back(pointbuf);
83 prepareandRunCalibration(imagePoints, imageSize, boardSize, squareSize, aspectRatio, flags, K, Dist);
88 void Camera::calibrate(
string imagesFilePath,
int boardWidth,
int boardHeight) {
89 vector<vector<Point2f> > imagePoints;
90 vector<string> imageList;
91 Size boardSize, imageSize;
92 boardSize.width=boardWidth;
93 boardSize.height=boardHeight;
97 float squareSize = 1.f, aspectRatio = 1.f;
100 if(!readStringList(imagesFilePath, imageList))
102 cout <<
"Cannot Open Image List File. Calibration Failed" << endl;
108 for(i = 0; i<(int)imageList.size();i++)
111 view = cv::imread(imageList[i], 1);
112 imageSize = view.size();
113 vector<Point2f> pointbuf;
114 cvtColor(view, viewGray, cv::COLOR_BGR2GRAY);
116 bool found = findChessboardCorners( view, boardSize, pointbuf,
117 cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_FAST_CHECK + cv::CALIB_CB_NORMALIZE_IMAGE);
122 drawChessboardCorners( view, boardSize, Mat(pointbuf), found );
123 imagePoints.push_back(pointbuf);
127 prepareandRunCalibration(imagePoints, imageSize, boardSize, squareSize, aspectRatio, flags, K, Dist);
131 bool Camera::readStringList(
const string& filename, vector<string>& l )
134 FileStorage fs(filename, FileStorage::READ);
137 FileNode n = fs.getFirstTopLevelNode();
138 if( n.type() != FileNode::SEQ )
140 FileNodeIterator it = n.begin(), it_end = n.end();
141 for( ; it != it_end; ++it )
142 l.push_back((
string)*it);
149 bool Camera::prepareandRunCalibration(
const vector<vector<Point2f> >& imagePoints,
150 Size imageSize, Size boardSize,
float squareSize,
151 float aspectRatio,
int flags, Mat& cameraMatrix,
154 vector<Mat> rvecs, tvecs;
155 vector<float> reprojErrs;
156 double totalAvgErr = 0;
158 bool ok = runCalibration(imagePoints, imageSize, boardSize, squareSize,
159 aspectRatio, flags, cameraMatrix, distCoeffs,
160 rvecs, tvecs, reprojErrs, totalAvgErr);
161 printf(
"%s. avg reprojection error = %.2f\n",
162 ok ?
"Calibration succeeded" :
"Calibration failed",
169 bool Camera::runCalibration( vector<vector<Point2f> > imagePoints,
170 Size imageSize, Size boardSize,
171 float squareSize,
float aspectRatio,
172 int flags, Mat& cameraMatrix, Mat& distCoeffs,
173 vector<Mat>& rvecs, vector<Mat>& tvecs,
174 vector<float>& reprojErrs,
177 cameraMatrix = Mat::eye(3, 3, CV_64F);
178 if( flags & cv::CALIB_FIX_ASPECT_RATIO )
179 cameraMatrix.at<
double>(0,0) = aspectRatio;
181 distCoeffs = Mat::zeros(4, 1, CV_64F);
183 vector<vector<Point3f> > objectPoints(1);
184 calcChessboardCorners(boardSize, squareSize, objectPoints[0]);
186 objectPoints.resize(imagePoints.size(),objectPoints[0]);
188 double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix,
189 distCoeffs, rvecs, tvecs, cv::CALIB_FIX_K3);
190 printf(
"RMS error reported by calibrateCamera: %g\n", rms);
192 bool ok = checkRange(cameraMatrix) && checkRange(distCoeffs);
194 totalAvgErr = computeReprojectionErrors(objectPoints, imagePoints,
195 rvecs, tvecs, cameraMatrix, distCoeffs, reprojErrs);
200 void Camera::calcChessboardCorners(Size boardSize,
float squareSize, vector<Point3f>& corners)
204 for(
int i = 0; i < boardSize.height; i++ )
205 for(
int j = 0; j < boardSize.width; j++ )
206 corners.push_back(Point3f(
float(j*squareSize),
207 float(i*squareSize), 0));
210 double Camera::computeReprojectionErrors(
211 const vector<vector<Point3f> >& objectPoints,
212 const vector<vector<Point2f> >& imagePoints,
213 const vector<Mat>& rvecs,
const vector<Mat>& tvecs,
214 const Mat& cameraMatrix,
const Mat& distCoeffs,
215 vector<float>& perViewErrors )
217 vector<Point2f> imagePoints2;
218 int i, totalPoints = 0;
219 double totalErr = 0, err;
220 perViewErrors.resize(objectPoints.size());
222 for( i = 0; i < (int)objectPoints.size(); i++ )
224 projectPoints(Mat(objectPoints[i]), rvecs[i], tvecs[i],
225 cameraMatrix, distCoeffs, imagePoints2);
226 err = norm(Mat(imagePoints[i]), Mat(imagePoints2), cv::NORM_L2);
227 int n = (int)objectPoints[i].size();
228 perViewErrors[i] = (float)std::sqrt(err*err/n);
233 return std::sqrt(totalErr/totalPoints);
239 if(this->K.empty()) {
240 printf(
"Camera is not calibrated, run calibration method before..\n");
243 FileStorage fs( intrinsicFilePath, FileStorage::WRITE );
244 fs <<
"camera_matrix" << this->K;
245 fs <<
"distortion_coefficients" << this->Dist;
249 void Camera::printCameraMatrix()
250 {
if(this->K.empty())
251 printf(
"Camera is not calibrated, run calibration method before..\n");
253 printMatrix(this->K);
256 void Camera::printDistortionVector()
257 {
if(this->Dist.empty())
258 printf(
"Camera is not calibrated, run calibration method before..\n");
260 printMatrix(this->Dist);
273 undistort(image,imund,K,Dist);
void setDistCoefficients(Mat &Dist)
It sets the distortion parameters.
Camera()
Default Constructor.
Mat getDistVector()
It returns the 4x1 distortion coefficients.
bool saveCalibration(string intrinsicFilePath)
It saves the calibration.
void setCameraMatrix(Mat &K)
It sets the camera parameters.
Mat undistortImage(Mat image)
It undistorts an image using the intrinsic parameters.
Mat getCameraMatrix()
It returns the 3x3 camera matrix.