Main MRPT website > C++ reference for MRPT 1.9.9
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-2018, 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::img;
22 using namespace mrpt::math;
23 using namespace std;
24 
25 /** Look for the corners of a chessboard in the image
26  * \param cornerCoords [OUT] The pixel coordinates of all the corners.
27  * \param check_size_x [IN] The number of squares, in the X direction
28  * \param check_size_y [IN] The number of squares, in the Y direction
29  * \param normalize_image [IN] Whether to normalize the image before detection
30  * \param useScaramuzzaMethod [IN] Whether to use the alternative, more robust
31  * method by M. Rufli, D. Scaramuzza, and R. Siegwart.
32  *
33  * \return true on success
34  */
36  const mrpt::img::CImage& in_img, std::vector<TPixelCoordf>& cornerCoords,
37  unsigned int check_size_x, unsigned int check_size_y, bool normalize_image,
38  bool useScaramuzzaMethod)
39 {
40 #if MRPT_HAS_OPENCV
42 
43  ASSERT_(check_size_y > 0 && check_size_x > 0);
44 
45  // Grayscale version:
46  const CImage img(in_img, FAST_REF_OR_CONVERT_TO_GRAY);
47 
48  // Try with expanded versions of the image if it fails to detect the
49  // checkerboard:
50  int corners_count;
51  bool corners_found = false;
52 
53  const CvSize check_size = cvSize(check_size_x, check_size_y);
54 
55  const int CORNERS_COUNT = check_size_x * check_size_y;
56 
57  vector<CvPoint2D32f> corners_list;
58  corners_count = CORNERS_COUNT;
59  corners_list.resize(CORNERS_COUNT);
60 
61  cornerCoords.clear();
62 
63  int find_chess_flags = cv::CALIB_CB_ADAPTIVE_THRESH;
64  if (normalize_image) find_chess_flags |= cv::CALIB_CB_NORMALIZE_IMAGE;
65 
66  if (!useScaramuzzaMethod)
67  {
68  cv::Mat cvImg = cv::cvarrToMat(img.getAs<IplImage>());
69 
70  vector<cv::Point2f> pointbuf;
71 
72  // Standard OpenCV's function:
73  corners_found = 0 != cv::findChessboardCorners(
74  cvImg, check_size, pointbuf, find_chess_flags);
75 
76  corners_list.resize(pointbuf.size());
77  for (size_t i = 0; i < pointbuf.size(); i++)
78  {
79  corners_list[i].x = pointbuf[i].x;
80  corners_list[i].y = pointbuf[i].y;
81  }
82  }
83  else
84  {
85  // Return: -1: errors, 0: not found, 1: found OK
86  corners_found =
87  1 == cvFindChessboardCorners3(img, check_size, corners_list);
88  }
89 
90  // Check # of corners:
91  if (corners_found && corners_count != CORNERS_COUNT) corners_found = false;
92 
93  if (corners_found)
94  {
95  // Refine corners:
96  cvFindCornerSubPix(
97  img.getAs<IplImage>(), &corners_list[0], corners_count,
98  cvSize(5, 5), // window
99  cvSize(-1, -1),
100  cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10, 0.01f));
101 
102  // save the corners in the data structure:
103  int y;
104  unsigned int k;
105  for (y = 0, k = 0; y < check_size.height; y++)
106  for (int x = 0; x < check_size.width; x++, k++)
107  cornerCoords.push_back(
108  TPixelCoordf(corners_list[k].x, corners_list[k].y));
109  }
110 
111  return corners_found;
112 
113  MRPT_END
114 #else
115  return false;
116 #endif
117 }
118 
119 /** Look for the corners of one or more chessboard/checkerboards in the image.
120  * This method uses an improved version of OpenCV's cvFindChessboardCorners
121  * published
122  * by M. Rufli, D. Scaramuzza, and R. Siegwart.
123  * That method has been extended in this MRPT implementation to automatically
124  * detect a
125  * number of different checkerboards in the same image.
126  *
127  * \param cornerCoords [OUT] A vector of N vectors of pixel coordinates, for
128  * each of the N chessboards detected.
129  * \param check_size_x [IN] The number of squares, in the X direction
130  * \param check_size_y [IN] The number of squares, in the Y direction
131  *
132  *
133  * \sa mrpt::vision::checkerBoardCameraCalibration, drawChessboardCorners
134  */
136  const mrpt::img::CImage& in_img,
137  std::vector<std::vector<TPixelCoordf>>& cornerCoords,
138  unsigned int check_size_x, unsigned int check_size_y)
139 {
140 #if MRPT_HAS_OPENCV
141  // Grayscale version:
142  const CImage img(in_img, FAST_REF_OR_CONVERT_TO_GRAY);
143 
144  std::vector<std::vector<CvPoint2D32f>> corners_list;
145 
146  // Return: -1: errors, 0: not found, 1: found OK
147  bool corners_found = find_chessboard_corners_multiple(
148  img, cvSize(check_size_x, check_size_y), corners_list);
149 
150  if (corners_found && !corners_list.empty())
151  {
152  // Alloc space for output points:
153  cornerCoords.resize(corners_list.size());
154 
155  // Refine corners:
156  for (size_t i = 0; i < corners_list.size(); i++)
157  {
158  ASSERT_(corners_list[i].size() == check_size_x * check_size_y);
159 
160  cvFindCornerSubPix(
161  img.getAs<IplImage>(), &corners_list[i][0],
162  check_size_x * check_size_y, cvSize(5, 5), // window
163  cvSize(-1, -1),
164  cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10, 0.01f));
165 
166  // save the corners in the data structure:
167  for (unsigned int y = 0, k = 0; y < check_size_y; y++)
168  for (unsigned int x = 0; x < check_size_x; x++, k++)
169  cornerCoords[i].push_back(
170  TPixelCoordf(
171  corners_list[i][k].x, corners_list[i][k].y));
172 
173  // Consistency of the counter-clockwise XYZ reference system and
174  // corners ORDER.
175 
176  // Key idea: The cross product of X * Y must point outwards the
177  // screen:
178 
179  const mrpt::math::TPoint2D pt_0{cornerCoords[i][0].x,
180  cornerCoords[i][0].y},
181  pt_x1{cornerCoords[i][1].x, cornerCoords[i][1].y},
182  pt_y1{cornerCoords[i][check_size_x].x,
183  cornerCoords[i][check_size_x].y};
184  const mrpt::math::TPoint3D Ax = pt_x1 - pt_0; // z=0
185  const mrpt::math::TPoint3D Ay = pt_y1 - pt_0; // z=0
186 
187  const Eigen::Matrix<double, 3, 1> Az =
189  if (Az[2] > 0)
190  {
191  // Invert all rows (X):
192  for (unsigned int y = 0; y < check_size_y; y++)
193  std::reverse(
194  cornerCoords[i].begin() + y * check_size_x,
195  cornerCoords[i].begin() + (y + 1) * check_size_x);
196  }
197  }
198  }
199  else
200  { // Not found.
201  cornerCoords.clear();
202  return;
203  }
204 
205 #endif
206 }
mrpt::img::TPixelCoordf
A pair (x,y) of pixel coordinates (subpixel resolution).
Definition: TPixelCoord.h:20
begin
EIGEN_STRONG_INLINE iterator begin()
Definition: eigen_plugins.h:29
geometry.h
cvFindChessboardCorners3
int cvFindChessboardCorners3(const CImage &img_, CvSize pattern_size, std::vector< CvPoint2D32f > &out_corners)
Definition: checkerboard_ocamcalib_detector.cpp:246
find_chessboard_corners_multiple
bool find_chessboard_corners_multiple(const CImage &img_, CvSize pattern_size, std::vector< std::vector< CvPoint2D32f >> &out_corners)
Definition: checkerboard_multiple_detector.cpp:34
mrpt::vision
Classes for computer vision, detectors, features, etc.
Definition: CCamModel.h:20
mrpt::math::TPoint2D::x
double x
X,Y coordinates.
Definition: lightweight_geom_data.h:49
mrpt
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Definition: CKalmanFilterCapable.h:30
ASSERT_
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:113
vision-precomp.h
push_back
EIGEN_STRONG_INLINE void push_back(Scalar val)
Insert an element at the end of the container (for 1D vectors/arrays)
Definition: eigen_plugins.h:134
mrpt::img
Definition: CCanvas.h:17
MRPT_START
#define MRPT_START
Definition: exceptions.h:262
mrpt::math::TPoint2D
Lightweight 2D point.
Definition: lightweight_geom_data.h:42
mrpt::vision::findMultipleChessboardsCorners
void findMultipleChessboardsCorners(const mrpt::img::CImage &img, std::vector< std::vector< mrpt::img::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.
Definition: checkerboard_find_corners.cpp:135
mrpt::img::CImage
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:130
mrpt::img::FAST_REF_OR_CONVERT_TO_GRAY
@ FAST_REF_OR_CONVERT_TO_GRAY
Definition: img/CImage.h:51
mrpt::math::crossProduct3D
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:814
mrpt::math::TPoint3D
Lightweight 3D point.
Definition: lightweight_geom_data.h:378
img
GLint GLvoid * img
Definition: glext.h:3763
checkerboard_ocamcalib_detector.h
MRPT_END
#define MRPT_END
Definition: exceptions.h:266
mrpt::vision::findChessboardCorners
bool findChessboardCorners(const mrpt::img::CImage &img, std::vector< mrpt::img::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.
Definition: checkerboard_find_corners.cpp:35
mrpt::math
This base provides a set of functions for maths stuff.
Definition: math/include/mrpt/math/bits_math.h:13
size
GLsizeiptr size
Definition: glext.h:3923
y
GLenum GLint GLint y
Definition: glext.h:3538
chessboard_find_corners.h
x
GLenum GLint x
Definition: glext.h:3538



Page generated by Doxygen 1.8.17 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at miƩ 12 jul 2023 10:03:34 CEST