39 #include <visp3/core/vpConfig.h>
41 #if VISP_HAVE_OPENCV_VERSION >= 0x020300
43 #include <opencv2/core/core.hpp>
44 #include <opencv2/imgproc/imgproc.hpp>
45 #include <opencv2/calib3d/calib3d.hpp>
46 #include <opencv2/highgui/highgui.hpp>
48 #include <visp3/vision/vpCalibration.h>
50 #include <visp3/gui/vpDisplayX.h>
51 #include <visp3/gui/vpDisplayGDI.h>
52 #include <visp3/gui/vpDisplayOpenCV.h>
53 #include <visp3/gui/vpDisplayD3D.h>
54 #include <visp3/gui/vpDisplayGTK.h>
55 #include <visp3/core/vpIoTools.h>
56 #include <visp3/core/vpPoint.h>
57 #include <visp3/io/vpVideoReader.h>
58 #include <visp3/core/vpXmlParserCamera.h>
60 #ifndef DOXYGEN_SHOULD_SKIP_THIS
66 : boardSize(), calibrationPattern(UNDEFINED), squareSize(0.), input(), tempo(0.), goodInput(false), patternToUse()
68 boardSize = cv::Size(0, 0);
69 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) calibrationPattern = CHESSBOARD;
115 else if (patternToUse.compare(
"CIRCLES_GRID") == 0) calibrationPattern = CIRCLES_GRID;
116 if (calibrationPattern == UNDEFINED) {
117 std::cerr <<
" Inexistent camera calibration mode: " << patternToUse << std::endl;
124 Pattern calibrationPattern;
131 std::string patternToUse;
135 int main(
int argc,
const char ** argv)
138 std::string outputFileName =
"camera.xml";
141 const std::string inputSettingsFile = argc > 1 ? argv[1] :
"default.cfg";
142 if (! s.read(inputSettingsFile) ) {
143 std::cout <<
"Could not open the configuration file: \"" << inputSettingsFile <<
"\"" << std::endl;
144 std::cout << std::endl <<
"Usage: " << argv[0] <<
" <configuration file>.cfg" << std::endl;
150 std::cout <<
"Invalid input detected. Application stopping. " << std::endl;
162 #elif defined VISP_HAVE_GDI
164 #elif defined VISP_HAVE_GTK
166 #elif defined VISP_HAVE_OPENCV
170 std::vector<vpPoint> model;
171 std::vector<vpCalibration> calibrator;
173 for (
int i=0; i< s.boardSize.height; i++) {
174 for (
int j=0; j< s.boardSize.width; j++) {
175 model.push_back(
vpPoint(j*s.squareSize, i*s.squareSize, 0) );
180 while(! reader.
end()) {
186 std::vector<cv::Point2f> pointBuf;
190 switch( s.calibrationPattern )
192 case Settings::CHESSBOARD:
194 found = findChessboardCorners( cvI, s.boardSize, pointBuf,
195 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
196 cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_FAST_CHECK | cv::CALIB_CB_NORMALIZE_IMAGE);
198 CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);
201 case Settings::CIRCLES_GRID:
203 found = findCirclesGrid( cvI, s.boardSize, pointBuf, cv::CALIB_CB_SYMMETRIC_GRID );
205 case Settings::UNDEFINED:
207 std::cout <<
"Unkown calibration grid " << std::endl;
211 std::cout <<
"frame: " << frame_index <<
", status: " << found;
213 std::cout <<
", image rejected" << std::endl;
215 std::cout <<
", image used as input data" << std::endl;
219 std::vector<vpImagePoint> data;
221 if (s.calibrationPattern == Settings::CHESSBOARD) {
223 cornerSubPix( cvI, pointBuf, cv::Size(11,11),
225 #
if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
226 cv::TermCriteria( cv::TermCriteria::EPS+cv::TermCriteria::COUNT, 30, 0.1 ));
228 cv::TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
231 char title[20]; sprintf(title,
"image %ld", frame_index);
233 for (
unsigned int i=0; i < pointBuf.size(); i++) {
243 for (
unsigned int i=0; i<model.size(); i++) {
244 calib.
addPoint(model[i].get_oX(), model[i].get_oY(), model[i].get_oZ(), data[i]);
258 calibrator.push_back(calib);
267 if (s.tempo > 10.f) {
280 if (calibrator.empty()) {
281 std::cerr <<
"Unable to calibrate. Image processing failed !" << std::endl;
285 std::cout <<
"\nCalibration without distorsion in progress on " << calibrator.size() <<
" images..." << std::endl;
289 std::cout << cam << std::endl;
290 std::cout <<
"Global reprojection error: " << error << std::endl;
291 #ifdef VISP_HAVE_XML2
295 std::cout <<
"Camera parameters without distortion successfully saved in \"" << outputFileName <<
"\"" << std::endl;
297 std::cout <<
"Failed to save the camera parameters without distortion in \"" << outputFileName <<
"\"" << std::endl;
298 std::cout <<
"A file with the same name exists. Remove it to be able to save the parameters..." << std::endl;
303 std::cout <<
"Calibration without distortion failed." << std::endl;
305 std::cout <<
"\nCalibration with distorsion in progress on " << calibrator.size() <<
" images..." << std::endl;
307 std::cout << cam << std::endl;
308 std::cout <<
"Global reprojection error: " << error << std::endl;
310 #ifdef VISP_HAVE_XML2
314 std::cout <<
"Camera parameters without distortion successfully saved in \"" << outputFileName <<
"\"" << std::endl;
316 std::cout <<
"Failed to save the camera parameters without distortion in \"" << outputFileName <<
"\"" << std::endl;
317 std::cout <<
"A file with the same name exists. Remove it to be able to save the parameters..." << std::endl;
320 std::cout << std::endl;
321 for (
unsigned int i=0; i<calibrator.size(); i++)
322 std::cout <<
"Estimated pose on input data " << i <<
": " <<
vpPoseVector(calibrator[i].cMo_dist).
t() << std::endl;
326 std::cout <<
"Calibration with distortion failed." << std::endl;
331 std::cout <<
"Catch an exception: " << e << std::endl;
338 std::cout <<
"OpenCV 2.3.0 or higher is requested to run the calibration." << std::endl;
VISP_EXPORT int wait(double t0, double t)
long getFrameIndex() const
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)
Define the X11 console to display images.
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)
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 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)
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.
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
Generic class defining intrinsic camera parameters.
virtual void setTitle(const char *title)=0
The vpDisplayGTK allows to display image using the GTK+ library version 1.2.
void acquire(vpImage< vpRGBa > &I)
void setFileName(const char *filename)
Implementation of a pose vector and operations on poses.
unsigned int getHeight() const
virtual bool getClick(bool blocking=true)=0
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static int computeCalibrationMulti(vpCalibrationMethodType method, std::vector< vpCalibration > &table_cal, vpCameraParameters &cam, double &globalReprojectionError, bool verbose=false)