Main MRPT website > C++ reference for MRPT 1.5.6
checkerboard_find_corners.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "vision-precomp.h" // Precompiled headers
11 
13 #include <mrpt/math/geometry.h> // crossProduct3D()
14 
15 // Universal include for all versions of OpenCV
16 #include <mrpt/otherlibs/do_opencv_includes.h>
18 
19 using namespace mrpt;
20 using namespace mrpt::vision;
21 using namespace mrpt::utils;
22 using namespace mrpt::math;
23 using namespace std;
24 
25 
26 /** Look for the corners of a chessboard in the image
27  * \param cornerCoords [OUT] The pixel coordinates of all the corners.
28  * \param check_size_x [IN] The number of squares, in the X direction
29  * \param check_size_y [IN] The number of squares, in the Y direction
30  * \param normalize_image [IN] Whether to normalize the image before detection
31  * \param useScaramuzzaMethod [IN] Whether to use the alternative, more robust method by M. Rufli, D. Scaramuzza, and R. Siegwart.
32  *
33  * \return true on success
34  */
36  const mrpt::utils::CImage &in_img,
37  std::vector<TPixelCoordf> &cornerCoords,
38  unsigned int check_size_x,
39  unsigned int check_size_y,
40  bool normalize_image,
41  bool useScaramuzzaMethod)
42 {
43 #if MRPT_HAS_OPENCV
45 
46  ASSERT_(check_size_y>0 && check_size_x>0)
47 
48  // Grayscale version:
49  const CImage img( in_img, FAST_REF_OR_CONVERT_TO_GRAY );
50 
51  // Try with expanded versions of the image if it fails to detect the checkerboard:
52  int corners_count;
53  bool corners_found=false;
54 
55  const CvSize check_size = cvSize(check_size_x, check_size_y);
56 
57  const int CORNERS_COUNT = check_size_x * check_size_y;
58 
59  vector<CvPoint2D32f> corners_list;
60  corners_count = CORNERS_COUNT;
61  corners_list.resize( CORNERS_COUNT );
62 
63  cornerCoords.clear();
64 
65  int find_chess_flags = cv::CALIB_CB_ADAPTIVE_THRESH;
66  if (normalize_image)
67  find_chess_flags |= cv::CALIB_CB_NORMALIZE_IMAGE;
68 
69  if (!useScaramuzzaMethod)
70  {
71  cv::Mat cvImg = cv::cvarrToMat(img.getAs<IplImage>());
72 
73  vector<cv::Point2f> pointbuf;
74 
75  // Standard OpenCV's function:
76  corners_found = 0 != cv::findChessboardCorners(
77  cvImg,
78  check_size,
79  pointbuf,
80  find_chess_flags);
81 
82  corners_list.resize(pointbuf.size());
83  for (size_t i=0;i<pointbuf.size();i++) {
84  corners_list[i].x = pointbuf[i].x;
85  corners_list[i].y = pointbuf[i].y;
86  }
87  }
88  else
89  {
90  // Return: -1: errors, 0: not found, 1: found OK
91  corners_found = 1 == cvFindChessboardCorners3(
92  img,
93  check_size,
94  corners_list
95  );
96  }
97 
98  // Check # of corners:
99  if (corners_found && corners_count!=CORNERS_COUNT)
100  corners_found=false;
101 
102  if( corners_found )
103  {
104  // Refine corners:
105  cvFindCornerSubPix(
106  img.getAs<IplImage>(),
107  &corners_list[0],
108  corners_count,
109  cvSize(5,5), // window
110  cvSize(-1,-1),
111  cvTermCriteria( CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10, 0.01f ));
112 
113  // save the corners in the data structure:
114  int y;
115  unsigned int k;
116  for( y = 0, k = 0; y < check_size.height; y++ )
117  for( int x = 0; x < check_size.width; x++, k++ )
118  cornerCoords.push_back( TPixelCoordf( corners_list[k].x, corners_list[k].y ) );
119  }
120 
121 
122  return corners_found;
123 
124  MRPT_END
125 #else
126  return false;
127 #endif
128 }
129 
130 
131 /** Look for the corners of one or more chessboard/checkerboards in the image.
132  * This method uses an improved version of OpenCV's cvFindChessboardCorners published
133  * by M. Rufli, D. Scaramuzza, and R. Siegwart.
134  * That method has been extended in this MRPT implementation to automatically detect a
135  * number of different checkerboards in the same image.
136  *
137  * \param cornerCoords [OUT] A vector of N vectors of pixel coordinates, for each of the N chessboards detected.
138  * \param check_size_x [IN] The number of squares, in the X direction
139  * \param check_size_y [IN] The number of squares, in the Y direction
140  *
141  *
142  * \sa mrpt::vision::checkerBoardCameraCalibration, drawChessboardCorners
143  */
145  const mrpt::utils::CImage &in_img,
146  std::vector<std::vector<TPixelCoordf> > &cornerCoords,
147  unsigned int check_size_x,
148  unsigned int check_size_y )
149 {
150 #if MRPT_HAS_OPENCV
151  // Grayscale version:
152  const CImage img( in_img, FAST_REF_OR_CONVERT_TO_GRAY );
153 
154  std::vector<std::vector<CvPoint2D32f> > corners_list;
155 
156  // Return: -1: errors, 0: not found, 1: found OK
157  bool corners_found = find_chessboard_corners_multiple(
158  img,
159  cvSize(check_size_x,check_size_y),
160  corners_list);
161 
162  if( corners_found && !corners_list.empty() )
163  {
164  // Alloc space for output points:
165  cornerCoords.resize( corners_list.size() );
166 
167  // Refine corners:
168  for (size_t i=0;i<corners_list.size();i++)
169  {
170  ASSERT_(corners_list[i].size()==check_size_x*check_size_y)
171 
172  cvFindCornerSubPix(
173  img.getAs<IplImage>(),
174  &corners_list[i][0],
175  check_size_x*check_size_y,
176  cvSize(5,5), // window
177  cvSize(-1,-1),
178  cvTermCriteria( CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10, 0.01f ));
179 
180  // save the corners in the data structure:
181  for( unsigned int y = 0, k = 0; y < check_size_y; y++ )
182  for( unsigned int x = 0; x < check_size_x; x++, k++ )
183  cornerCoords[i].push_back( TPixelCoordf( corners_list[i][k].x, corners_list[i][k].y ) );
184 
185 
186  // Consistency of the counter-clockwise XYZ reference system and corners ORDER.
187 
188  // Key idea: The cross product of X * Y must point outwards the screen:
189 
191  pt_0 = cornerCoords[i][0],
192  pt_x1 = cornerCoords[i][1],
193  pt_y1 = cornerCoords[i][check_size_x];
194  const mrpt::math::TPoint3D Ax = pt_x1 - pt_0; // z=0
195  const mrpt::math::TPoint3D Ay = pt_y1 - pt_0; // z=0
196 
197  const Eigen::Matrix<double,3,1> Az = mrpt::math::crossProduct3D(Ax,Ay);
198  if (Az[2] > 0) {
199  // Invert all rows (X):
200  for( unsigned int y = 0; y < check_size_y; y++ )
201  std::reverse( cornerCoords[i].begin()+y*check_size_x, cornerCoords[i].begin()+(y+1)*check_size_x );
202  }
203  }
204  }
205  else
206  { // Not found.
207  cornerCoords.clear();
208  return;
209  }
210 
211 #endif
212 }
213 
214 
int cvFindChessboardCorners3(const mrpt::utils::CImage &img_, CvSize pattern_size, std::vector< CvPoint2D32f > &out_corners)
A pair (x,y) of pixel coordinates (subpixel resolution).
Definition: TPixelCoord.h:21
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1166
bool find_chessboard_corners_multiple(const mrpt::utils::CImage &img_, CvSize pattern_size, std::vector< std::vector< CvPoint2D32f > > &out_corners)
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:101
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.
EIGEN_STRONG_INLINE iterator begin()
Definition: eigen_plugins.h:26
EIGEN_STRONG_INLINE void push_back(Scalar val)
Insert an element at the end of the container (for 1D vectors/arrays)
void crossProduct3D(const T &v0, const U &v1, V &vOut)
Computes the cross product of two 3D vectors, returning a vector normal to both.
Definition: geometry.h:614
GLint GLvoid * img
Definition: glew.h:1290
#define MRPT_END
GLint GLint GLint GLint GLint x
Definition: glew.h:1166
GLsizeiptr size
Definition: glew.h:1586
#define MRPT_START
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.
Definition: CImage.h:517
void VISION_IMPEXP findMultipleChessboardsCorners(const mrpt::utils::CImage &img, std::vector< std::vector< mrpt::utils::TPixelCoordf > > &cornerCoords, unsigned int check_size_x, unsigned int check_size_y)
Look for the corners of one or more chessboard/checkerboards in the image.
#define ASSERT_(f)
Lightweight 3D point.
Lightweight 2D point.
GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble f
Definition: glew.h:5092



Page generated by Doxygen 1.8.6 for MRPT 1.5.6 Git: 4c65e84 Tue Apr 24 08:18:17 2018 +0200 at mar abr 24 08:26:17 CEST 2018