43 #include <visp/vpConfig.h>
45 #if VISP_HAVE_OPENCV_VERSION >= 0x020300
47 #include <opencv2/core/core.hpp>
48 #include <opencv2/imgproc/imgproc.hpp>
49 #include <opencv2/calib3d/calib3d.hpp>
50 #include <opencv2/highgui/highgui.hpp>
52 #include <visp/vpCalibration.h>
54 #include <visp/vpDisplayX.h>
55 #include <visp/vpDisplayGDI.h>
56 #include <visp/vpDisplayOpenCV.h>
57 #include <visp/vpDisplayD3D.h>
58 #include <visp/vpDisplayGTK.h>
59 #include <visp/vpIoTools.h>
60 #include <visp/vpPoint.h>
61 #include <visp/vpVideoReader.h>
62 #include <visp/vpXmlParserCamera.h>
64 #ifndef DOXYGEN_SHOULD_SKIP_THIS
70 : boardSize(), calibrationPattern(UNDEFINED), squareSize(0.), input(), tempo(0.), goodInput(false), patternToUse()
72 boardSize = cv::Size(0, 0);
73 calibrationPattern = UNDEFINED;
79 enum Pattern { UNDEFINED, CHESSBOARD, CIRCLES_GRID};
81 bool read(
const std::string &filename)
93 std::cout <<
"grid width : " << boardSize.width << std::endl;
94 std::cout <<
"grid height: " << boardSize.height << std::endl;
95 std::cout <<
"square size: " << squareSize << std::endl;
96 std::cout <<
"pattern : " << patternToUse << std::endl;
97 std::cout <<
"input seq : " << input << std::endl;
98 std::cout <<
"tempo : " << tempo << std::endl;
105 if (boardSize.width <= 0 || boardSize.height <= 0) {
106 std::cerr <<
"Invalid Board size: " << boardSize.width <<
" " << boardSize.height << std::endl;
109 if (squareSize <= 10e-6) {
110 std::cerr <<
"Invalid square size " << squareSize << std::endl;
117 calibrationPattern = UNDEFINED;
118 if (patternToUse.compare(
"CHESSBOARD") == 0) calibrationPattern = CHESSBOARD;
119 else if (patternToUse.compare(
"CIRCLES_GRID") == 0) calibrationPattern = CIRCLES_GRID;
120 if (calibrationPattern == UNDEFINED) {
121 std::cerr <<
" Inexistent camera calibration mode: " << patternToUse << std::endl;
128 Pattern calibrationPattern;
135 std::string patternToUse;
139 int main(
int argc,
const char ** argv)
142 std::string outputFileName =
"camera.xml";
145 const std::string inputSettingsFile = argc > 1 ? argv[1] :
"default.cfg";
146 if (! s.read(inputSettingsFile) ) {
147 std::cout <<
"Could not open the configuration file: \"" << inputSettingsFile <<
"\"" << std::endl;
148 std::cout << std::endl <<
"Usage: " << argv[0] <<
" <configuration file>.cfg" << std::endl;
154 std::cout <<
"Invalid input detected. Application stopping. " << std::endl;
166 #elif defined VISP_HAVE_GDI
168 #elif defined VISP_HAVE_GTK
170 #elif defined VISP_HAVE_OPENCV
174 std::vector<vpPoint> model;
175 std::vector<vpCalibration> calibrator;
177 for (
int i=0; i< s.boardSize.height; i++) {
178 for (
int j=0; j< s.boardSize.width; j++) {
186 while(! reader.
end()) {
192 std::vector<cv::Point2f> pointBuf;
196 switch( s.calibrationPattern )
198 case Settings::CHESSBOARD:
200 found = findChessboardCorners( cvI, s.boardSize, pointBuf,
201 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
202 cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_FAST_CHECK | cv::CALIB_CB_NORMALIZE_IMAGE);
204 CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);
207 case Settings::CIRCLES_GRID:
209 found = findCirclesGrid( cvI, s.boardSize, pointBuf, cv::CALIB_CB_SYMMETRIC_GRID );
211 case Settings::UNDEFINED:
213 std::cout <<
"Unkown calibration grid " << std::endl;
217 std::cout <<
"frame: " << frame_index <<
", status: " << found;
219 std::cout <<
", image rejected" << std::endl;
221 std::cout <<
", image used as input data" << std::endl;
225 std::vector<vpImagePoint> data;
227 if (s.calibrationPattern == Settings::CHESSBOARD) {
229 cornerSubPix( cvI, pointBuf, cv::Size(11,11),
231 #
if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
232 cv::TermCriteria( cv::TermCriteria::EPS+cv::TermCriteria::COUNT, 30, 0.1 ));
234 cv::TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
237 char title[20]; sprintf(title,
"image %ld", frame_index);
239 for (
unsigned int i=0; i < pointBuf.size(); i++) {
249 for (
unsigned int i=0; i<model.size(); i++) {
250 calib.
addPoint(model[i].get_oX(), model[i].get_oY(), model[i].get_oZ(), data[i]);
264 calibrator.push_back(calib);
273 if (s.tempo > 10.f) {
286 if (calibrator.empty()) {
287 std::cerr <<
"Unable to calibrate. Image processing failed !" << std::endl;
291 std::cout <<
"\nCalibration without distorsion in progress on " << calibrator.size() <<
" images..." << std::endl;
295 std::cout << cam << std::endl;
296 std::cout <<
"Global reprojection error: " << error << std::endl;
297 #ifdef VISP_HAVE_XML2
301 std::cout <<
"Camera parameters without distortion successfully saved in \"" << outputFileName <<
"\"" << std::endl;
303 std::cout <<
"Failed to save the camera parameters without distortion in \"" << outputFileName <<
"\"" << std::endl;
304 std::cout <<
"A file with the same name exists. Remove it to be able to save the parameters..." << std::endl;
309 std::cout <<
"Calibration without distortion failed." << std::endl;
311 std::cout <<
"\nCalibration with distorsion in progress on " << calibrator.size() <<
" images..." << std::endl;
313 std::cout << cam << std::endl;
314 std::cout <<
"Global reprojection error: " << error << std::endl;
316 #ifdef VISP_HAVE_XML2
320 std::cout <<
"Camera parameters without distortion successfully saved in \"" << outputFileName <<
"\"" << std::endl;
322 std::cout <<
"Failed to save the camera parameters without distortion in \"" << outputFileName <<
"\"" << std::endl;
323 std::cout <<
"A file with the same name exists. Remove it to be able to save the parameters..." << std::endl;
326 std::cout << std::endl;
327 for (
unsigned int i=0; i<calibrator.size(); i++)
328 std::cout <<
"Estimated pose on input data " << i <<
": " <<
vpPoseVector(calibrator[i].cMo_dist).
t() << std::endl;
332 std::cout <<
"Calibration with distortion failed." << std::endl;
337 std::cout <<
"Catch an exception: " << e << std::endl;
344 std::cout <<
"OpenCV 2.3.0 or higher is requested to run the calibration." << std::endl;
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)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
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.
static int wait(double t0, double t)
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.
vpRowVector t() const
Transpose of a vector.
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)
The pose is a complete representation of every rigid motion in the euclidian space.
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)
void setWorldCoordinates(const double ox, const double oy, const double oz)
Set the point world coordinates. We mean here the coordinates of the point in the object frame...