20 #include <mrpt/3rdparty/do_opencv_includes.h>    36     const CImage& img_, CvSize pattern_size,
    37     std::vector<std::vector<CvPoint2D32f>>& out_corners)
    47     const size_t expected_quads_count =
    48         ((pattern_size.width + 1) * (pattern_size.height + 1) + 1) / 2;
    56     vector<CvCBQuad::Ptr> quads;
    57     vector<CvCBCorner::Ptr> corners;
    58     list<vector<CvCBQuad::Ptr>>
    61     if (pattern_size.width < 2 || pattern_size.height < 2)
    63         std::cerr << 
"Pattern should have at least 2x2 size" << endl;
    66     if (pattern_size.width > 127 || pattern_size.height > 127)
    68         std::cerr << 
"Pattern should not have a size larger than 127 x 127"    74     IplConvKernel* kernel_cross =
    75         cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_CROSS, 
nullptr);
    76     IplConvKernel* kernel_rect =
    77         cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT, 
nullptr);
    79     static int kernel_diag1_vals[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
    80     IplConvKernel* kernel_diag1 = cvCreateStructuringElementEx(
    81         3, 3, 1, 1, CV_SHAPE_CUSTOM, kernel_diag1_vals);
    82     static int kernel_diag2_vals[9] = {0, 0, 1, 0, 1, 0, 1, 0, 0};
    83     IplConvKernel* kernel_diag2 = cvCreateStructuringElementEx(
    84         3, 3, 1, 1, CV_SHAPE_CUSTOM, kernel_diag2_vals);
    85     static int kernel_horz_vals[9] = {0, 0, 0, 1, 1, 1, 0, 0, 0};
    86     IplConvKernel* kernel_horz = cvCreateStructuringElementEx(
    87         3, 3, 1, 1, CV_SHAPE_CUSTOM, kernel_horz_vals);
    88     static int kernel_vert_vals[9] = {0, 1, 0, 0, 1, 0, 0, 1, 0};
    89     IplConvKernel* kernel_vert = cvCreateStructuringElementEx(
    90         3, 3, 1, 1, CV_SHAPE_CUSTOM, kernel_vert_vals);
    98     cv::adaptiveThreshold(
   101         CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, block_size, 0);
   103     thresh_img_save = thresh_img.makeDeepCopy();
   114     bool last_dilation = 
false;
   116     for (
int dilations = 0; !last_dilation; dilations++)
   120         thresh_img = thresh_img_save.makeDeepCopy();
   124             thresh_img, dilations, kernel_cross, kernel_rect, kernel_diag1,
   125             kernel_diag2, kernel_horz, kernel_vert);
   132             thresh_img.asCvMatRef(), cv::Point(0, 0),
   133             cv::Point(thresh_img.getWidth() - 1, thresh_img.getHeight() - 1),
   134             CV_RGB(255, 255, 255), 3, 8);
   139             quads, corners, thresh_img, flags, dilations, 
true);
   140         if (quad_count <= 0) 
continue;
   150         std::vector<CVectorFixedDouble<2>> quad_centers;
   151         quad_centers.resize(quads.size());
   152         for (
size_t i = 0; i < quads.size(); i++)
   164         static const size_t MAX_NUM_CLUSTERS = 4;
   165         for (
size_t nClusters = 1; nClusters < MAX_NUM_CLUSTERS; nClusters++)
   167             vector<size_t> num_quads_by_cluster(nClusters);
   169             vector<int> assignments;
   173             for (
size_t i = 0; i < nClusters; i++)
   174                 num_quads_by_cluster[i] =
   175                     std::count(assignments.begin(), assignments.end(), i);
   179             for (
size_t i = 0; i < nClusters; i++)
   181                 if (num_quads_by_cluster[i] <
   182                     size_t(pattern_size.height) * size_t(pattern_size.width))
   186                 vector<CvCBQuad::Ptr> ith_quads;
   187                 for (
size_t q = 0; q < quads.size(); q++)
   188                     if (
size_t(assignments[q]) == i)
   189                         ith_quads.push_back(quads[q]);
   206                 for (
int group_idx = 0;; group_idx++)
   208                     vector<CvCBQuad::Ptr> quad_group;
   211                         ith_quads, quad_group, group_idx, dilations);
   212                     if (quad_group.empty()) 
