Visual Servoing Platform  version 3.5.0
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
Tools for perspective camera calibration.
Definition: vpCalibration.h:72
static void setLambda(const double &lambda)
set the gain for the virtual visual servoing algorithm
int computeCalibration(vpCalibrationMethodType method, vpHomogeneousMatrix &cMo_est, vpCameraParameters &cam_est, bool verbose=false)
double getResidual(void) const
get the residual in pixels
int addPoint(double X, double Y, double Z, vpImagePoint &ip)
static int computeCalibrationMulti(vpCalibrationMethodType method, std::vector< vpCalibration > &table_cal, vpCameraParameters &cam, double &globalReprojectionError, bool verbose=false)
void setAspectRatio(double aspect_ratio)
Generic class defining intrinsic camera parameters.
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
static const vpColor red
Definition: vpColor.h:217
static const vpColor green
Definition: vpColor.h:220
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:129
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:135
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:135
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void setTitle(const vpImage< unsigned char > &I, const std::string &windowtitle)
static void flush(const vpImage< unsigned char > &I)
@ SCALE_AUTO
Definition: vpDisplay.h:183
unsigned int getDownScalingFactor()
Definition: vpDisplay.h:235
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emited by ViSP classes.
Definition: vpException.h:72
const std::string & getStringMessage() const
Send a reference (constant) related the error message (can be empty).
Definition: vpException.cpp:92
Implementation of an homogeneous matrix and operations on such kind of matrices.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
static void undistort(const vpImage< Type > &I, const vpCameraParameters &cam, vpImage< Type > &newI, unsigned int nThreads=2)
Definition: vpImageTools.h:645
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getHeight() const
Definition: vpImage.h:188
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:802
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1510
static double lineFitting(const std::vector< vpImagePoint > &imPts, double &a, double &b, double &c)
Definition: vpMath.cpp:328
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:82
double get_y() const
Get the point y coordinate in the image plane.
Definition: vpPoint.cpp:472
double get_x() const
Get the point x coordinate in the image plane.
Definition: vpPoint.cpp:470
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:152
vpRowVector t() const
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
void acquire(vpImage< vpRGBa > &I)
void open(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)
long getFrameIndex() const
XML parser to load and save intrinsic camera parameters.
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="")
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)
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT std::string getDateTime(const std::string &format="%Y/%m/%d %H:%M:%S")