1// This file is part of OpenCV project.
2// It is subject to the license terms in the LICENSE file found in the top-level directory
3// of this distribution and at http://opencv.org/license.html.
4
5#ifndef CHESSBOARD_HPP_
6#define CHESSBOARD_HPP_
7
8#include "opencv2/core.hpp"
9#include "opencv2/features2d.hpp"
10#include <vector>
11#include <set>
12#include <map>
13
14namespace cv {
15namespace details{
16/**
17 * \brief Fast point sysmetric cross detector based on a localized radon transformation
18 */
19class FastX : public cv::Feature2D
20{
21 public:
22 struct Parameters
23 {
24 float strength; //!< minimal strength of a valid junction in dB
25 float resolution; //!< angle resolution in radians
26 int branches; //!< the number of branches
27 int min_scale; //!< scale level [0..8]
28 int max_scale; //!< scale level [0..8]
29 bool filter; //!< post filter feature map to improve impulse response
30 bool super_resolution; //!< up-sample
31
32 Parameters()
33 {
34 strength = 40;
35 resolution = float(CV_PI*0.25);
36 branches = 2;
37 min_scale = 2;
38 max_scale = 5;
39 super_resolution = true;
40 filter = true;
41 }
42 };
43
44 public:
45 FastX(const Parameters &config = Parameters());
46 virtual ~FastX(){}
47
48 void reconfigure(const Parameters &para);
49
50 //declaration to be wrapped by rbind
51 void detect(cv::InputArray image,std::vector<cv::KeyPoint>& keypoints, cv::InputArray mask=cv::Mat())override
52 {cv::Feature2D::detect(image: image.getMat(),keypoints,mask: mask.getMat());}
53
54 virtual void detectAndCompute(cv::InputArray image,
55 cv::InputArray mask,
56 std::vector<cv::KeyPoint>& keypoints,
57 cv::OutputArray descriptors,
58 bool useProvidedKeyPoints = false)override;
59
60 void detectImpl(const cv::Mat& image,
61 std::vector<cv::KeyPoint>& keypoints,
62 std::vector<cv::Mat> &feature_maps,
63 const cv::Mat& mask=cv::Mat())const;
64
65 void detectImpl(const cv::Mat& image,
66 std::vector<cv::Mat> &rotated_images,
67 std::vector<cv::Mat> &feature_maps,
68 const cv::Mat& mask=cv::Mat())const;
69
70 void findKeyPoints(const std::vector<cv::Mat> &feature_map,
71 std::vector<cv::KeyPoint>& keypoints,
72 const cv::Mat& mask = cv::Mat())const;
73
74 std::vector<std::vector<float> > calcAngles(const std::vector<cv::Mat> &rotated_images,
75 std::vector<cv::KeyPoint> &keypoints)const;
76 // define pure virtual methods
77 virtual int descriptorSize()const override{return 0;}
78 virtual int descriptorType()const override{return 0;}
79 virtual void operator()( cv::InputArray image, cv::InputArray mask, std::vector<cv::KeyPoint>& keypoints, cv::OutputArray descriptors, bool useProvidedKeypoints=false )const
80 {
81 descriptors.clear();
82 detectImpl(image: image.getMat(),keypoints,mask);
83 if(!useProvidedKeypoints) // suppress compiler warning
84 return;
85 return;
86 }
87
88 protected:
89 virtual void computeImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors)const
90 {
91 descriptors = cv::Mat();
92 detectImpl(image,keypoints);
93 }
94
95 private:
96 void detectImpl(const cv::Mat& _src, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask)const;
97 virtual void detectImpl(cv::InputArray image, std::vector<cv::KeyPoint>& keypoints, cv::InputArray mask=cv::noArray())const;
98
99 void rotate(float angle,cv::InputArray img,cv::Size size,cv::OutputArray out)const;
100 void calcFeatureMap(const cv::Mat &images,cv::Mat& out)const;
101
102 private:
103 Parameters parameters;
104};
105
106/**
107 * \brief Ellipse class
108 */
109class Ellipse
110{
111 public:
112 Ellipse();
113 Ellipse(const cv::Point2f &center, const cv::Size2f &axes, float angle);
114
115 void draw(cv::InputOutputArray img,const cv::Scalar &color = cv::Scalar::all(v0: v0: 120))const;
116 bool contains(const cv::Point2f &pt)const;
117 cv::Point2f getCenter()const;
118 const cv::Size2f &getAxes()const;
119
120 private:
121 cv::Point2f center;
122 cv::Size2f axes;
123 float angle,cosf,sinf;
124};
125
126/**
127 * \brief Chessboard corner detector
128 *
129 * The detectors tries to find all chessboard corners of an imaged
130 * chessboard and returns them as an ordered vector of KeyPoints.
131 * Thereby, the left top corner has index 0 and the bottom right
132 * corner n*m-1.
133 */
134class Chessboard: public cv::Feature2D
135{
136 public:
137 static const int DUMMY_FIELD_SIZE = 100; // in pixel
138
139 /**
140 * \brief Configuration of a chessboard corner detector
141 *
142 */
143 struct Parameters
144 {
145 cv::Size chessboard_size; //!< size of the chessboard
146 int min_scale; //!< scale level [0..8]
147 int max_scale; //!< scale level [0..8]
148 int max_points; //!< maximal number of points regarded
149 int max_tests; //!< maximal number of tested hypothesis
150 bool super_resolution; //!< use super-repsolution for chessboard detection
151 bool larger; //!< indicates if larger boards should be returned
152 bool marker; //!< indicates that valid boards must have a white and black cirlce marker used for orientation
153
154 Parameters()
155 {
156 chessboard_size = cv::Size(9,6);
157 min_scale = 3;
158 max_scale = 4;
159 super_resolution = true;
160 max_points = 200;
161 max_tests = 50;
162 larger = false;
163 marker = false;
164 }
165
166 Parameters(int scale,int _max_points):
167 min_scale(scale),
168 max_scale(scale),
169 max_points(_max_points)
170 {
171 chessboard_size = cv::Size(9,6);
172 }
173 };
174
175
176 /**
177 * \brief Gets the 3D objects points for the chessboard assuming the
178 * left top corner is located at the origin.
179 *
180 * \param[in] pattern_size Number of rows and cols of the pattern
181 * \param[in] cell_size Size of one cell
182 *
183 * \returns Returns the object points as CV_32FC3
184 */
185 static cv::Mat getObjectPoints(const cv::Size &pattern_size,float cell_size);
186
187 /**
188 * \brief Class for searching and storing chessboard corners.
189 *
190 * The search is based on a feature map having strong pixel
191 * values at positions where a chessboard corner is located.
192 *
193 * The board must be rectangular but supports empty cells
194 *
195 */
196 class Board
197 {
198 public:
199 /**
200 * \brief Estimates the position of the next point on a line using cross ratio constrain
201 *
202 * cross ratio:
203 * d12/d34 = d13/d24
204 *
205 * point order on the line:
206 * p0 --> p1 --> p2 --> p3
207 *
208 * \param[in] p0 First point coordinate
209 * \param[in] p1 Second point coordinate
210 * \param[in] p2 Third point coordinate
211 * \param[out] p3 Forth point coordinate
212 *
213 */
214 static bool estimatePoint(const cv::Point2f &p0,const cv::Point2f &p1,const cv::Point2f &p2,cv::Point2f &p3);
215
216 // using 1D homography
217 static bool estimatePoint(const cv::Point2f &p0,const cv::Point2f &p1,const cv::Point2f &p2,const cv::Point2f &p3, cv::Point2f &p4);
218
219 /**
220 * \brief Checks if all points of a row or column have a valid cross ratio constraint
221 *
222 * cross ratio:
223 * d12/d34 = d13/d24
224 *
225 * point order on the row/column:
226 * pt1 --> pt2 --> pt3 --> pt4
227 *
228 * \param[in] points THe points of the row/column
229 *
230 */
231 static bool checkRowColumn(const std::vector<cv::Point2f> &points);
232
233 /**
234 * \brief Estimates the search area for the next point on the line using cross ratio
235 *
236 * point order on the line:
237 * (p0) --> p1 --> p2 --> p3 --> search area
238 *
239 * \param[in] p1 First point coordinate
240 * \param[in] p2 Second point coordinate
241 * \param[in] p3 Third point coordinate
242 * \param[in] p Percentage of d34 used for the search area width and height [0..1]
243 * \param[out] ellipse The search area
244 * \param[in] p0 optional point to improve accuracy
245 *
246 * \return Returns false if no search area can be calculated
247 *
248 */
249 static bool estimateSearchArea(const cv::Point2f &p1,const cv::Point2f &p2,const cv::Point2f &p3,float p,
250 Ellipse &ellipse,const cv::Point2f *p0 =NULL);
251
252 /**
253 * \brief Estimates the search area for a specific point based on the given homography
254 *
255 * \param[in] H homography describing the transformation from ideal board to real one
256 * \param[in] row Row of the point
257 * \param[in] col Col of the point
258 * \param[in] p Percentage [0..1]
259 *
260 * \return Returns false if no search area can be calculated
261 *
262 */
263 static Ellipse estimateSearchArea(cv::Mat H,int row, int col,float p,int field_size = DUMMY_FIELD_SIZE);
264
265 /**
266 * \brief Searches for the maximum in a given search area
267 *
268 * \param[in] map feature map
269 * \param[in] ellipse search area
270 * \param[in] min_val Minimum value of the maximum to be accepted as maximum
271 *
272 * \return Returns a negative value if all points are outside the ellipse
273 *
274 */
275 static float findMaxPoint(cv::flann::Index &index,const cv::Mat &data,const Ellipse &ellipse,float white_angle,float black_angle,cv::Point2f &pt);
276
277 /**
278 * \brief Searches for the next point using cross ratio constrain
279 *
280 * \param[in] index flann index
281 * \param[in] data extended flann data
282 * \param[in] pt1
283 * \param[in] pt2
284 * \param[in] pt3
285 * \param[in] white_angle
286 * \param[in] black_angle
287 * \param[in] min_response
288 * \param[out] point The resulting point
289 *
290 * \return Returns false if no point could be found
291 *
292 */
293 static bool findNextPoint(cv::flann::Index &index,const cv::Mat &data,
294 const cv::Point2f &pt1,const cv::Point2f &pt2, const cv::Point2f &pt3,
295 float white_angle,float black_angle,float min_response,cv::Point2f &point);
296
297 /**
298 * \brief Creates a new Board object
299 *
300 */
301 Board(float white_angle=0,float black_angle=0);
302 Board(const cv::Size &size, const std::vector<cv::Point2f> &points,float white_angle=0,float black_angle=0);
303 Board(const Chessboard::Board &other);
304 virtual ~Board();
305
306 Board& operator=(const Chessboard::Board &other);
307
308 /**
309 * \brief Draws the corners into the given image
310 *
311 * \param[in] m The image
312 * \param[out] out The resulting image
313 * \param[in] H optional homography to calculate search area
314 *
315 */
316 void draw(cv::InputArray m,cv::OutputArray out,cv::InputArray H=cv::Mat())const;
317
318 /**
319 * \brief Estimates the pose of the chessboard
320 *
321 */
322 bool estimatePose(const cv::Size2f &real_size,cv::InputArray _K,cv::OutputArray rvec,cv::OutputArray tvec)const;
323
324 /**
325 * \brief Clears all internal data of the object
326 *
327 */
328 void clear();
329
330 /**
331 * \brief Returns the angle of the black diagnonale
332 *
333 */
334 float getBlackAngle()const;
335
336 /**
337 * \brief Returns the angle of the black diagnonale
338 *
339 */
340 float getWhiteAngle()const;
341
342 /**
343 * \brief Initializes a 3x3 grid from 9 corner coordinates
344 *
345 * All points must be ordered:
346 * p0 p1 p2
347 * p3 p4 p5
348 * p6 p7 p8
349 *
350 * \param[in] points vector of points
351 *
352 * \return Returns false if the grid could not be initialized
353 */
354 bool init(const std::vector<cv::Point2f> points);
355
356 /**
357 * \brief Returns true if the board is empty
358 *
359 */
360 bool isEmpty() const;
361
362 /**
363 * \brief Returns all board corners as ordered vector
364 *
365 * The left top corner has index 0 and the bottom right
366 * corner rows*cols-1. All corners which only belong to
367 * empty cells are returned as NaN.
368 */
369 std::vector<cv::Point2f> getCorners(bool ball=true) const;
370
371 /**
372 * \brief Returns all board corners as ordered vector of KeyPoints
373 *
374 * The left top corner has index 0 and the bottom right
375 * corner rows*cols-1.
376 *
377 * \param[in] ball if set to false only non empty points are returned
378 *
379 */
380 std::vector<cv::KeyPoint> getKeyPoints(bool ball=true) const;
381
382 /**
383 * \brief Returns the centers of the chessboard cells
384 *
385 * The left top corner has index 0 and the bottom right
386 * corner (rows-1)*(cols-1)-1.
387 *
388 */
389 std::vector<cv::Point2f> getCellCenters() const;
390
391 /**
392 * \brief Returns all cells as mats of four points each describing their corners.
393 *
394 * The left top cell has index 0
395 *
396 */
397 std::vector<cv::Mat> getCells(float shrink_factor = 1.0,bool bwhite=true,bool bblack = true) const;
398
399 /**
400 * \brief Estimates the homography between an ideal board
401 * and reality based on the already recovered points
402 *
403 * \param[in] rect selecting a subset of the already recovered points
404 * \param[in] field_size The field size of the ideal board
405 *
406 */
407 cv::Mat estimateHomography(cv::Rect rect,int field_size = DUMMY_FIELD_SIZE)const;
408
409 /**
410 * \brief Estimates the homography between an ideal board
411 * and reality based on the already recovered points
412 *
413 * \param[in] field_size The field size of the ideal board
414 *
415 */
416 cv::Mat estimateHomography(int field_size = DUMMY_FIELD_SIZE)const;
417
418 /**
419 * \brief Warp image to match ideal checkerboard
420 *
421 */
422 cv::Mat warpImage(cv::InputArray image)const;
423
424 /**
425 * \brief Returns the size of the board
426 *
427 */
428 cv::Size getSize() const;
429
430 /**
431 * \brief Returns the number of cols
432 *
433 */
434 size_t colCount() const;
435
436 /**
437 * \brief Returns the number of rows
438 *
439 */
440 size_t rowCount() const;
441
442 /**
443 * \brief Returns the inner contour of the board including only valid corners
444 *
445 * \info the contour might be non squared if not all points of the board are defined
446 *
447 */
448 std::vector<cv::Point2f> getContour()const;
449
450 /**
451 * \brief Masks the found board in the given image
452 *
453 */
454 void maskImage(cv::InputOutputArray img,const cv::Scalar &color=cv::Scalar::all(v0: v0: 0))const;
455
456 /**
457 * \brief Grows the board in all direction until no more corners are found in the feature map
458 *
459 * \param[in] data CV_32FC1 data of the flann index
460 * \param[in] flann_index flann index
461 *
462 * \returns the number of grows
463 */
464 int grow(const cv::Mat &data,cv::flann::Index &flann_index);
465
466 /**
467 * \brief Validates all corners using guided search based on the given homography
468 *
469 * \param[in] data CV_32FC1 data of the flann index
470 * \param[in] flann_index flann index
471 * \param[in] h Homography describing the transformation from ideal board to the real one
472 * \param[in] min_response Min response
473 *
474 * \returns the number of valid corners
475 */
476 int validateCorners(const cv::Mat &data,cv::flann::Index &flann_index,const cv::Mat &h,float min_response=0);
477
478 /**
479 * \brief check that no corner is used more than once
480 *
481 * \returns Returns false if a corner is used more than once
482 */
483 bool checkUnique()const;
484
485 /**
486 * \brief Returns false if the angles of the contour are smaller than 35°
487 *
488 */
489 bool validateContour()const;
490
491
492 /**
493 \brief delete left column of the board
494 */
495 bool shrinkLeft();
496
497 /**
498 \brief delete right column of the board
499 */
500 bool shrinkRight();
501
502 /**
503 \brief shrink first row of the board
504 */
505 bool shrinkTop();
506
507 /**
508 \brief delete last row of the board
509 */
510 bool shrinkBottom();
511
512 /**
513 * \brief Grows the board to the left by adding one column.
514 *
515 * \param[in] map CV_32FC1 feature map
516 *
517 * \returns Returns false if the feature map has no maxima at the requested positions
518 */
519 bool growLeft(const cv::Mat &map,cv::flann::Index &flann_index);
520 void growLeft();
521
522 /**
523 * \brief Grows the board to the top by adding one row.
524 *
525 * \param[in] map CV_32FC1 feature map
526 *
527 * \returns Returns false if the feature map has no maxima at the requested positions
528 */
529 bool growTop(const cv::Mat &map,cv::flann::Index &flann_index);
530 void growTop();
531
532 /**
533 * \brief Grows the board to the right by adding one column.
534 *
535 * \param[in] map CV_32FC1 feature map
536 *
537 * \returns Returns false if the feature map has no maxima at the requested positions
538 */
539 bool growRight(const cv::Mat &map,cv::flann::Index &flann_index);
540 void growRight();
541
542 /**
543 * \brief Grows the board to the bottom by adding one row.
544 *
545 * \param[in] map CV_32FC1 feature map
546 *
547 * \returns Returns false if the feature map has no maxima at the requested positions
548 */
549 bool growBottom(const cv::Mat &map,cv::flann::Index &flann_index);
550 void growBottom();
551
552 /**
553 * \brief Adds one column on the left side
554 *
555 * \param[in] points The corner coordinates
556 *
557 */
558 void addColumnLeft(const std::vector<cv::Point2f> &points);
559
560 /**
561 * \brief Adds one column at the top
562 *
563 * \param[in] points The corner coordinates
564 *
565 */
566 void addRowTop(const std::vector<cv::Point2f> &points);
567
568 /**
569 * \brief Adds one column on the right side
570 *
571 * \param[in] points The corner coordinates
572 *
573 */
574 void addColumnRight(const std::vector<cv::Point2f> &points);
575
576 /**
577 * \brief Adds one row at the bottom
578 *
579 * \param[in] points The corner coordinates
580 *
581 */
582 void addRowBottom(const std::vector<cv::Point2f> &points);
583
584 /**
585 * \brief Rotates the board 90° degrees to the left
586 */
587 void rotateLeft();
588
589 /**
590 * \brief Rotates the board 90° degrees to the right
591 */
592 void rotateRight();
593
594 /**
595 * \brief Flips the board along its local x(width) coordinate direction
596 */
597 void flipVertical();
598
599 /**
600 * \brief Flips the board along its local y(height) coordinate direction
601 */
602 void flipHorizontal();
603
604 /**
605 * \brief Flips and rotates the board so that the angle of
606 * either the black or white diagonal is bigger than the x
607 * and y axis of the board and from a right handed
608 * coordinate system
609 */
610 void normalizeOrientation(bool bblack=true);
611
612 /**
613 * \brief Flips and rotates the board so that the marker
614 * is normalized
615 */
616 bool normalizeMarkerOrientation();
617
618 /**
619 * \brief Exchanges the stored board with the board stored in other
620 */
621 void swap(Chessboard::Board &other);
622
623 bool operator==(const Chessboard::Board& other) const {return rows*cols == other.rows*other.cols;}
624 bool operator< (const Chessboard::Board& other) const {return rows*cols < other.rows*other.cols;}
625 bool operator> (const Chessboard::Board& other) const {return rows*cols > other.rows*other.cols;}
626 bool operator>= (const cv::Size& size)const { return rows*cols >= size.width*size.height; }
627
628 /**
629 * \brief Returns a specific corner
630 *
631 * \info raises runtime_error if row col does not exists
632 */
633 cv::Point2f& getCorner(int row,int col);
634
635 /**
636 * \brief Returns true if the cell is empty meaning at least one corner is NaN
637 */
638 bool isCellEmpty(int row,int col);
639
640 /**
641 * \brief Returns the mapping from all corners idx to only valid corners idx
642 */
643 std::map<int,int> getMapping()const;
644
645 /**
646 * \brief Returns true if the cell is black
647 *
648 */
649 bool isCellBlack(int row,int col)const;
650
651 /**
652 * \brief Returns true if the cell has a round marker at its
653 * center
654 *
655 */
656 bool hasCellMarker(int row,int col);
657
658 /**
659 * \brief Detects round markers in the chessboard fields based
660 * on the given image and the already recoverd board corners
661 *
662 * \returns Returns the number of found markes
663 *
664 */
665 int detectMarkers(cv::InputArray image);
666
667 /**
668 * \brief Calculates the average edge sharpness for the chessboard
669 *
670 * \param[in] image The image where the chessboard was detected
671 * \param[in] rise_distance Rise distance 0.8 means 10% ... 90%
672 * \param[in] vertical by default only edge response for horiontal lines are calculated
673 *
674 * \returns Scalar(sharpness, average min_val, average max_val)
675 *
676 * \author aduda@krakenrobotik.de
677 */
678 cv::Scalar calcEdgeSharpness(cv::InputArray image,float rise_distance=0.8,bool vertical=false,cv::OutputArray sharpness=cv::noArray());
679
680
681 /**
682 * \brief Gets the 3D objects points for the chessboard
683 * assuming the left top corner is located at the origin. In
684 * case the board as a marker, the white marker cell is at position zero
685 *
686 * \param[in] cell_size Size of one cell
687 *
688 * \returns Returns the object points as CV_32FC3
689 */
690 cv::Mat getObjectPoints(float cell_size)const;
691
692
693 /**
694 * \brief Returns the angle the board is rotated agains the x-axis of the image plane
695 * \returns Returns the object points as CV_32FC3
696 */
697 float getAngle()const;
698
699 /**
700 * \brief Returns true if the main direction of the board is close to the image x-axis than y-axis
701 */
702 bool isHorizontal()const;
703
704 /**
705 * \brief Updates the search angles
706 */
707 void setAngles(float white,float black);
708
709 private:
710 // stores one cell
711 // in general a cell is initialized by the Board so that:
712 // * all corners are always pointing to a valid cv::Point2f
713 // * depending on the position left,top,right and bottom might be set to NaN
714 // * A cell is empty if at least one corner is NaN
715 struct Cell
716 {
717 cv::Point2f *top_left,*top_right,*bottom_right,*bottom_left; // corners
718 Cell *left,*top,*right,*bottom; // neighbouring cells
719 bool black; // set to true if cell is black
720 bool marker; // set to true if cell has a round marker in its center
721 Cell();
722 bool empty()const; // indicates if the cell is empty (one of its corners has NaN)
723 int getRow()const;
724 int getCol()const;
725 cv::Point2f getCenter()const;
726 bool isInside(const cv::Point2f &pt)const; // check if point is inside the cell
727 };
728
729 // corners
730 enum CornerIndex
731 {
732 TOP_LEFT,
733 TOP_RIGHT,
734 BOTTOM_RIGHT,
735 BOTTOM_LEFT
736 };
737
738 Cell* getCell(int row,int column); // returns a specific cell
739 const Cell* getCell(int row,int column)const; // returns a specific cell
740 void drawEllipses(const std::vector<Ellipse> &ellipses);
741
742 // Iterator for iterating over board corners
743 class PointIter
744 {
745 public:
746 PointIter(Cell *cell,CornerIndex corner_index);
747 PointIter(const PointIter &other);
748 void operator=(const PointIter &other);
749 bool valid() const; // returns if the pointer is pointing to a cell
750
751 bool left(bool check_empty=false); // moves one corner to the left or returns false
752 bool right(bool check_empty=false); // moves one corner to the right or returns false
753 bool bottom(bool check_empty=false); // moves one corner to the bottom or returns false
754 bool top(bool check_empty=false); // moves one corner to the top or returns false
755 bool checkCorner()const; // returns true if the current corner belongs to at least one
756 // none empty cell
757 bool isNaN()const; // returns true if the current corner is NaN
758
759 const cv::Point2f* operator*() const; // current corner coordinate
760 cv::Point2f* operator*(); // current corner coordinate
761 const cv::Point2f* operator->() const; // current corner coordinate
762 cv::Point2f* operator->(); // current corner coordinate
763
764 Cell *getCell(); // current cell
765 private:
766 CornerIndex corner_index;
767 Cell *cell;
768 };
769
770 std::vector<Cell*> cells; // storage for all board cells
771 std::vector<cv::Point2f*> corners; // storage for all corners
772 Cell *top_left; // pointer to the top left corner of the board in its local coordinate system
773 int rows; // number of inner pattern rows
774 int cols; // number of inner pattern cols
775 float white_angle,black_angle;
776 };
777 public:
778
779 /**
780 * \brief Creates a chessboard corner detectors
781 *
782 * \param[in] config Configuration used to detect chessboard corners
783 *
784 */
785 Chessboard(const Parameters &config = Parameters());
786 virtual ~Chessboard();
787 void reconfigure(const Parameters &config = Parameters());
788 Parameters getPara()const;
789
790 /*
791 * \brief Detects chessboard corners in the given image.
792 *
793 * The detectors tries to find all chessboard corners of an imaged
794 * chessboard and returns them as an ordered vector of KeyPoints.
795 * Thereby, the left top corner has index 0 and the bottom right
796 * corner n*m-1.
797 *
798 * \param[in] image The image
799 * \param[out] keypoints The detected corners as a vector of ordered KeyPoints
800 * \param[in] mask Currently not supported
801 *
802 */
803 void detect(cv::InputArray image,std::vector<cv::KeyPoint>& keypoints, cv::InputArray mask=cv::Mat())override
804 {cv::Feature2D::detect(image: image.getMat(),keypoints,mask: mask.getMat());}
805
806 virtual void detectAndCompute(cv::InputArray image,cv::InputArray mask, std::vector<cv::KeyPoint>& keypoints,cv::OutputArray descriptors,
807 bool useProvidedKeyPoints = false)override;
808
809 /*
810 * \brief Detects chessboard corners in the given image.
811 *
812 * The detectors tries to find all chessboard corners of an imaged
813 * chessboard and returns them as an ordered vector of KeyPoints.
814 * Thereby, the left top corner has index 0 and the bottom right
815 * corner n*m-1.
816 *
817 * \param[in] image The image
818 * \param[out] keypoints The detected corners as a vector of ordered KeyPoints
819 * \param[out] feature_maps The feature map generated by LRJT and used to find the corners
820 * \param[in] mask Currently not supported
821 *
822 */
823 void detectImpl(const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints,std::vector<cv::Mat> &feature_maps,const cv::Mat& mask)const;
824 Chessboard::Board detectImpl(const cv::Mat& image,std::vector<cv::Mat> &feature_maps,const cv::Mat& mask)const;
825
826 // define pure virtual methods
827 virtual int descriptorSize()const override{return 0;}
828 virtual int descriptorType()const override{return 0;}
829 virtual void operator()( cv::InputArray image, cv::InputArray mask, std::vector<cv::KeyPoint>& keypoints, cv::OutputArray descriptors, bool useProvidedKeypoints=false )const
830 {
831 descriptors.clear();
832 detectImpl(image: image.getMat(),keypoints,mask);
833 if(!useProvidedKeypoints) // suppress compiler warning
834 return;
835 return;
836 }
837
838 protected:
839 virtual void computeImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors)const
840 {
841 descriptors = cv::Mat();
842 detectImpl(image,keypoints);
843 }
844
845 // indicates why a board could not be initialized for a certain keypoint
846 enum BState
847 {
848 MISSING_POINTS = 0, // at least 5 points are needed
849 MISSING_PAIRS = 1, // at least two pairs are needed
850 WRONG_PAIR_ANGLE = 2, // angle between pairs is too small
851 WRONG_CONFIGURATION = 3, // point configuration is wrong and does not belong to a board
852 FOUND_BOARD = 4 // board was found
853 };
854
855 void findKeyPoints(const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints,std::vector<cv::Mat> &feature_maps,
856 std::vector<std::vector<float> > &angles ,const cv::Mat& mask)const;
857 cv::Mat buildData(const std::vector<cv::KeyPoint>& keypoints)const;
858 std::vector<cv::KeyPoint> getInitialPoints(cv::flann::Index &flann_index,const cv::Mat &data,const cv::KeyPoint &center,float white_angle,float black_angle, float min_response = 0)const;
859 BState generateBoards(cv::flann::Index &flann_index,const cv::Mat &data, const cv::KeyPoint &center,
860 float white_angle,float black_angle,float min_response,const cv::Mat &img,
861 std::vector<Chessboard::Board> &boards)const;
862
863 private:
864 void detectImpl(const cv::Mat&,std::vector<cv::KeyPoint>&, const cv::Mat& mast =cv::Mat())const;
865 virtual void detectImpl(cv::InputArray image, std::vector<cv::KeyPoint>& keypoints, cv::InputArray mask=cv::noArray())const;
866
867 private:
868 Parameters parameters; // storing the configuration of the detector
869};
870}} // end namespace details and cv
871
872#endif
873

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of opencv/modules/calib3d/src/chessboard.hpp