break;
   215                     size_t count = quad_group.size();
   217                     if (count == expected_quads_count)
   226                         good_quad_groups.push_back(quad_group);
   244     for (
auto it = good_quad_groups.begin(); it != good_quad_groups.end(); ++it)
   248         for (
size_t i = 0; i < it->size(); i++)
   252                  (*it)[i]->corners[0]->pt.x +
   253                     (*it)[i]->corners[1]->pt.x + (*it)[i]->corners[2]->pt.x +
   254                     (*it)[i]->corners[3]->pt.x,
   255                  (*it)[i]->corners[0]->pt.y +
   256                     (*it)[i]->corners[1]->pt.y + (*it)[i]->corners[2]->pt.y +
   257                     (*it)[i]->corners[3]->pt.y);
   262         double min_dist = std::numeric_limits<double>::max();
   263         for (
size_t b = 0; b < out_boards_centers.size(); b++)
   268         if (out_corners.empty() || min_dist > 80)
   270             vector<CvPoint2D32f> pts;
   275                 out_corners.push_back(pts);
   277                 out_boards_centers.push_back(boardCenter);
   283     cvReleaseStructuringElement(&kernel_cross);
   284     cvReleaseStructuringElement(&kernel_rect);
   285     cvReleaseStructuringElement(&kernel_diag1);
   286     cvReleaseStructuringElement(&kernel_diag2);
   287     cvReleaseStructuringElement(&kernel_horz);
   288     cvReleaseStructuringElement(&kernel_vert);
   290     return !out_corners.empty();
   293 #endif  // MRPT_HAS_OPENCV void mrFindQuadNeighbors2(std::vector< CvCBQuad::Ptr > &quads, int dilation)
 
Shallow copy: the copied object is a reference to the original one. 
 
void keep_min(T &var, const K test_val)
If the second argument is below the first one, set the first argument to this lower value...
 
TPoint2D_< double > TPoint2D
Lightweight 2D point. 
 
void mrLabelQuadGroup(std::vector< CvCBQuad::Ptr > &quad_group, const CvSize &pattern_size, bool firstRun)
 
void icvCleanFoundConnectedQuads(std::vector< CvCBQuad::Ptr > &quad_group, const CvSize &pattern_size)
 
size_t getHeight() const override
Returns the height of the image in pixels. 
 
void asCvMat(cv::Mat &out_img, copy_type_t copy_type) const
Makes a shallow or deep copy of this image into the provided cv::Mat. 
 
This base provides a set of functions for maths stuff. 
 
size_t getWidth() const override
Returns the width of the image in pixels. 
 
bool do_special_dilation(CImage &thresh_img, const int dilations, IplConvKernel *kernel_cross, IplConvKernel *kernel_rect, IplConvKernel *kernel_diag1, IplConvKernel *kernel_diag2, IplConvKernel *kernel_horz, IplConvKernel *kernel_vert)
 
int myQuads2Points(const std::vector< CvCBQuad::Ptr > &output_quads, const CvSize &pattern_size, std::vector< CvPoint2D32f > &out_corners)
 
double kmeanspp(const size_t k, const LIST_OF_VECTORS1 &points, std::vector< int > &assignments, LIST_OF_VECTORS2 *out_centers=nullptr, const size_t attempts=3)
k-means++ algorithm to cluster a list of N points of arbitrary dimensionality into exactly K clusters...
 
void clear()
Resets the image to the state after a default ctor. 
 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
 
bool find_chessboard_corners_multiple(const CImage &img_, CvSize pattern_size, std::vector< std::vector< CvPoint2D32f >> &out_corners)
 
CvCBCorner::Ptr corners[4]
 
void quadListMakeUnique(std::vector< CvCBQuad::Ptr > &quads)
 
void icvFindConnectedQuads(std::vector< CvCBQuad::Ptr > &quad, std::vector< CvCBQuad::Ptr > &out_group, const int group_idx, [[maybe_unused]] const int dilation)
 
double distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space. 
 
A class for storing images as grayscale or RGB bitmaps. 
 
int icvGenerateQuads(vector< CvCBQuad::Ptr > &out_quads, vector< CvCBCorner::Ptr > &out_corners, const CImage &image, int flags, [[maybe_unused]] int dilation, bool firstRun)