Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
visp-calibrate-camera.cpp

This app allows to calibrate camera intrinsic parameters.

/*
* ViSP, open source Visual Servoing Platform software.
* Copyright (C) 2005 - 2025 by Inria. All rights reserved.
*
* This software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* See the file LICENSE.txt at the root directory of this source
* distribution for additional information about the GNU GPL.
*
* For using ViSP with software that can not be combined with the GNU
* GPL, please contact Inria about acquiring a ViSP Professional
* Edition License.
*
* See https://visp.inria.fr for more information.
*
* This software was developed at:
* Inria Rennes - Bretagne Atlantique
* Campus Universitaire de Beaulieu
* 35042 Rennes Cedex
* France
*
* If you have questions regarding the use of this file, please contact
* Inria at visp@inria.fr
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Description:
* Camera calibration with chessboard or circle calibration grid.
*/
#include <iostream>
#include <visp3/core/vpConfig.h>
#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC) && defined(VISP_HAVE_PUGIXML) \
&& (((VISP_HAVE_OPENCV_VERSION < 0x050000) && defined(HAVE_OPENCV_CALIB3D)) || ((VISP_HAVE_OPENCV_VERSION >= 0x050000) && defined(HAVE_OPENCV_3D)))
#include <map>
#if defined(HAVE_OPENCV_CALIB3D)
#include <opencv2/calib3d/calib3d.hpp>
#elif defined(HAVE_OPENCV_CALIB)
#include <opencv2/calib.hpp>
#endif
#if defined(HAVE_OPENCV_CONTRIB)
#include <opencv2/contrib/contrib.hpp> // Needed on Ubuntu 16.04 with OpenCV 2.4.9.1
#endif
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <visp3/vision/vpCalibration.h>
#include <visp3/core/vpImageTools.h>
#include <visp3/core/vpIoTools.h>
#include <visp3/core/vpMeterPixelConversion.h>
#include <visp3/core/vpPixelMeterConversion.h>
#include <visp3/core/vpPoint.h>
#include <visp3/core/vpXmlParserCamera.h>
#include <visp3/gui/vpDisplayFactory.h>
#include <visp3/io/vpVideoReader.h>
#include "calibration-helper.hpp"
using namespace calib_helper;
void usage(const char *argv[], int error)
{
std::cout << "Synopsis" << std::endl
<< " " << argv[0]
<< " <configuration file>.cfg"
<< " [--init-from-xml <camera-init.xml>]"
<< " [--camera-name <name>]"
<< " [--aspect-ratio <ratio>]"
<< " [--output <file.xml>]"
<< " [--help, -h]" << std::endl
<< std::endl;
std::cout << "Description" << std::endl
<< " <configuration file>.cfg" << std::endl
<< " Configuration file. See example in \"default-chessboard.cfg\" or in \"default-circles.cfg\"." << std::endl
<< " Default: \"default.cfg\"." << std::endl
<< std::endl
<< " --init-from-xml <camera-init.xml>" << std::endl
<< " XML file that contains camera parameters used to initialize the calibration process." << std::endl
<< std::endl
<< " --camera-name <name>" << std::endl
<< " Camera name in the XML file set using \"--init-from-xml\" option." << std::endl
<< " Default: \"Camera\"." << std::endl
<< std::endl
<< " --aspect-ratio <ratio>" << std::endl
<< " Pixel aspect ratio. To estimate px = py, use \"--aspect-ratio 1\" option. Set to -1" << std::endl
<< " to unset any constraint for px and py parameters. " << std::endl
<< " Default: -1." << std::endl
<< std::endl
<< " --output <file.xml>" << std::endl
<< " XML file containing estimated camera parameters." << std::endl
<< " Default: \"camera.xml\"." << std::endl
<< std::endl
<< " --help, -h" << std::endl
<< " Print this helper message." << std::endl
<< std::endl;
if (error) {
std::cout << "Error" << std::endl
<< " "
<< "Unsupported parameter " << argv[error] << std::endl;
}
}
int main(int argc, const char *argv[])
{
#if defined(ENABLE_VISP_NAMESPACE)
using namespace VISP_NAMESPACE_NAME;
#endif
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
vpDisplay *d = nullptr;
#endif
try {
if (argc == 1) {
usage(argv, 0);
return EXIT_SUCCESS;
}
std::string opt_output_file_name = "camera.xml";
Settings s;
const std::string opt_inputSettingsFile = argc > 1 ? argv[1] : "default.cfg";
std::string opt_init_camera_xml_file;
std::string opt_camera_name = "Camera";
double opt_aspect_ratio = -1; // Not used
for (int i = 2; i < argc; i++) {
if (std::string(argv[i]) == "--init-from-xml" && i + 1 < argc) {
opt_init_camera_xml_file = std::string(argv[++i]);
}
else if (std::string(argv[i]) == "--camera-name" && i + 1 < argc) {
opt_camera_name = std::string(argv[++i]);
}
else if (std::string(argv[i]) == "--output" && i + 1 < argc) {
opt_output_file_name = std::string(argv[++i]);
}
else if (std::string(argv[i]) == "--aspect-ratio" && i + 1 < argc) {
opt_aspect_ratio = std::atof(argv[++i]);
}
else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
usage(argv, 0);
return EXIT_SUCCESS;
}
else {
usage(argv, i);
return EXIT_FAILURE;
}
}
std::cout << "Settings from config file: " << argv[1] << std::endl;
if (!s.read(opt_inputSettingsFile)) {
std::cout << "Could not open the configuration file: \"" << opt_inputSettingsFile << "\"" << std::endl;
usage(argv, 0);
return EXIT_FAILURE;
}
if (!s.goodInput) {
std::cout << "Invalid input detected. Application stopping. " << std::endl;
return EXIT_FAILURE;
}
std::cout << "\nSettings from command line options: " << std::endl;
if (!opt_init_camera_xml_file.empty()) {
std::cout << "Init parameters: " << opt_init_camera_xml_file << std::endl;
}
std::cout << "Ouput xml file : " << opt_output_file_name << std::endl;
std::cout << "Camera name : " << opt_camera_name << std::endl;
// Check if output file name exists
if (vpIoTools::checkFilename(opt_output_file_name)) {
std::cout << "\nOutput file name " << opt_output_file_name << " already exists." << std::endl;
std::cout << "Remove this file or change output file name using [--output <file.xml>] command line option."
<< std::endl;
return EXIT_SUCCESS;
}
// Start the calibration code
vpVideoReader reader;
reader.setFileName(s.input);
try {
reader.open(I);
}
catch (const vpException &e) {
std::cout << "Catch an exception: " << e.getStringMessage() << std::endl;
std::cout << "Check if input images name \"" << s.input << "\" set in " << opt_inputSettingsFile
<< " config file is correct..." << std::endl;
return EXIT_FAILURE;
}
#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
std::shared_ptr<vpDisplay> d = vpDisplayFactory::createDisplay(I, vpDisplay::SCALE_AUTO);
#else
#endif
bool init_from_xml = false;
if (!opt_init_camera_xml_file.empty()) {
if (!vpIoTools::checkFilename(opt_init_camera_xml_file)) {
std::cout << "Input camera file \"" << opt_init_camera_xml_file << "\" doesn't exist!" << std::endl;
std::cout << "Modify [--init-from-xml <camera-init.xml>] option value" << std::endl;
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
if (display != nullptr) {
delete display;
}
#endif
return EXIT_FAILURE;
}
init_from_xml = true;
}
if (init_from_xml) {
std::cout << "Initialize camera parameters from xml file: " << opt_init_camera_xml_file << std::endl;
if (parser.parse(cam_init, opt_init_camera_xml_file, opt_camera_name,
std::cout << "Unable to find camera with name \"" << opt_camera_name
<< "\" in file: " << opt_init_camera_xml_file << std::endl;
std::cout << "Modify [--camera-name <name>] option value" << std::endl;
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
if (display != nullptr) {
delete display;
}
#endif
return EXIT_FAILURE;
}
}
else {
std::cout << "Initialize camera parameters with default values " << std::endl;
// Initialize camera parameters
double px = cam_init.get_px();
double py = cam_init.get_py();
// Set (u0,v0) in the middle of the image
double u0 = I.getWidth() / 2;
double v0 = I.getHeight() / 2;
cam_init.initPersProjWithoutDistortion(px, py, u0, v0);
}
std::cout << "Camera parameters used for initialization:\n" << cam_init << std::endl;
std::vector<vpPoint> model;
std::vector<vpCalibration> calibrator;
for (int i = 0; i < s.boardSize.height; i++) {
for (int j = 0; j < s.boardSize.width; j++) {
model.push_back(vpPoint(j * s.squareSize, i * s.squareSize, 0));
}
}
std::vector<CalibInfo> calib_info;
std::multimap<double, vpCameraParameters, std::less<double> > map_cam_sorted; // Sorted by residual
map_cam_sorted.insert(std::make_pair(1000, cam_init));
do {
reader.acquire(I);
long frame_index = reader.getFrameIndex();
std::string filename = vpIoTools::formatString(s.input, frame_index);
std::string frame_name = vpIoTools::getName(filename);
cv::Mat cvI;
std::vector<cv::Point2f> pointBuf;
std::cout << "Process frame: " << frame_name << std::flush;
bool found = extractCalibrationPoints(s, cvI, pointBuf);
std::cout << ", grid detection status: " << found;
if (!found)
std::cout << ", image rejected" << std::endl;
else
std::cout << ", image used as input data" << std::endl;
if (found) { // If image processing done with success
vpDisplay::setTitle(I, frame_name);
std::vector<vpImagePoint> data;
for (unsigned int i = 0; i < pointBuf.size(); i++) {
vpImagePoint ip(pointBuf[i].y, pointBuf[i].x);
data.push_back(ip);
}
// Calibration on a single mono image
std::vector<vpPoint> calib_points;
calib.setLambda(0.5);
calib.setAspectRatio(opt_aspect_ratio);
for (unsigned int i = 0; i < model.size(); i++) {
calib.addPoint(model[i].get_oX(), model[i].get_oY(), model[i].get_oZ(), data[i]);
calib_points.push_back(vpPoint(model[i].get_oX(), model[i].get_oY(), model[i].get_oZ()));
calib_points.back().set_x(data[i].get_u());
calib_points.back().set_y(data[i].get_v());
}
bool calib_status = false;
std::multimap<double, vpCameraParameters>::const_iterator it_cam;
for (it_cam = map_cam_sorted.begin(); it_cam != map_cam_sorted.end(); ++it_cam) {
vpCameraParameters cam = it_cam->second;
if (calib.computeCalibration(vpCalibration::CALIB_VIRTUAL_VS, cMo, cam, false) == EXIT_SUCCESS) {
calibrator.push_back(calib);
// Add calibration info
calib_info.push_back(CalibInfo(I, calib_points, data, frame_name));
calib_status = true;
double residual = calib.getResidual();
map_cam_sorted.insert(std::make_pair(residual, cam));
break;
}
}
if (!calib_status) {
std::cout << "frame: " << frame_name << ", unable to calibrate from single image, image rejected"
<< std::endl;
found = false;
}
}
if (found)
"Image processing succeed", vpColor::green);
else
"Image processing failed", vpColor::green);
if (s.tempo > 10.f) {
"A click to process the next image", vpColor::green);
}
else {
vpTime::wait(s.tempo * 1000);
}
} while (!reader.end());
// Now we consider the multi image calibration
// Calibrate by a non linear method based on virtual visual servoing
if (calibrator.empty()) {
std::cerr << "Unable to calibrate. Image processing failed !" << std::endl;
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
if (display != nullptr) {
delete display;
}
#endif
return EXIT_FAILURE;
}
// Display calibration pattern occupancy
drawCalibrationOccupancy(I, calib_info, s.boardSize.width);
cv::Mat1b img(I.getHeight(), I.getWidth());
cv::Mat3b imgColor(I.getHeight(), I.getWidth());
cv::applyColorMap(img, imgColor, cv::COLORMAP_JET);
// Draw calibration board corners
for (size_t idx1 = 0; idx1 < calib_info.size(); idx1++) {
const CalibInfo &calib = calib_info[idx1];
for (size_t idx2 = 0; idx2 < calib.m_imPts.size(); idx2++) {
const vpImagePoint &imPt = calib.m_imPts[idx2];
cv::rectangle(imgColor,
cv::Rect(static_cast<int>(imPt.get_u() - 2), static_cast<int>(imPt.get_v() - 2),
cv::Scalar(0, 0, 0), -1);
}
}
vpImage<vpRGBa> I_color;
vpImageConvert::convert(imgColor, I_color);
d->close(I);
d->init(I_color, 0, 0, "Calibration pattern occupancy");
15 * vpDisplay::getDownScalingFactor(I_color), "Calibration pattern occupancy in the image",
if (s.tempo > 10.f) {
15 * vpDisplay::getDownScalingFactor(I_color), "Click to continue...", vpColor::red);
vpDisplay::flush(I_color);
}
else {
vpDisplay::flush(I_color);
vpTime::wait(s.tempo * 1000);
}
d->close(I_color);
std::stringstream ss_additional_info;
ss_additional_info << "<date>" << vpTime::getDateTime() << "</date>";
ss_additional_info << "<nb_calibration_images>" << calibrator.size() << "</nb_calibration_images>";
ss_additional_info << "<calibration_pattern_type>";
switch (s.calibrationPattern) {
case Settings::CHESSBOARD:
ss_additional_info << "Chessboard";
break;
case Settings::CIRCLES_GRID:
ss_additional_info << "Circles grid";
break;
case Settings::UNDEFINED:
default:
ss_additional_info << "Undefined";
break;
}
ss_additional_info << "</calibration_pattern_type>";
ss_additional_info << "<board_size>" << s.boardSize.width << "x" << s.boardSize.height << "</board_size>";
ss_additional_info << "<square_size>" << s.squareSize << "</square_size>";
double error;
// Initialize with camera parameter that has the lowest residual
vpCameraParameters cam = map_cam_sorted.begin()->second;
std::cout << "\nCalibration without distortion in progress on " << calibrator.size() << " images..." << std::endl;
EXIT_SUCCESS) {
std::cout << cam << std::endl;
d->init(I);
vpDisplay::setTitle(I, "Without distortion results");
ss_additional_info << "<reprojection_error><without_distortion>";
for (size_t i = 0; i < calibrator.size(); i++) {
double reproj_error = sqrt(calibrator[i].getResidual() / calibrator[i].get_npt());
const CalibInfo &calib = calib_info[i];
std::cout << "Image " << calib.m_frame_name << " reprojection error: " << reproj_error << std::endl;
ss_additional_info << "<image>" << reproj_error << "</image>";
I = calib.m_img;
std::ostringstream ss;
ss << "Reprojection error: " << reproj_error;
calib.m_frame_name, vpColor::red);
ss.str(), vpColor::red);
"Extracted points", vpColor::red);
"Projected points", vpColor::green);
for (size_t idx = 0; idx < calib.m_points.size(); idx++) {
vpPoint pt = calib.m_points[idx];
pt.project(calibrator[i].cMo);
}
if (s.tempo > 10.f) {
15 * vpDisplay::getDownScalingFactor(I), "Click to continue...", vpColor::red);
}
else {
vpTime::wait(s.tempo * 1000);
}
}
std::cout << "\nGlobal reprojection error: " << error << std::endl;
ss_additional_info << "<global_reprojection_error>" << error << "</global_reprojection_error>";
ss_additional_info << "</without_distortion>";
if (xml.save(cam, opt_output_file_name.c_str(), opt_camera_name, I.getWidth(), I.getHeight()) ==
std::cout << "Camera parameters without distortion successfully saved in \"" << opt_output_file_name << "\""
<< std::endl;
else {
std::cout << "Failed to save the camera parameters without distortion in \"" << opt_output_file_name << "\""
<< std::endl;
std::cout << "A file with the same name exists. Remove it to be able "
"to save the parameters..."
<< std::endl;
}
}
else {
std::cout << "Calibration without distortion failed." << std::endl;
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
if (display != nullptr) {
delete display;
}
#endif
return EXIT_FAILURE;
}
vpCameraParameters cam_without_dist = cam;
std::vector<vpCalibration> calibrator_without_dist = calibrator;
std::cout << "\n\nCalibration with distortion in progress on " << calibrator.size() << " images..." << std::endl;
EXIT_SUCCESS) {
std::cout << cam << std::endl;
vpDisplay::setTitle(I, "With distortion results");
ss_additional_info << "<with_distortion>";
for (size_t i = 0; i < calibrator.size(); i++) {
double reproj_error = sqrt(calibrator[i].getResidual_dist() / calibrator[i].get_npt());
const CalibInfo &calib = calib_info[i];
std::cout << "Image " << calib.m_frame_name << " reprojection error: " << reproj_error << std::endl;
ss_additional_info << "<image>" << reproj_error << "</image>";
I = calib.m_img;
std::ostringstream ss;
ss << "Reprojection error: " << reproj_error;
calib.m_frame_name, vpColor::red);
ss.str(), vpColor::red);
"Extracted points", vpColor::red);
"Projected points", vpColor::green);
for (size_t idx = 0; idx < calib.m_points.size(); idx++) {
vpPoint pt = calib.m_points[idx];
pt.project(calibrator[i].cMo_dist);
}
if (s.tempo > 10.f) {
15 * vpDisplay::getDownScalingFactor(I), "Click to continue...", vpColor::red);
}
else {
vpTime::wait(s.tempo * 1000);
}
}
std::cout << "\nGlobal reprojection error: " << error << std::endl;
ss_additional_info << "<global_reprojection_error>" << error << "</global_reprojection_error>";
ss_additional_info << "</with_distortion></reprojection_error>";
vpImage<unsigned char> I_dist_undist(I.getHeight(), 2 * I.getWidth());
d->close(I);
d->init(I_dist_undist, 0, 0, "Straight lines have to be straight - distorted image / undistorted image");
for (size_t idx = 0; idx < calib_info.size(); idx++) {
std::cout << "\nThis tool computes the line fitting error (mean distance error) on image points extracted from "
"the raw distorted image."
<< std::endl;
I = calib_info[idx].m_img;
vpImageTools::undistort(I, cam, I_undist);
I_dist_undist.insert(I, vpImagePoint(0, 0));
I_dist_undist.insert(I_undist, vpImagePoint(0, I.getWidth()));
vpDisplay::display(I_dist_undist);
vpDisplay::displayText(I_dist_undist, 15 * vpDisplay::getDownScalingFactor(I_dist_undist),
15 * vpDisplay::getDownScalingFactor(I_dist_undist),
calib_info[idx].m_frame_name + std::string(" distorted"), vpColor::red);
vpDisplay::displayText(I_dist_undist, 30 * vpDisplay::getDownScalingFactor(I_dist_undist),
15 * vpDisplay::getDownScalingFactor(I_dist_undist),
"Draw lines from first / last points.", vpColor::red);
std::vector<vpImagePoint> grid_points = calib_info[idx].m_imPts;
for (int i = 0; i < s.boardSize.height; i++) {
std::vector<vpImagePoint> current_line(grid_points.begin() + i * s.boardSize.width,
grid_points.begin() + (i + 1) * s.boardSize.width);
std::vector<vpImagePoint> current_line_undist = undistort(cam, current_line);
double a = 0, b = 0, c = 0;
double line_fitting_error = vpMath::lineFitting(current_line, a, b, c);
double line_fitting_error_undist = vpMath::lineFitting(current_line_undist, a, b, c);
std::cout << calib_info[idx].m_frame_name << " line " << i + 1
<< " fitting error on distorted points: " << line_fitting_error
<< " ; on undistorted points: " << line_fitting_error_undist << std::endl;
vpImagePoint ip1 = current_line.front();
vpImagePoint ip2 = current_line.back();
vpDisplay::displayLine(I_dist_undist, ip1, ip2, vpColor::red);
}
std::cout << "\nThis tool computes the line fitting error (mean distance error) on image points extracted from "
"the undistorted image"
<< " (vpImageTools::undistort())." << std::endl;
cv::Mat cvI;
std::vector<cv::Point2f> pointBuf;
vpImageConvert::convert(I_undist, cvI);
bool found = extractCalibrationPoints(s, cvI, pointBuf);
if (found) {
std::vector<vpImagePoint> grid_points;
for (unsigned int i = 0; i < pointBuf.size(); i++) {
vpImagePoint ip(pointBuf[i].y, pointBuf[i].x);
grid_points.push_back(ip);
}
vpDisplay::displayText(I_dist_undist, 15 * vpDisplay::getDownScalingFactor(I_dist_undist),
I.getWidth() + 15 * vpDisplay::getDownScalingFactor(I_dist_undist),
calib_info[idx].m_frame_name + std::string(" undistorted"), vpColor::red);
for (int i = 0; i < s.boardSize.height; i++) {
std::vector<vpImagePoint> current_line(grid_points.begin() + i * s.boardSize.width,
grid_points.begin() + (i + 1) * s.boardSize.width);
double a = 0, b = 0, c = 0;
double line_fitting_error = vpMath::lineFitting(current_line, a, b, c);
std::cout << calib_info[idx].m_frame_name << " undistorted image, line " << i + 1
<< " fitting error: " << line_fitting_error << std::endl;
vpImagePoint ip1 = current_line.front() + vpImagePoint(0, I.getWidth());
vpImagePoint ip2 = current_line.back() + vpImagePoint(0, I.getWidth());
vpDisplay::displayLine(I_dist_undist, ip1, ip2, vpColor::red);
}
}
else {
std::string msg("Unable to detect grid on undistorted image");
std::cout << msg << std::endl;
std::cout << "Check that the grid is not too close to the image edges" << std::endl;
vpDisplay::displayText(I_dist_undist, 15 * vpDisplay::getDownScalingFactor(I_dist_undist),
15 * vpDisplay::getDownScalingFactor(I_dist_undist),
calib_info[idx].m_frame_name + std::string(" undistorted"), vpColor::red);
vpDisplay::displayText(I_dist_undist, 30 * vpDisplay::getDownScalingFactor(I_dist_undist),
15 * vpDisplay::getDownScalingFactor(I_dist_undist), msg, vpColor::red);
}
if (s.tempo > 10.f) {
I_dist_undist, I_dist_undist.getHeight() - 20 * vpDisplay::getDownScalingFactor(I_dist_undist),
15 * vpDisplay::getDownScalingFactor(I_dist_undist), "Click to continue...", vpColor::red);
vpDisplay::flush(I_dist_undist);
vpDisplay::getClick(I_dist_undist);
}
else {
vpDisplay::flush(I_dist_undist);
vpTime::wait(s.tempo * 1000);
}
}
std::cout << std::endl;
// Camera poses
ss_additional_info << "<camera_poses>";
for (size_t i = 0; i < calibrator.size(); i++) {
vpPoseVector pose(calibrator[i].cMo);
ss_additional_info << "<cMo>" << pose.t() << "</cMo>";
}
for (size_t i = 0; i < calibrator.size(); i++) {
vpPoseVector pose(calibrator[i].cMo_dist);
ss_additional_info << "<cMo_dist>" << pose.t() << "</cMo_dist>";
}
ss_additional_info << "</camera_poses>";
if (xml.save(cam, opt_output_file_name.c_str(), opt_camera_name, I.getWidth(), I.getHeight(),
ss_additional_info.str()) == vpXmlParserCamera::SEQUENCE_OK)
std::cout << "Camera parameters without distortion successfully saved in \"" << opt_output_file_name << "\""
<< std::endl;
else {
std::cout << "Failed to save the camera parameters without distortion in \"" << opt_output_file_name << "\""
<< std::endl;
std::cout << "A file with the same name exists. Remove it to be able "
"to save the parameters..."
<< std::endl;
}
std::cout << std::endl;
std::cout << "Estimated pose using vpPoseVector format: [tx ty tz tux tuy tuz] with translation in meter and "
"rotation in rad"
<< std::endl;
for (unsigned int i = 0; i < calibrator.size(); i++)
std::cout << "Estimated pose on input data extracted from " << calib_info[i].m_frame_name << ": "
<< vpPoseVector(calibrator[i].cMo_dist).t() << std::endl;
}
else {
std::cout << "Calibration with distortion failed." << std::endl;
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
if (display != nullptr) {
delete display;
}
#endif
return EXIT_FAILURE;
}
std::cout << "\nCamera calibration succeeded. Results are saved in " << "\"" << opt_output_file_name << "\"" << std::endl;
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
if (display != nullptr) {
delete display;
}
#endif
return EXIT_SUCCESS;
}
catch (const vpException &e) {
std::cout << "Catch an exception: " << e << std::endl;
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
if (display != nullptr) {
delete display;
}
#endif
return EXIT_FAILURE;
}
}
#else
int main()
{
#if !defined(HAVE_OPENCV_IMGPROC)
std::cout << "This example requires OpenCV imgproc module." << std::endl;
#endif
#if !defined(HAVE_OPENCV_HIGHGUI)
std::cout << "This example requires OpenCV highgui module." << std::endl;
#endif
#if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x050000) && !defined(HAVE_OPENCV_CALIB3D)
std::cout << "This example requires OpenCV calib3d module." << std::endl;
#endif
#if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x050000) && !defined(HAVE_OPENCV_3D)
std::cout << "This example requires OpenCV 3d module." << std::endl;
#endif
#if !defined(VISP_HAVE_PUGIXML)
std::cout << "pugixml built-in 3rdparty is requested to run the calibration." << std::endl;
#endif
return EXIT_SUCCESS;
}
#endif
Tools for perspective camera intrinsic parameters calibration.
static void setLambda(const double &lambda)
int computeCalibration(vpCalibrationMethodType method, vpHomogeneousMatrix &cMo_est, vpCameraParameters &cam_est, bool verbose=false)
double getResidual(void) const
int addPoint(double X, double Y, double Z, vpImagePoint &ip)
static int computeCalibrationMulti(vpCalibrationMethodType method, std::vector< vpCalibration > &table_cal, vpCameraParameters &cam_est, 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)
@ perspectiveProjWithoutDistortion
Perspective projection without distortion model.
static const vpColor red
Definition vpColor.h:198
static const vpColor green
Definition vpColor.h:201
Class that defines generic functionalities for display.
Definition vpDisplay.h:171
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)
unsigned int getDownScalingFactor()
Definition vpDisplay.h:218
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emitted by ViSP classes.
Definition vpException.h:60
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 ...
double get_u() const
double get_v() const
static void undistort(const vpImage< Type > &I, const vpCameraParameters &cam, vpImage< Type > &newI, unsigned int nThreads=2)
Definition of the vpImage class member functions.
Definition vpImage.h:131
unsigned int getHeight() const
Definition vpImage.h:181
static bool checkFilename(const std::string &filename)
static std::string formatString(const std::string &name, unsigned int val)
static std::string getName(const std::string &pathname)
static double lineFitting(const std::vector< vpImagePoint > &imPts, double &a, double &b, double &c)
Definition vpMath.cpp:411
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:79
double get_y() const
Get the point y coordinate in the image plane.
Definition vpPoint.cpp:429
double get_x() const
Get the point x coordinate in the image plane.
Definition vpPoint.cpp:427
Implementation of a pose vector and operations on poses.
vpRowVector t() const
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
void open(vpImage< vpRGBa > &I) VP_OVERRIDE
void setFileName(const std::string &filename)
long getFrameIndex() const
void acquire(vpImage< vpRGBa > &I) VP_OVERRIDE
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="", bool verbose=true)
std::shared_ptr< vpDisplay > createDisplay()
Return a smart pointer vpDisplay specialization if a GUI library is available or nullptr otherwise.
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT std::string getDateTime(const std::string &format="%Y/%m/%d %H:%M:%S")