20 #include <mrpt/otherlibs/do_opencv_includes.h>
35 unsigned int check_size_y,
double check_squares_length_X_meters,
37 std::vector<double>& distortionParams,
bool normalize_image,
38 double* out_MSE,
bool skipDrawDetectedImgs,
39 bool useScaramuzzaAlternativeDetector)
44 images, check_size_x, check_size_y, check_squares_length_X_meters,
45 check_squares_length_Y_meters, cam, normalize_image, out_MSE,
46 skipDrawDetectedImgs, useScaramuzzaAlternativeDetector);
60 typename _Tp,
int _rows,
int _cols,
int _options,
int _maxRows,
64 Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>&
dst)
66 CV_DbgAssert(
src.rows == _rows &&
src.cols == _cols);
67 if (!(
dst.Flags & Eigen::RowMajorBit))
71 (
size_t)(
dst.stride() *
sizeof(_Tp)));
72 if (
src.type() == _dst.type())
74 else if (
src.cols ==
src.rows)
76 src.convertTo(_dst, _dst.type());
80 Mat(
src.t()).convertTo(_dst, _dst.type());
81 CV_DbgAssert(_dst.data == (uchar*)
dst.data());
87 (
size_t)(
dst.stride() *
sizeof(_Tp)));
88 src.convertTo(_dst, _dst.type());
89 CV_DbgAssert(_dst.data == (uchar*)
dst.data());
100 unsigned int check_size_y,
double check_squares_length_X_meters,
102 bool normalize_image,
double* out_MSE,
bool skipDrawDetectedImgs,
103 bool useScaramuzzaAlternativeDetector)
111 ASSERT_(check_squares_length_X_meters > 0);
112 ASSERT_(check_squares_length_Y_meters > 0);
114 if (images.size() < 1)
116 std::cout <<
"ERROR: No input images." << std::endl;
120 const unsigned CORNERS_COUNT = check_size_x * check_size_y;
121 const CvSize check_size = cvSize(check_size_x, check_size_y);
125 vector<cv::Point3f> pattern_obj_points(CORNERS_COUNT);
128 for (
y = 0, k = 0;
y < check_size_y;
y++)
130 for (
unsigned int x = 0;
x < check_size_x;
x++, k++)
132 pattern_obj_points[k].x = -check_squares_length_X_meters *
136 pattern_obj_points[k].y = check_squares_length_Y_meters *
y;
137 pattern_obj_points[k].z = 0;
145 for (it = images.begin(); it != images.end(); ++it)
158 "Error reading image: %s", it->first.c_str());
167 vector<vector<cv::Point3f>>
169 vector<vector<cv::Point2f>>
172 unsigned int valid_detected_imgs = 0;
173 vector<string> pointsIdx2imageFile;
174 cv::Size imgSize(0, 0);
177 for (i = 0, it = images.begin(); it != images.end(); it++, i++)
188 out_camera_params.
ncols = imgSize.width;
189 out_camera_params.
nrows = imgSize.height;
193 if (imgSize.height != (
int)img_gray.
getHeight() ||
194 imgSize.width != (
int)img_gray.
getWidth())
196 std::cout <<
"ERROR: All the images must have the same size"
204 unsigned corners_count;
205 bool corners_found =
false;
207 corners_count = CORNERS_COUNT;
209 vector<cv::Point2f> this_img_pts(
217 vector<TPixelCoordf> detectedCoords;
219 img_gray, detectedCoords, check_size_x, check_size_y,
221 useScaramuzzaAlternativeDetector);
223 corners_count = detectedCoords.size();
226 ASSERT_(detectedCoords.size() <= CORNERS_COUNT);
227 for (
size_t p = 0;
p < detectedCoords.size();
p++)
229 this_img_pts[
p].x = detectedCoords[
p].x;
230 this_img_pts[
p].y = detectedCoords[
p].y;
233 if (corners_found && corners_count != CORNERS_COUNT)
234 corners_found =
false;
239 corners_found ?
"DETECTED" :
"NOT DETECTED");
246 for (
y = 0, k = 0;
y < check_size.height;
y++)
247 for (
x = 0;
x < check_size.width;
x++, k++)
249 this_img_pts[k].x, this_img_pts[k].y));
256 CvPoint prev_pt = cvPoint(0, 0);
257 const int line_max = 8;
258 CvScalar line_colors[8];
260 line_colors[0] = CV_RGB(255, 0, 0);
261 line_colors[1] = CV_RGB(255, 128, 0);
262 line_colors[2] = CV_RGB(255, 128, 0);
263 line_colors[3] = CV_RGB(200, 200, 0);
264 line_colors[4] = CV_RGB(0, 255, 0);
265 line_colors[5] = CV_RGB(0, 200, 200);
266 line_colors[6] = CV_RGB(0, 0, 255);
267 line_colors[7] = CV_RGB(255, 0, 255);
274 for (
y = 0, k = 0;
y < check_size.height;
y++)
276 CvScalar
color = line_colors[
y % line_max];
277 for (
x = 0;
x < check_size.width;
x++, k++)
280 pt.x = cvRound(this_img_pts[k].
x);
281 pt.y = cvRound(this_img_pts[k].
y);
283 if (k != 0) cvLine(rgb_img, prev_pt, pt,
color);
286 rgb_img, cvPoint(pt.x -
r, pt.y -
r),
287 cvPoint(pt.x +
r, pt.y +
r),
color);
289 rgb_img, cvPoint(pt.x -
r, pt.y +
r),
290 cvPoint(pt.x +
r, pt.y -
r),
color);
291 cvCircle(rgb_img, pt,
r + 1,
color);
298 pointsIdx2imageFile.push_back(it->first);
299 imagePoints.push_back(this_img_pts);
300 objectPoints.push_back(pattern_obj_points);
302 valid_detected_imgs++;
307 std::cout << valid_detected_imgs <<
" valid images." << std::endl;
308 if (!valid_detected_imgs)
310 std::cout <<
"ERROR: No valid images. Perhaps the checkerboard "
320 cv::Mat cameraMatrix, distCoeffs(1, 5, CV_64F, cv::Scalar::all(0));
321 vector<cv::Mat> rvecs, tvecs;
323 const double cv_calib_err = cv::calibrateCamera(
324 objectPoints, imagePoints, imgSize, cameraMatrix, distCoeffs, rvecs,
331 out_camera_params.
dist.fill(0);
332 for (
int k = 0; k < 5; k++)
333 out_camera_params.
dist[k] = distCoeffs.ptr<
double>()[k];
336 for (i = 0; i < valid_detected_imgs; i++)
345 cv::Rodrigues(rvecs[i], cv_rot);
349 HM.block<3, 3>(0, 0) = rot;
353 Eigen::Matrix<double, 3, 1> trans;
355 HM.block<3, 1>(0, 3) = trans;
360 images[pointsIdx2imageFile[i]].reconstructed_camera_pose =
p;
364 <<
": " <<
p << std::endl;
376 for (it = images.begin(); it != images.end(); ++it)
389 for (i = 0; i < valid_detected_imgs; i++)
396 vector<TPoint3D> lstPatternPoints(
398 for (
unsigned int p = 0;
p < CORNERS_COUNT;
p++)
400 pattern_obj_points[
p].
x, pattern_obj_points[
p].
y,
401 pattern_obj_points[
p].
z);
403 vector<TPixelCoordf>& projectedPoints =
405 vector<TPixelCoordf>& projectedPoints_distorted =
420 projectedPoints_distorted
423 ASSERT_(projectedPoints.size() == CORNERS_COUNT);
424 ASSERT_(projectedPoints_distorted.size() == CORNERS_COUNT);
426 for (
unsigned int p = 0;
p < CORNERS_COUNT;
p++)
428 const double px = projectedPoints[
p].x;
429 const double py = projectedPoints[
p].y;
431 const double px_d = projectedPoints_distorted[
p].x;
432 const double py_d = projectedPoints_distorted[
p].y;
437 if (px >= 0 && px < imgSize.width && py >= 0 &&
441 cvPoint(px, py), 4, CV_RGB(0, 0, 255));
455 if (valid_detected_imgs)
457 sqrErr /= CORNERS_COUNT * valid_detected_imgs;
458 std::cout <<
"Average err. of reprojection: " << sqrt(sqrErr)
459 <<
" pixels (OpenCV error=" << cv_calib_err <<
")\n";
461 if (out_MSE) *out_MSE = sqrt(sqrErr);
465 catch (std::exception& e)
467 std::cout << e.what() << std::endl;
471 THROW_EXCEPTION(
"Function not available: MRPT was compiled without OpenCV");