Visual Servoing Platform  version 3.5.0 under development (2022-02-15)
calibrate-camera.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Camera calibration with chessboard or circle calibration grid.
33  *
34  * Authors:
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 #include <iostream>
39 
40 #include <visp3/core/vpConfig.h>
41 
42 #if VISP_HAVE_OPENCV_VERSION >= 0x020300
43 
44 #include <map>
45 
46 #include <opencv2/calib3d/calib3d.hpp>
47 #include <opencv2/core/core.hpp>
48 #include <opencv2/highgui/highgui.hpp>
49 #include <opencv2/imgproc/imgproc.hpp>
50 
51 #include <visp3/vision/vpCalibration.h>
52 
53 #include <visp3/core/vpImageTools.h>
54 #include <visp3/core/vpIoTools.h>
55 #include <visp3/core/vpMeterPixelConversion.h>
56 #include <visp3/core/vpPixelMeterConversion.h>
57 #include <visp3/core/vpPoint.h>
58 #include <visp3/core/vpXmlParserCamera.h>
59 #include <visp3/gui/vpDisplayD3D.h>
60 #include <visp3/gui/vpDisplayGDI.h>
61 #include <visp3/gui/vpDisplayGTK.h>
62 #include <visp3/gui/vpDisplayOpenCV.h>
63 #include <visp3/gui/vpDisplayX.h>
64 #include <visp3/io/vpVideoReader.h>
65 
66 #include "calibration-helper.hpp"
67 
68 using namespace calib_helper;
69 
70 void usage(const char *argv[], int error)
71 {
72  std::cout << "Synopsis" << std::endl
73  << " " << argv[0] << " <configuration file>.cfg [--init-from-xml <camera-init.xml>]"
74  << " [--camera-name <name>] [--aspect-ratio <ratio>] [--output <file.xml>] [--help] [-h]" << std::endl << std::endl;
75  std::cout << "Description" << std::endl
76  << " <configuration file>.cfg Configuration file. See example in" << std::endl
77  << " \"default-chessboard.cfg\" or in \"default-circles.cfg\"." << std::endl
78  << " Default: \"default.cfg\"." << std::endl << std::endl
79  << " --init-from-xml <camera-init.xml> XML file that contains camera parameters" << std::endl
80  << " used to initialize the calibration process." << std::endl << std::endl
81  << " --camera-name <name> Camera name in the XML file set using \"--init-from-xml\" option." << std::endl
82  << " Default: \"Camera\"." << std::endl << std::endl
83  << " --aspect-ratio <ratio> Pixel aspect ratio. " << std::endl
84  << " To estimate px = py, use \"--aspect-ratio 1\" option. Set to -1" << std::endl
85  << " to unset any constraint for px and py parameters. " << std::endl
86  << " Default: -1." << std::endl << std::endl
87  << " --output <file.xml> XML file containing estimated camera parameters." << std::endl
88  << " Default: \"camera.xml\"." << std::endl << std::endl
89  << " --help, -h Print this helper message." << std::endl << std::endl;
90  if (error) {
91  std::cout << "Error" << std::endl
92  << " " << "Unsupported parameter " << argv[error] << std::endl;
93  }
94 }
95 
96 int main(int argc, const char *argv[])
97 {
98  try {
99  if (argc == 1) {
100  usage(argv, 0);
101  return EXIT_SUCCESS;
102  }
103  std::string opt_output_file_name = "camera.xml";
104  Settings s;
105  const std::string opt_inputSettingsFile = argc > 1 ? argv[1] : "default.cfg";
106  std::string opt_init_camera_xml_file;
107  std::string opt_camera_name = "Camera";
108  double opt_aspect_ratio = -1; // Not used
109 
110  for (int i = 2; i < argc; i++) {
111  if (std::string(argv[i]) == "--init-from-xml" && i+1 < argc) {
112  opt_init_camera_xml_file = std::string(argv[i + 1]);
113  i ++;
114  }
115  else if (std::string(argv[i]) == "--camera-name" && i+1 < argc) {
116  opt_camera_name = std::string(argv[i + 1]);
117  i ++;
118  }
119  else if (std::string(argv[i]) == "--output" && i+1 < argc) {
120  opt_output_file_name = std::string(argv[i + 1]);
121  i ++;
122  }
123  else if (std::string(argv[i]) == "--aspect-ratio" && i+1 < argc) {
124  opt_aspect_ratio = std::atof(argv[i + 1]);
125  i ++;
126  }
127  else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
128  usage(argv, 0);
129  return EXIT_SUCCESS;
130  }
131  else {
132  usage(argv, i);
133  return EXIT_FAILURE;
134  }
135  }
136 
137  std::cout << "Settings from config file: " << argv[1] << std::endl;
138  if (!s.read(opt_inputSettingsFile)) {
139  std::cout << "Could not open the configuration file: \"" << opt_inputSettingsFile << "\"" << std::endl;
140  usage(argv, 0);
141  return EXIT_FAILURE;
142  }
143 
144  if (!s.goodInput) {
145  std::cout << "Invalid input detected. Application stopping. " << std::endl;
146  return EXIT_FAILURE;
147  }
148 
149  std::cout << "\nSettings from command line options: " << std::endl;
150  if (!opt_init_camera_xml_file.empty()) {
151  std::cout << "Init parameters: " << opt_init_camera_xml_file << std::endl;
152  }
153  std::cout << "Ouput xml file : " << opt_output_file_name << std::endl;
154  std::cout << "Camera name : " << opt_camera_name << std::endl;
155 
156  // Check if output file name exists
157  if (vpIoTools::checkFilename(opt_output_file_name)) {
158  std::cout << "\nOutput file name " << opt_output_file_name << " already exists." << std::endl;
159  std::cout << "Remove this file or change output file name using [--output <file.xml>] command line option."
160  << std::endl;
161  return EXIT_SUCCESS;
162  }
163 
164  // Start the calibration code
166  vpVideoReader reader;
167  reader.setFileName(s.input);
168  try {
169  reader.open(I);
170  } catch (const vpException &e) {
171  std::cout << "Catch an exception: " << e.getStringMessage() << std::endl;
172  std::cout << "Check if input images name \"" << s.input << "\" set in " << opt_inputSettingsFile
173  << " config file is correct..." << std::endl;
174  return EXIT_FAILURE;
175  }
176 
177 #ifdef VISP_HAVE_X11
179 #elif defined VISP_HAVE_GDI
181 #elif defined VISP_HAVE_GTK
183 #elif defined VISP_HAVE_OPENCV
185 #endif
186 
187  vpCameraParameters cam_init;
188  bool init_from_xml = false;
189  if (!opt_init_camera_xml_file.empty()) {
190  if (!vpIoTools::checkFilename(opt_init_camera_xml_file)) {
191  std::cout << "Input camera file \"" << opt_init_camera_xml_file << "\" doesn't exist!" << std::endl;
192  std::cout << "Modify [--init-from-xml <camera-init.xml>] option value" << std::endl;
193  return EXIT_FAILURE;
194  }
195  init_from_xml = true;
196  }
197  if (init_from_xml) {
198  std::cout << "Initialize camera parameters from xml file: " << opt_init_camera_xml_file << std::endl;
199  vpXmlParserCamera parser;
200  if (parser.parse(cam_init, opt_init_camera_xml_file, opt_camera_name,
202  std::cout << "Unable to find camera with name \"" << opt_camera_name
203  << "\" in file: " << opt_init_camera_xml_file << std::endl;
204  std::cout << "Modify [--camera-name <name>] option value" << std::endl;
205  return EXIT_FAILURE;
206  }
207  } else {
208  std::cout << "Initialize camera parameters with default values " << std::endl;
209  // Initialize camera parameters
210  double px = cam_init.get_px();
211  double py = cam_init.get_py();
212  // Set (u0,v0) in the middle of the image
213  double u0 = I.getWidth() / 2;
214  double v0 = I.getHeight() / 2;
215  cam_init.initPersProjWithoutDistortion(px, py, u0, v0);
216  }
217 
218  std::cout << "Camera parameters used for initialization:\n" << cam_init << std::endl;
219 
220  std::vector<vpPoint> model;
221  std::vector<vpCalibration> calibrator;
222 
223  for (int i = 0; i < s.boardSize.height; i++) {
224  for (int j = 0; j < s.boardSize.width; j++) {
225  model.push_back(vpPoint(j * s.squareSize, i * s.squareSize, 0));
226  }
227  }
228 
229  std::vector<CalibInfo> calib_info;
230  std::multimap<double, vpCameraParameters, std::less<double> > map_cam_sorted; // Sorted by residual
231 
232  map_cam_sorted.insert(std::make_pair(1000, cam_init));
233 
234  do {
235  reader.acquire(I);
236  long frame_index = reader.getFrameIndex();
237  char filename[FILENAME_MAX];
238  sprintf(filename, s.input.c_str(), frame_index);
239  std::string frame_name = vpIoTools::getName(filename);
241  vpDisplay::flush(I);
242 
243  cv::Mat cvI;
244  std::vector<cv::Point2f> pointBuf;
245  vpImageConvert::convert(I, cvI);
246 
247  std::cout << "Process frame: " << frame_name << std::flush;
248  bool found = extractCalibrationPoints(s, cvI, pointBuf);
249 
250  std::cout << ", grid detection status: " << found;
251  if (!found)
252  std::cout << ", image rejected" << std::endl;
253  else
254  std::cout << ", image used as input data" << std::endl;
255 
256  if (found) { // If image processing done with success
257  vpDisplay::setTitle(I, frame_name);
258 
259  std::vector<vpImagePoint> data;
260  for (unsigned int i = 0; i < pointBuf.size(); i++) {
261  vpImagePoint ip(pointBuf[i].y, pointBuf[i].x);
262  data.push_back(ip);
264  }
265 
266  // Calibration on a single mono image
267  std::vector<vpPoint> calib_points;
268  vpCalibration calib;
269  calib.setLambda(0.5);
270  calib.setAspectRatio(opt_aspect_ratio);
271  for (unsigned int i = 0; i < model.size(); i++) {
272  calib.addPoint(model[i].get_oX(), model[i].get_oY(), model[i].get_oZ(), data[i]);
273  calib_points.push_back(vpPoint(model[i].get_oX(), model[i].get_oY(), model[i].get_oZ()));
274  calib_points.back().set_x(data[i].get_u());
275  calib_points.back().set_y(data[i].get_v());
276  }
277 
279  bool calib_status = false;
280  std::multimap<double, vpCameraParameters>::const_iterator it_cam;
281  for (it_cam = map_cam_sorted.begin(); it_cam != map_cam_sorted.end(); ++it_cam) {
282  vpCameraParameters cam = it_cam->second;
283  if (calib.computeCalibration(vpCalibration::CALIB_VIRTUAL_VS, cMo, cam, false) == EXIT_SUCCESS) {
284  calibrator.push_back(calib);
285  // Add calibration info
286  calib_info.push_back(CalibInfo(I, calib_points, data, frame_name));
287  calib_status = true;
288  double residual = calib.getResidual();
289  map_cam_sorted.insert(std::make_pair(residual, cam));
290  break;
291  }
292  }
293  if (!calib_status) {
294  std::cout << "frame: " << frame_name << ", unable to calibrate from single image, image rejected"
295  << std::endl;
296  found = false;
297  }
298  }
299 
300  if (found)
302  "Image processing succeed", vpColor::green);
303  else
305  "Image processing failed", vpColor::green);
306 
307  if (s.tempo > 10.f) {
309  "A click to process the next image", vpColor::green);
310  vpDisplay::flush(I);
312  } else {
313  vpDisplay::flush(I);
314  vpTime::wait(s.tempo * 1000);
315  }
316  } while (!reader.end());
317 
318  // Now we consider the multi image calibration
319  // Calibrate by a non linear method based on virtual visual servoing
320  if (calibrator.empty()) {
321  std::cerr << "Unable to calibrate. Image processing failed !" << std::endl;
322  return 0;
323  }
324 
325  // Display calibration pattern occupancy
326  drawCalibrationOccupancy(I, calib_info, s.boardSize.width);
327  vpDisplay::setTitle(I, "Calibration pattern occupancy");
330  "Calibration pattern occupancy in the image", vpColor::red);
332  15 * vpDisplay::getDownScalingFactor(I), "Click to continue...", vpColor::red);
333  vpDisplay::flush(I);
335 
336  std::stringstream ss_additional_info;
337  ss_additional_info << "<date>" << vpTime::getDateTime() << "</date>";
338  ss_additional_info << "<nb_calibration_images>" << calibrator.size() << "</nb_calibration_images>";
339  ss_additional_info << "<calibration_pattern_type>";
340 
341  switch (s.calibrationPattern) {
342  case Settings::CHESSBOARD:
343  ss_additional_info << "Chessboard";
344  break;
345 
346  case Settings::CIRCLES_GRID:
347  ss_additional_info << "Circles grid";
348  break;
349 
350  case Settings::UNDEFINED:
351  default:
352  ss_additional_info << "Undefined";
353  break;
354  }
355  ss_additional_info << "</calibration_pattern_type>";
356  ss_additional_info << "<board_size>" << s.boardSize.width << "x" << s.boardSize.height << "</board_size>";
357  ss_additional_info << "<square_size>" << s.squareSize << "</square_size>";
358 
359  double error;
360  // Initialize with camera parameter that has the lowest residual
361  vpCameraParameters cam = map_cam_sorted.begin()->second;
362  std::cout << "\nCalibration without distortion in progress on " << calibrator.size() << " images..." << std::endl;
363  if (vpCalibration::computeCalibrationMulti(vpCalibration::CALIB_VIRTUAL_VS, calibrator, cam, error, false) ==
364  EXIT_SUCCESS) {
365  std::cout << cam << std::endl;
366  vpDisplay::setTitle(I, "Without distorsion results");
367 
368  for (size_t i = 0; i < calibrator.size(); i++) {
369  double reproj_error = sqrt(calibrator[i].getResidual() / calibrator[i].get_npt());
370 
371  const CalibInfo &calib = calib_info[i];
372  std::cout << "Image " << calib.m_frame_name << " reprojection error: " << reproj_error << std::endl;
373  I = calib.m_img;
375 
376  std::ostringstream ss;
377  ss << "Reprojection error: " << reproj_error;
379  calib.m_frame_name, vpColor::red);
381  ss.str(), vpColor::red);
383  "Extracted points", vpColor::red);
385  "Projected points", vpColor::green);
386 
387  for (size_t idx = 0; idx < calib.m_points.size(); idx++) {
389 
390  vpPoint pt = calib.m_points[idx];
391  pt.project(calibrator[i].cMo);
392  vpImagePoint imPt;
393  vpMeterPixelConversion::convertPoint(cam, pt.get_x(), pt.get_y(), imPt);
395  }
396 
398  15 * vpDisplay::getDownScalingFactor(I), "Click to continue...", vpColor::red);
399  vpDisplay::flush(I);
401  }
402 
403  std::cout << "\nGlobal reprojection error: " << error << std::endl;
404  ss_additional_info << "<global_reprojection_error><without_distortion>" << error << "</without_distortion>";
405 
406  vpXmlParserCamera xml;
407 
408  if (xml.save(cam, opt_output_file_name.c_str(), opt_camera_name, I.getWidth(), I.getHeight()) ==
410  std::cout << "Camera parameters without distortion successfully saved in \"" << opt_output_file_name << "\""
411  << std::endl;
412  else {
413  std::cout << "Failed to save the camera parameters without distortion in \"" << opt_output_file_name << "\""
414  << std::endl;
415  std::cout << "A file with the same name exists. Remove it to be able "
416  "to save the parameters..."
417  << std::endl;
418  }
419  } else {
420  std::cout << "Calibration without distortion failed." << std::endl;
421  return EXIT_FAILURE;
422  }
423  vpCameraParameters cam_without_dist = cam;
424  std::vector<vpCalibration> calibrator_without_dist = calibrator;
425 
426  std::cout << "\n\nCalibration with distortion in progress on " << calibrator.size() << " images..." << std::endl;
428  EXIT_SUCCESS) {
429  std::cout << cam << std::endl;
430  vpDisplay::setTitle(I, "With distorsion results");
431 
432  for (size_t i = 0; i < calibrator.size(); i++) {
433  double reproj_error = sqrt(calibrator[i].getResidual_dist() / calibrator[i].get_npt());
434 
435  const CalibInfo &calib = calib_info[i];
436  std::cout << "Image " << calib.m_frame_name << " reprojection error: " << reproj_error << std::endl;
437  I = calib.m_img;
439 
440  std::ostringstream ss;
441  ss << "Reprojection error: " << reproj_error;
443  calib.m_frame_name, vpColor::red);
445  ss.str(), vpColor::red);
447  "Extracted points", vpColor::red);
449  "Projected points", vpColor::green);
450 
451  for (size_t idx = 0; idx < calib.m_points.size(); idx++) {
453 
454  vpPoint pt = calib.m_points[idx];
455  pt.project(calibrator[i].cMo_dist);
456  vpImagePoint imPt;
457  vpMeterPixelConversion::convertPoint(cam, pt.get_x(), pt.get_y(), imPt);
459  }
460 
462  15 * vpDisplay::getDownScalingFactor(I), "Click to continue...", vpColor::red);
463  vpDisplay::flush(I);
465  }
466 
467  std::cout << "\nGlobal reprojection error: " << error << std::endl;
468  ss_additional_info << "<with_distortion>" << error << "</with_distortion></global_reprojection_error>";
469 
470  vpImage<unsigned char> I_undist = I;
471 #ifdef VISP_HAVE_X11
472  vpDisplayX d_undist(I_undist, I.getWidth() / vpDisplay::getDownScalingFactor(I) + 100, 0, "Undistorted image",
474 #elif defined VISP_HAVE_GDI
475  vpDisplayGDI d_undist(I_undist, I.getWidth() / vpDisplay::getDownScalingFactor(I) + 100, 0, "Undistorted image",
477 #elif defined VISP_HAVE_GTK
478  vpDisplayGTK d_undist(I_undist, I.getWidth() / vpDisplay::getDownScalingFactor(I) + 100, 0, "Undistorted image",
480 #elif defined VISP_HAVE_OPENCV
481  vpDisplayOpenCV d_undist(I_undist, I.getWidth() / vpDisplay::getDownScalingFactor(I) + 100, 0,
482  "Undistorted image", vpDisplay::SCALE_AUTO);
483 #endif
484 
485  vpDisplay::setTitle(I, "Straight lines have to be straight (distorted image)");
486  vpDisplay::setTitle(I_undist, "Straight lines have to be straight (undistorted image)");
487  for (size_t idx = 0; idx < calib_info.size(); idx++) {
488  std::cout << "\nThis tool computes the line fitting error (mean distance error) on image points extracted from "
489  "the raw distorted image."
490  << std::endl;
491 
492  I = calib_info[idx].m_img;
493  vpImageTools::undistort(I, cam, I_undist);
494 
496  vpDisplay::display(I_undist);
497 
499  calib_info[idx].m_frame_name, vpColor::red);
501  "Draw lines from first / last points.", vpColor::red);
502  std::vector<vpImagePoint> grid_points = calib_info[idx].m_imPts;
503  for (int i = 0; i < s.boardSize.height; i++) {
504  std::vector<vpImagePoint> current_line(grid_points.begin() + i * s.boardSize.width,
505  grid_points.begin() + (i + 1) * s.boardSize.width);
506 
507  std::vector<vpImagePoint> current_line_undist = undistort(cam, current_line);
508  double a = 0, b = 0, c = 0;
509  double line_fitting_error = vpMath::lineFitting(current_line, a, b, c);
510  double line_fitting_error_undist = vpMath::lineFitting(current_line_undist, a, b, c);
511  std::cout << calib_info[idx].m_frame_name << " line " << i + 1
512  << " fitting error on distorted points: " << line_fitting_error
513  << " ; on undistorted points: " << line_fitting_error_undist << std::endl;
514 
515  vpImagePoint ip1 = current_line.front();
516  vpImagePoint ip2 = current_line.back();
517  vpDisplay::displayLine(I, ip1, ip2, vpColor::red);
518  }
519 
520  std::cout << "\nThis tool computes the line fitting error (mean distance error) on image points extracted from "
521  "the undistorted image"
522  << " (vpImageTools::undistort())." << std::endl;
523  cv::Mat cvI;
524  std::vector<cv::Point2f> pointBuf;
525  vpImageConvert::convert(I_undist, cvI);
526 
527  bool found = extractCalibrationPoints(s, cvI, pointBuf);
528  if (found) {
529  std::vector<vpImagePoint> grid_points;
530  for (unsigned int i = 0; i < pointBuf.size(); i++) {
531  vpImagePoint ip(pointBuf[i].y, pointBuf[i].x);
532  grid_points.push_back(ip);
533  }
534 
536  15 * vpDisplay::getDownScalingFactor(I_undist),
537  calib_info[idx].m_frame_name + std::string(" undistorted"), vpColor::red);
539  15 * vpDisplay::getDownScalingFactor(I_undist), "Draw lines from first / last points.",
540  vpColor::red);
541  for (int i = 0; i < s.boardSize.height; i++) {
542  std::vector<vpImagePoint> current_line(grid_points.begin() + i * s.boardSize.width,
543  grid_points.begin() + (i + 1) * s.boardSize.width);
544 
545  double a = 0, b = 0, c = 0;
546  double line_fitting_error = vpMath::lineFitting(current_line, a, b, c);
547  std::cout << calib_info[idx].m_frame_name << " undistorted image, line " << i + 1
548  << " fitting error: " << line_fitting_error << std::endl;
549 
550  vpImagePoint ip1 = current_line.front();
551  vpImagePoint ip2 = current_line.back();
552  vpDisplay::displayLine(I_undist, ip1, ip2, vpColor::red);
553  }
554  } else {
555  std::string msg("Unable to detect grid on undistorted image");
556  std::cout << msg << std::endl;
557  std::cout << "Check that the grid is not too close to the image edges" << std::endl;
559  15 * vpDisplay::getDownScalingFactor(I_undist),
560  calib_info[idx].m_frame_name + std::string(" undistorted"), vpColor::red);
562  15 * vpDisplay::getDownScalingFactor(I_undist), msg, vpColor::red);
563  }
564 
566  15 * vpDisplay::getDownScalingFactor(I), "Click to continue...", vpColor::red);
567  vpDisplay::flush(I);
568  vpDisplay::flush(I_undist);
570  }
571 
572  std::cout << std::endl;
573  vpXmlParserCamera xml;
574 
575  // Camera poses
576  ss_additional_info << "<camera_poses>";
577  for (size_t i = 0; i < calibrator.size(); i++) {
578  vpPoseVector pose(calibrator[i].cMo);
579  ss_additional_info << "<cMo>" << pose.t() << "</cMo>";
580  }
581  for (size_t i = 0; i < calibrator.size(); i++) {
582  vpPoseVector pose(calibrator[i].cMo_dist);
583  ss_additional_info << "<cMo_dist>" << pose.t() << "</cMo_dist>";
584  }
585  ss_additional_info << "</camera_poses>";
586 
587  if (xml.save(cam, opt_output_file_name.c_str(), opt_camera_name, I.getWidth(), I.getHeight(),
588  ss_additional_info.str()) == vpXmlParserCamera::SEQUENCE_OK)
589  std::cout << "Camera parameters without distortion successfully saved in \"" << opt_output_file_name << "\""
590  << std::endl;
591  else {
592  std::cout << "Failed to save the camera parameters without distortion in \"" << opt_output_file_name << "\""
593  << std::endl;
594  std::cout << "A file with the same name exists. Remove it to be able "
595  "to save the parameters..."
596  << std::endl;
597  }
598  std::cout << std::endl;
599  std::cout << "Estimated pose using vpPoseVector format: [tx ty tz tux tuy tuz] with translation in meter and "
600  "rotation in rad"
601  << std::endl;
602  for (unsigned int i = 0; i < calibrator.size(); i++)
603  std::cout << "Estimated pose on input data extracted from " << calib_info[i].m_frame_name << ": "
604  << vpPoseVector(calibrator[i].cMo_dist).t() << std::endl;
605  } else {
606  std::cout << "Calibration with distortion failed." << std::endl;
607  return EXIT_FAILURE;
608  }
609 
610  return EXIT_SUCCESS;
611  } catch (const vpException &e) {
612  std::cout << "Catch an exception: " << e << std::endl;
613  return EXIT_FAILURE;
614  }
615 }
616 #else
617 int main()
618 {
619  std::cout << "OpenCV 2.3.0 or higher is requested to run the calibration." << std::endl;
620  std::cout << "Tip:" << std::endl;
621  std::cout << "- Install OpenCV, configure again ViSP using cmake and build again this example" << std::endl;
622  return EXIT_SUCCESS;
623 }
624 #endif
VISP_EXPORT int wait(double t0, double t)
Definition: vpTime.cpp:173
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static double lineFitting(const std::vector< vpImagePoint > &imPts, double &a, double &b, double &c)
Definition: vpMath.cpp:328
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
double getResidual(void) const
get the residual in pixels
int computeCalibration(vpCalibrationMethodType method, vpHomogeneousMatrix &cMo_est, vpCameraParameters &cam_est, bool verbose=false)
Implementation of an homogeneous matrix and operations on such kind of matrices.
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
void setAspectRatio(double aspect_ratio)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:134
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
error that can be emited by ViSP classes.
Definition: vpException.h:71
int addPoint(double X, double Y, double Z, vpImagePoint &ip)
Tools for perspective camera calibration.
Definition: vpCalibration.h:71
XML parser to load and save intrinsic camera parameters.
static const vpColor green
Definition: vpColor.h:220
static void flush(const vpImage< unsigned char > &I)
VISP_EXPORT std::string getDateTime(const std::string &format="%Y/%m/%d %H:%M:%S")
Definition: vpTime.cpp:358
static const vpColor red
Definition: vpColor.h:217
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:81
static void setLambda(const double &lambda)
set the gain for the virtual visual servoing algorithm
void open(vpImage< vpRGBa > &I)
static void display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Generic class defining intrinsic camera parameters.
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:134
void acquire(vpImage< vpRGBa > &I)
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1510
int parse(vpCameraParameters &cam, const std::string &filename, const std::string &camera_name, const vpCameraParameters::vpCameraParametersProjType &projModel, unsigned int image_width=0, unsigned int image_height=0)
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
static void undistort(const vpImage< Type > &I, const vpCameraParameters &cam, vpImage< Type > &newI, unsigned int nThreads=2)
Definition: vpImageTools.h:645
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
long getFrameIndex() const
unsigned int getHeight() const
Definition: vpImage.h:188
double get_x() const
Get the point x coordinate in the image plane.
Definition: vpPoint.cpp:470
unsigned int getDownScalingFactor()
Definition: vpDisplay.h:235
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:151
int save(const vpCameraParameters &cam, const std::string &filename, const std::string &camera_name, unsigned int image_width=0, unsigned int image_height=0, const std::string &additionalInfo="")
double get_y() const
Get the point y coordinate in the image plane.
Definition: vpPoint.cpp:472
const std::string & getStringMessage() const
Send a reference (constant) related the error message (can be empty).
Definition: vpException.cpp:92
vpRowVector t() const
void setFileName(const std::string &filename)
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:802
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:87
static int computeCalibrationMulti(vpCalibrationMethodType method, std::vector< vpCalibration > &table_cal, vpCameraParameters &cam, double &globalReprojectionError, bool verbose=false)
static void setTitle(const vpImage< unsigned char > &I, const std::string &windowtitle)
unsigned int getWidth() const
Definition: vpImage.h:246
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)