40 #include <visp3/core/vpConfig.h> 42 #if VISP_HAVE_OPENCV_VERSION >= 0x020300 44 #include <opencv2/calib3d/calib3d.hpp> 45 #include <opencv2/core/core.hpp> 46 #include <opencv2/highgui/highgui.hpp> 47 #include <opencv2/imgproc/imgproc.hpp> 49 #include <visp3/vision/vpCalibration.h> 51 #include <visp3/core/vpIoTools.h> 52 #include <visp3/core/vpPoint.h> 53 #include <visp3/core/vpXmlParserCamera.h> 54 #include <visp3/gui/vpDisplayD3D.h> 55 #include <visp3/gui/vpDisplayGDI.h> 56 #include <visp3/gui/vpDisplayGTK.h> 57 #include <visp3/gui/vpDisplayOpenCV.h> 58 #include <visp3/gui/vpDisplayX.h> 59 #include <visp3/io/vpVideoReader.h> 61 #ifndef DOXYGEN_SHOULD_SKIP_THIS 67 : boardSize(), calibrationPattern(UNDEFINED), squareSize(0.), input(), tempo(0.), goodInput(false), patternToUse()
69 boardSize = cv::Size(0, 0);
70 calibrationPattern = UNDEFINED;
75 enum Pattern { UNDEFINED, CHESSBOARD, CIRCLES_GRID };
77 bool read(
const std::string &filename)
89 std::cout <<
"grid width : " << boardSize.width << std::endl;
90 std::cout <<
"grid height: " << boardSize.height << std::endl;
91 std::cout <<
"square size: " << squareSize << std::endl;
92 std::cout <<
"pattern : " << patternToUse << std::endl;
93 std::cout <<
"input seq : " << input << std::endl;
94 std::cout <<
"tempo : " << tempo << std::endl;
101 if (boardSize.width <= 0 || boardSize.height <= 0) {
102 std::cerr <<
"Invalid Board size: " << boardSize.width <<
" " << boardSize.height << std::endl;
105 if (squareSize <= 10e-6) {
106 std::cerr <<
"Invalid square size " << squareSize << std::endl;
113 calibrationPattern = UNDEFINED;
114 if (patternToUse.compare(
"CHESSBOARD") == 0)
115 calibrationPattern = CHESSBOARD;
116 else if (patternToUse.compare(
"CIRCLES_GRID") == 0)
117 calibrationPattern = CIRCLES_GRID;
118 if (calibrationPattern == UNDEFINED) {
119 std::cerr <<
" Inexistent camera calibration mode: " << patternToUse << std::endl;
127 Pattern calibrationPattern;
137 std::string patternToUse;
141 int main(
int argc,
const char **argv)
144 std::string outputFileName =
"camera.xml";
146 const std::string inputSettingsFile = argc > 1 ? argv[1] :
"default.cfg";
148 if (!s.read(inputSettingsFile)) {
149 std::cout <<
"Could not open the configuration file: \"" << inputSettingsFile <<
"\"" << std::endl;
150 std::cout << std::endl <<
"Usage: " << argv[0] <<
" <configuration file>.cfg" << std::endl;
155 std::cout <<
"Invalid input detected. Application stopping. " << std::endl;
168 std::cout <<
"Check if input images name \"" << s.input <<
"\" set in " << inputSettingsFile <<
" config file is correct..." << std::endl;
174 #elif defined VISP_HAVE_GDI 176 #elif defined VISP_HAVE_GTK 178 #elif defined VISP_HAVE_OPENCV 192 std::vector<vpPoint> model;
193 std::vector<vpCalibration> calibrator;
195 for (
int i = 0; i < s.boardSize.height; i++) {
196 for (
int j = 0; j < s.boardSize.width; j++) {
197 model.push_back(
vpPoint(j * s.squareSize, i * s.squareSize, 0));
201 while (!reader.
end()) {
208 std::vector<cv::Point2f> pointBuf;
212 switch (s.calibrationPattern)
214 case Settings::CHESSBOARD:
216 found = findChessboardCorners(cvI, s.boardSize, pointBuf,
217 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
218 cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_FAST_CHECK |
219 cv::CALIB_CB_NORMALIZE_IMAGE);
221 CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK |
222 CV_CALIB_CB_NORMALIZE_IMAGE);
225 case Settings::CIRCLES_GRID:
227 found = findCirclesGrid(cvI, s.boardSize, pointBuf, cv::CALIB_CB_SYMMETRIC_GRID);
229 case Settings::UNDEFINED:
231 std::cout <<
"Unkown calibration grid " << std::endl;
235 std::cout <<
"frame: " << frame_index <<
", status: " << found;
237 std::cout <<
", image rejected" << std::endl;
239 std::cout <<
", image used as input data" << std::endl;
243 std::vector<vpImagePoint> data;
245 if (s.calibrationPattern == Settings::CHESSBOARD) {
247 cornerSubPix(cvI, pointBuf, cv::Size(11, 11), cv::Size(-1, -1),
248 #
if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
249 cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.1));
251 cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
254 std::stringstream ss;
255 ss <<
"image " << frame_index;
257 for (
unsigned int i = 0; i < pointBuf.size(); i++) {
267 for (
unsigned int i = 0; i < model.size(); i++) {
268 calib.
addPoint(model[i].get_oX(), model[i].get_oY(), model[i].get_oZ(), data[i]);
274 calibrator.push_back(calib);
283 if (s.tempo > 10.f) {
295 if (calibrator.empty()) {
296 std::cerr <<
"Unable to calibrate. Image processing failed !" << std::endl;
300 std::stringstream ss_additional_info;
302 ss_additional_info <<
"<nb_calibration_images>" << calibrator.size() <<
"</nb_calibration_images>";
303 ss_additional_info <<
"<calibration_pattern_type>";
305 switch (s.calibrationPattern) {
306 case Settings::CHESSBOARD:
307 ss_additional_info <<
"Chessboard";
310 case Settings::CIRCLES_GRID:
311 ss_additional_info <<
"Circles grid";
314 case Settings::UNDEFINED:
316 ss_additional_info <<
"Undefined";
319 ss_additional_info <<
"</calibration_pattern_type>";
320 ss_additional_info <<
"<board_size>" << s.boardSize.width <<
"x" << s.boardSize.height <<
"</board_size>";
321 ss_additional_info <<
"<square_size>" << s.squareSize <<
"</square_size>";
323 std::cout <<
"\nCalibration without distortion in progress on " << calibrator.size() <<
" images..." << std::endl;
326 std::cout << cam << std::endl;
327 std::cout <<
"Global reprojection error: " << error << std::endl;
328 ss_additional_info <<
"<global_reprojection_error><without_distortion>" << error <<
"</without_distortion>";
330 #ifdef VISP_HAVE_XML2 335 std::cout <<
"Camera parameters without distortion successfully saved in \"" << outputFileName <<
"\"" 338 std::cout <<
"Failed to save the camera parameters without distortion in \"" << outputFileName <<
"\"" 340 std::cout <<
"A file with the same name exists. Remove it to be able " 341 "to save the parameters..." 346 std::cout <<
"Calibration without distortion failed." << std::endl;
350 std::cout <<
"\nCalibration with distortion in progress on " << calibrator.size() <<
" images..." << std::endl;
353 std::cout << cam << std::endl;
354 std::cout <<
"Global reprojection error: " << error << std::endl;
355 ss_additional_info <<
"<with_distortion>" << error <<
"</with_distortion></global_reprojection_error>";
357 #ifdef VISP_HAVE_XML2 360 if (xml.
save(cam, outputFileName.c_str(),
"Camera", I.
getWidth(), I.
getHeight(), ss_additional_info.str()) ==
362 std::cout <<
"Camera parameters without distortion successfully saved in \"" << outputFileName <<
"\"" 365 std::cout <<
"Failed to save the camera parameters without distortion in \"" << outputFileName <<
"\"" 367 std::cout <<
"A file with the same name exists. Remove it to be able " 368 "to save the parameters..." 372 std::cout << std::endl;
373 for (
unsigned int i = 0; i < calibrator.size(); i++)
374 std::cout <<
"Estimated pose on input data " << i <<
": " <<
vpPoseVector(calibrator[i].cMo_dist).
t()
378 std::cout <<
"Calibration with distortion failed." << std::endl;
384 std::cout <<
"Catch an exception: " << e << std::endl;
391 std::cout <<
"OpenCV 2.3.0 or higher is requested to run the calibration." << std::endl;
392 std::cout <<
"Tip:" << std::endl;
393 std::cout <<
"- Install OpenCV, configure again ViSP using cmake and build again this example" << std::endl;
VISP_EXPORT int wait(double t0, double t)
long getFrameIndex() const
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
unsigned int getWidth() const
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
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.
Display for windows using GDI (available on any windows 32 platform).
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...
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.
int addPoint(double X, double Y, double Z, vpImagePoint &ip)
Tools for perspective camera calibration.
XML parser to load and save intrinsic camera parameters.
static const vpColor green
static void flush(const vpImage< unsigned char > &I)
VISP_EXPORT std::string getDateTime(const std::string &format="%Y/%m/%d %H:%M:%S")
Class that defines what is a point.
static void setLambda(const double &lambda)
set the gain for the virtual visual servoing algorithm
void initPersProjWithoutDistortion(const double px, const double py, const double u0, const double v0)
void open(vpImage< vpRGBa > &I)
int clearPoint()
Suppress all the point in the array of point.
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...
void acquire(vpImage< vpRGBa > &I)
void setFileName(const char *filename)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
Implementation of a pose vector and operations on poses.
unsigned int getHeight() const
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
const std::string & getStringMessage(void) const
Send a reference (constant) related the error message (can be empty).
int save(const vpCameraParameters &cam, const std::string &filename, const std::string &camera_name, const unsigned int image_width=0, const unsigned int image_height=0, const std::string &additionalInfo="")
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)