20 #include <mrpt/otherlibs/do_opencv_includes.h> 34 unsigned int check_size_x,
35 unsigned int check_size_y,
36 double check_squares_length_X_meters,
37 double check_squares_length_Y_meters,
39 std::vector<double> &distortionParams,
42 bool skipDrawDetectedImgs,
43 bool useScaramuzzaAlternativeDetector
50 check_size_x,check_size_y,
51 check_squares_length_X_meters, check_squares_length_Y_meters,
54 out_MSE,skipDrawDetectedImgs,
55 useScaramuzzaAlternativeDetector);
66 template<
typename _Tp,
int _rows,
int _cols,
int _options,
int _maxRows,
int _maxCols>
68 Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>&
dst )
70 CV_DbgAssert(
src.rows == _rows &&
src.cols == _cols);
71 if( !(
dst.Flags & Eigen::RowMajorBit) )
74 dst.data(), (size_t)(
dst.stride()*
sizeof(_Tp)));
75 if(
src.type() == _dst.type() )
77 else if(
src.cols ==
src.rows )
79 src.convertTo(_dst, _dst.type());
83 Mat(
src.t()).convertTo(_dst, _dst.type());
84 CV_DbgAssert(_dst.data == (uchar*)
dst.data());
89 dst.data(), (size_t)(
dst.stride()*
sizeof(_Tp)));
90 src.convertTo(_dst, _dst.type());
91 CV_DbgAssert(_dst.data == (uchar*)
dst.data());
102 unsigned int check_size_x,
103 unsigned int check_size_y,
104 double check_squares_length_X_meters,
105 double check_squares_length_Y_meters,
107 bool normalize_image,
109 bool skipDrawDetectedImgs,
110 bool useScaramuzzaAlternativeDetector
119 ASSERT_(check_squares_length_X_meters>0)
120 ASSERT_(check_squares_length_Y_meters>0)
124 std::cout <<
"ERROR: No input images." << std::endl;
128 const unsigned CORNERS_COUNT = check_size_x * check_size_y;
129 const CvSize check_size = cvSize(check_size_x, check_size_y);
132 vector<cv::Point3f> pattern_obj_points(CORNERS_COUNT);
135 for(
y = 0, k = 0;
y < check_size_y;
y++ )
137 for(
unsigned int x = 0;
x < check_size_x;
x++, k++ )
139 pattern_obj_points[k].x =-check_squares_length_X_meters *
x;
140 pattern_obj_points[k].y = check_squares_length_Y_meters *
y;
141 pattern_obj_points[k].z = 0;
149 for (it=images.begin();it!=images.end();++it)
169 vector<vector<cv::Point3f> > objectPoints;
170 vector<vector<cv::Point2f> > imagePoints;
172 unsigned int valid_detected_imgs = 0;
173 vector<string> pointsIdx2imageFile;
174 cv::Size imgSize(0,0);
177 for (i=0,it=images.begin();it!=images.end();it++,i++)
187 out_camera_params.
ncols = imgSize.width;
188 out_camera_params.
nrows = imgSize.height;
192 if (imgSize.height != (
int)img_gray.
getHeight() || imgSize.width != (int)img_gray.
getWidth())
194 std::cout <<
"ERROR: All the images must have the same size" << std::endl;
200 unsigned corners_count;
201 bool corners_found=
false;
203 corners_count = CORNERS_COUNT;
205 vector<cv::Point2f> this_img_pts(CORNERS_COUNT);
210 vector<TPixelCoordf> detectedCoords;
214 check_size_x,check_size_y,
216 useScaramuzzaAlternativeDetector
219 corners_count = detectedCoords.size();
222 ASSERT_(detectedCoords.size()<=CORNERS_COUNT);
223 for (
size_t p=0;
p<detectedCoords.size();
p++)
225 this_img_pts[
p].x = detectedCoords[
p].x;
226 this_img_pts[
p].y = detectedCoords[
p].y;
229 if (corners_found && corners_count!=CORNERS_COUNT)
230 corners_found =
false;
239 for(
y = 0, k = 0;
y < check_size.height;
y++ )
240 for(
x = 0;
x < check_size.width;
x++, k++ )
248 CvPoint prev_pt= cvPoint(0, 0);
249 const int line_max = 8;
250 CvScalar line_colors[8];
252 line_colors[0] = CV_RGB(255,0,0);
253 line_colors[1] = CV_RGB(255,128,0);
254 line_colors[2] = CV_RGB(255,128,0);
255 line_colors[3] = CV_RGB(200,200,0);
256 line_colors[4] = CV_RGB(0,255,0);
257 line_colors[5] = CV_RGB(0,200,200);
258 line_colors[6] = CV_RGB(0,0,255);
259 line_colors[7] = CV_RGB(255,0,255);
266 for(
y = 0, k = 0;
y < check_size.height;
y++ )
268 CvScalar
color = line_colors[
y % line_max];
269 for(
x = 0;
x < check_size.width;
x++, k++ )
272 pt.x = cvRound(this_img_pts[k].
x);
273 pt.y = cvRound(this_img_pts[k].
y);
275 if( k != 0 ) cvLine( rgb_img, prev_pt, pt,
color );
278 cvPoint( pt.x -
r, pt.y -
r ),
279 cvPoint( pt.x +
r, pt.y +
r ),
color );
281 cvPoint( pt.x -
r, pt.y +
r),
282 cvPoint( pt.x +
r, pt.y -
r),
color );
283 cvCircle( rgb_img, pt,
r+1,
color );
290 pointsIdx2imageFile.push_back( it->first );
291 imagePoints.push_back( this_img_pts );
292 objectPoints.push_back( pattern_obj_points );
294 valid_detected_imgs++;
299 std::cout << valid_detected_imgs <<
" valid images." << std::endl;
300 if (!valid_detected_imgs)
302 std::cout <<
"ERROR: No valid images. Perhaps the checkerboard size is incorrect?" << std::endl;
310 cv::Mat cameraMatrix, distCoeffs(1,5,CV_64F,cv::Scalar::all(0));
311 vector<cv::Mat> rvecs, tvecs;
313 const double cv_calib_err =
315 objectPoints,imagePoints,imgSize,
316 cameraMatrix, distCoeffs, rvecs, tvecs,
322 out_camera_params.
dist.assign(0);
323 for (
int i=0;i<5;i++)
324 out_camera_params.
dist[i] = distCoeffs.ptr<
double>()[i];
327 for (i=0;i<valid_detected_imgs;i++)
336 cv::Rodrigues(rvecs[i],cv_rot);
340 HM.block<3,3>(0,0) = rot;
344 Eigen::Matrix<double,3,1> trans;
346 HM.block<3,1>(0,3) = trans;
351 images[ pointsIdx2imageFile[i] ].reconstructed_camera_pose =
p;
365 for (it=images.begin();it!=images.end();++it)
377 for (i=0;i<valid_detected_imgs;i++)
384 vector<TPoint3D> lstPatternPoints(CORNERS_COUNT);
385 for (
unsigned int p=0;
p<CORNERS_COUNT;
p++)
386 lstPatternPoints[
p] =
TPoint3D(pattern_obj_points[
p].
x,pattern_obj_points[
p].
y,pattern_obj_points[
p].
z);
403 projectedPoints_distorted
406 ASSERT_(projectedPoints.size()==CORNERS_COUNT);
407 ASSERT_(projectedPoints_distorted.size()==CORNERS_COUNT);
410 for (
unsigned int p=0;
p<CORNERS_COUNT;
p++)
412 const double px = projectedPoints[
p].x;
413 const double py = projectedPoints[
p].y;
415 const double px_d = projectedPoints_distorted[
p].x;
416 const double py_d = projectedPoints_distorted[
p].y;
421 if( px >= 0 && px < imgSize.width && py >= 0 && py < imgSize.height )
430 if (valid_detected_imgs)
432 sqrErr /= CORNERS_COUNT*valid_detected_imgs;
433 std::cout <<
"Average err. of reprojection: " << sqrt(sqrErr) <<
" pixels (OpenCV error=" << cv_calib_err <<
")\n";
435 if(out_MSE) *out_MSE = sqrt(sqrErr);
439 catch(std::exception &e)
441 std::cout << e.what() << std::endl;
445 THROW_EXCEPTION(
"Function not available: MRPT was compiled without OpenCV")
A pair (x,y) of pixel coordinates (subpixel resolution).
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
mrpt::utils::CImage img_original
This image will be automatically loaded from the file name passed to checkerBoardCameraCalibration.
A class for storing images as grayscale or RGB bitmaps.
bool VISION_IMPEXP findChessboardCorners(const mrpt::utils::CImage &img, std::vector< mrpt::utils::TPixelCoordf > &cornerCoords, unsigned int check_size_x, unsigned int check_size_y, bool normalize_image=true, bool useScaramuzzaMethod=false)
Look for the corners of a chessboard in the image using one of two different methods.
#define THROW_EXCEPTION(msg)
void rectifyImage(CImage &out_img, const mrpt::utils::TCamera &cameraParams) const
Rectify (un-distort) the image according to some camera parameters, and returns an output un-distorte...
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
void VISION_IMPEXP projectPoints_with_distortion(const std::vector< mrpt::math::TPoint3D > &in_points_3D, const mrpt::poses::CPose3D &cameraPose, const mrpt::math::CMatrixDouble33 &intrinsicParams, const std::vector< double > &distortionParams, std::vector< mrpt::utils::TPixelCoordf > &projectedPoints, bool accept_points_behind=false)
Project a set of 3D points into a camera at an arbitrary 6D pose using its calibration matrix and dis...
std::vector< mrpt::utils::TPixelCoordf > detected_corners
At output, the detected corners (x,y) in pixel units.
bool loadFromFile(const std::string &fileName, int isColor=-1)
Load image from a file, whose format is determined from the extension (internally uses OpenCV)...
const T * getAs() const
Returns a pointer to a const T* containing the image - the idea is to call like "img.getAs<IplImage>()" so we can avoid here including OpenCV's headers.
bool VISION_IMPEXP checkerBoardCameraCalibration(TCalibrationImageList &images, unsigned int check_size_x, unsigned int check_size_y, double check_squares_length_X_meters, double check_squares_length_Y_meters, mrpt::utils::TCamera &out_camera_params, bool normalize_image=true, double *out_MSE=NULL, bool skipDrawDetectedImgs=false, bool useScaramuzzaAlternativeDetector=false)
Performs a camera calibration (computation of projection and distortion parameters) from a sequence o...
T square(const T x)
Inline function for the square of a number.
std::vector< mrpt::utils::TPixelCoordf > projectedPoints_undistorted
At output, like projectedPoints_distorted but for the undistorted image.
This class implements a config file-like interface over a memory-stored string list.
void getContent(std::string &str) const
Return the current contents of the virtual "config file".
Data associated to each image in the calibration process mrpt::vision::checkerBoardCameraCalibration ...
This base provides a set of functions for maths stuff.
mrpt::utils::CImage img_checkboard
At output, this will contain the detected checkerboard overprinted to the image.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
std::vector< mrpt::utils::TPixelCoordf > projectedPoints_distorted
At output, only will have an empty vector if the checkerboard was not found in this image...
std::map< std::string, TImageCalibData > TCalibrationImageList
A list of images, used in checkerBoardCameraCalibration.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
CMatrixFixedNumeric< double, 3, 3 > CMatrixDouble33
Classes for computer vision, detectors, features, etc.
bool isExternallyStored() const MRPT_NO_THROWS
See setExternalStorage().
void VISION_IMPEXP projectPoints_no_distortion(const std::vector< mrpt::math::TPoint3D > &in_points_3D, const mrpt::poses::CPose3D &cameraPose, const mrpt::math::CMatrixDouble33 &intrinsicParams, std::vector< mrpt::utils::TPixelCoordf > &projectedPoints, bool accept_points_behind=false)
Project a set of 3D points into a camera at an arbitrary 6D pose using its calibration matrix (undist...
std::string BASE_IMPEXP extractFileExtension(const std::string &filePath, bool ignore_gz=false)
Extract the extension of a filename.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
mrpt::math::CMatrixDouble33 intrinsicParams
Matrix of intrinsic parameters (containing the focal length and principal point coordinates) ...
std::vector< double > getDistortionParamsAsVector() const
Get a vector with the distortion params of the camera.
GLsizei GLboolean transpose
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLdouble GLdouble GLdouble r
mrpt::math::CArrayDouble< 5 > dist
[k1 k2 t1 t2 k3] -> k_i: parameters of radial distortion, t_i: parameters of tangential distortion (d...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
uint32_t nrows
Camera resolution.
void my_cv2eigen(const Mat &src, Eigen::Matrix< _Tp, _rows, _cols, _options, _maxRows, _maxCols > &dst)
mrpt::utils::CImage img_rectified
At output, this will be the rectified image.
void colorImage(CImage &ret) const
Returns a RGB version of the grayscale image, or itself if it is already a RGB image.
std::string BASE_IMPEXP extractFileName(const std::string &filePath)
Extract just the name (without extension) of a filename from a complete path plus name plus extension...
mrpt::poses::CPose3D reconstructed_camera_pose
At output, the reconstructed pose of the camera.
size_t getWidth() const MRPT_OVERRIDE
Returns the width of the image in pixels.
GLuint GLuint GLsizei GLenum type
Structure to hold the parameters of a pinhole camera model.
size_t getHeight() const MRPT_OVERRIDE
Returns the height of the image in pixels.
void saveToConfigFile(const std::string §ion, mrpt::utils::CConfigFileBase &cfg) const
Save as a config block: