17 #include <mrpt/otherlibs/do_opencv_includes.h>    38         std::vector< std::vector<CvPoint2D32f> > &out_corners)
    48     const size_t expected_quads_count = ((pattern_size.width + 1)*(pattern_size.height + 1) + 1)/2;
    56         vector<CvCBQuadPtr>             quads;
    57     vector<CvCBCornerPtr>       corners;
    58         list< vector<CvCBQuadPtr> > good_quad_groups;  
    60     if( pattern_size.width < 2 || pattern_size.height < 2 )
    62         std::cerr  << 
"Pattern should have at least 2x2 size" << endl;
    65         if( pattern_size.width > 127 || pattern_size.height > 127 )
    67         std::cerr  << 
"Pattern should not have a size larger than 127 x 127" << endl;
    72         IplConvKernel *kernel_cross = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_CROSS,NULL);
    73         IplConvKernel *kernel_rect = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_RECT,NULL);
    75         static int kernel_diag1_vals[9] = {
    79         IplConvKernel *kernel_diag1 = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_CUSTOM,kernel_diag1_vals);
    80         static int kernel_diag2_vals[9] = {
    84         IplConvKernel *kernel_diag2 = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_CUSTOM,kernel_diag2_vals);
    85         static int kernel_horz_vals[9] = {
    89         IplConvKernel *kernel_horz = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_CUSTOM,kernel_horz_vals);
    90         static int kernel_vert_vals[9] = {
    94         IplConvKernel *kernel_vert = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_CUSTOM,kernel_vert_vals);
    99     int block_size = cvRound(
MIN(
img.getWidth(),
img.getHeight())*0.2)|1;
   101         cvAdaptiveThreshold( 
img.getAs<IplImage>(), thresh_img.getAs<IplImage>(), 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, block_size, 0 );
   103         cvCopy( thresh_img.getAs<IplImage>(), thresh_img_save.getAs<IplImage>());
   113         bool last_dilation = 
false;
   115         for( 
int dilations = 0; !last_dilation; dilations++ )
   118                 cvCopy( thresh_img_save.getAs<IplImage>(), thresh_img.getAs<IplImage>() );
   121                 last_dilation = 
do_special_dilation(thresh_img, dilations,kernel_cross,kernel_rect,kernel_diag1,kernel_diag2, kernel_horz,kernel_vert);
   127         cvRectangle( thresh_img.getAs<IplImage>(), cvPoint(0,0),
   128                                         cvPoint(thresh_img.getWidth()-1,thresh_img.getHeight()-1),
   129                                         CV_RGB(255,255,255), 3, 8);
   133         int quad_count = 
icvGenerateQuads( quads, corners, thresh_img, flags, dilations, 
true );
   134         if( quad_count <= 0 )
   145                 quad_centers.resize(quads.size());
   146                 for (
size_t i=0;i<quads.size();i++)
   149                         quad_centers[i][0] = 0.25 * (
q->corners[0]->pt.x + 
q->corners[1]->pt.x + 
q->corners[2]->pt.x + 
q->corners[3]->pt.x);
   150                         quad_centers[i][1] = 0.25 * (
q->corners[0]->pt.y + 
q->corners[1]->pt.y + 
q->corners[2]->pt.y + 
q->corners[3]->pt.y);
   154                 static const size_t MAX_NUM_CLUSTERS = 4;
   155                 for (
size_t nClusters=1;nClusters<MAX_NUM_CLUSTERS;nClusters++)
   157                         vector<size_t> num_quads_by_cluster(nClusters);
   159                         vector<int>     assignments;
   163                                 (nClusters,quad_centers,assignments);
   166                         for (
size_t i=0;i<nClusters;i++)
   167                                 num_quads_by_cluster[i] = 
std::count(assignments.begin(),assignments.end(), i);
   173                                         (
unsigned)quad_centers.size(),
   174                                         (unsigned)nClusters ));
   177                                 for (
size_t i=0;i<quad_centers.size();i++)
   179                                         static const TColor colors[4] = { 
TColor(255,0,0),
TColor(0,0,255),
TColor(255,0,255),
TColor(0,255,0) };
   180                                         im.
cross(quad_centers[i][0],quad_centers[i][1], colors[assignments[i]%4],
'+', 10);
   190                         for (
size_t i=0;i<nClusters;i++)
   192                                 if (num_quads_by_cluster[i]<
size_t(pattern_size.height*pattern_size.width))
   196                                 vector<CvCBQuadPtr> ith_quads;
   197                                 for (
size_t q=0;
q<quads.size();
q++)
   198                                         if (
size_t(assignments[
q])==i)
   199                                                 ith_quads.push_back(quads[
q]);
   212                                 for( 
int group_idx = 0; ; group_idx++ )
   214                                         vector<CvCBQuadPtr>             quad_group;
   217                                         if( quad_group.empty() )
   221                                         size_t count = quad_group.size();
   223                                         if( 
count == expected_quads_count )
   231                                                         for (
size_t i=0;i<quad_group.size();i++)
   233                                                                 static const TColor colors[4] = { 
TColor(255,0,0),
TColor(0,0,255),
TColor(255,0,255),
TColor(0,255,0) };
   234                                                                 const double x=0.25*(quad_group[i]->corners[0]->pt.x+quad_group[i]->corners[1]->pt.x+quad_group[i]->corners[2]->pt.x+quad_group[i]->corners[3]->pt.x);
   235                                                                 const double y=0.25*(quad_group[i]->corners[0]->pt.y+quad_group[i]->corners[1]->pt.y+quad_group[i]->corners[2]->pt.y+quad_group[i]->corners[3]->pt.y);
   236                                                                 im.
cross(
x,
y, colors[group_idx%4],
'+', 10);
   248                                                 good_quad_groups.push_back(quad_group);
   265         vector<TPoint2D> out_boards_centers; 
   266         for (list<vector<CvCBQuadPtr> >::
const_iterator it=good_quad_groups.begin();it!=good_quad_groups.end();++it)
   270                 for (
size_t i=0;i<it->size();i++)
   273                                  (*it)[i]->corners[0]->pt.x+(*it)[i]->corners[1]->pt.x+(*it)[i]->corners[2]->pt.x+(*it)[i]->corners[3]->pt.x,
   274                                  (*it)[i]->corners[0]->pt.y+(*it)[i]->corners[1]->pt.y+(*it)[i]->corners[2]->pt.y+(*it)[i]->corners[3]->pt.y );
   278                 double min_dist = std::numeric_limits<double>::max();
   279                 for (
size_t b=0;
b<out_boards_centers.size();
b++)
   282                 if (out_corners.empty() || min_dist > 80 )
   284                         vector<CvPoint2D32f> pts;
   288                                 out_corners.push_back(pts);
   290                                 out_boards_centers.push_back(boardCenter);
   297         cvReleaseStructuringElement(&kernel_cross);
   298         cvReleaseStructuringElement(&kernel_rect);
   299         cvReleaseStructuringElement(&kernel_diag1);
   300         cvReleaseStructuringElement(&kernel_diag2);
   301         cvReleaseStructuringElement(&kernel_horz);
   302         cvReleaseStructuringElement(&kernel_vert);
   304         return !out_corners.empty();
   308 #endif // MRPT_HAS_OPENCV int waitForKey(bool ignoreControlKeys=true, mrptKeyModifier *out_pushModifier=NULL)
Waits for any key to be pushed on the image or the console, and returns the key code. 
GLuint GLuint GLsizei count
bool find_chessboard_corners_multiple(const mrpt::utils::CImage &img_, CvSize pattern_size, std::vector< std::vector< CvPoint2D32f > > &out_corners)
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL. 
bool do_special_dilation(mrpt::utils::CImage &thresh_img, const int dilations, IplConvKernel *kernel_cross, IplConvKernel *kernel_rect, IplConvKernel *kernel_diag1, IplConvKernel *kernel_diag2, IplConvKernel *kernel_horz, IplConvKernel *kernel_vert)
A class for storing images as grayscale or RGB bitmaps. 
void mrFindQuadNeighbors2(std::vector< CvCBQuadPtr > &quads, int dilation)
GLdouble GLdouble GLdouble GLdouble q
void icvCleanFoundConnectedQuads(std::vector< CvCBQuadPtr > &quad_group, const CvSize &pattern_size)
const Scalar * const_iterator
int myQuads2Points(const std::vector< CvCBQuadPtr > &output_quads, const CvSize &pattern_size, std::vector< CvPoint2D32f > &out_corners)
void icvFindConnectedQuads(std::vector< CvCBQuadPtr > &quad, std::vector< CvCBQuadPtr > &out_group, const int group_idx, const int dilation)
double kmeanspp(const size_t k, const LIST_OF_VECTORS1 &points, std::vector< int > &assignments, LIST_OF_VECTORS2 *out_centers=NULL, const size_t attempts=3)
k-means++ algorithm to cluster a list of N points of arbitrary dimensionality into exactly K clusters...
void mrLabelQuadGroup(std::vector< CvCBQuadPtr > &quad_group, const CvSize &pattern_size, bool firstRun)
This base provides a set of functions for maths stuff. 
void cross(int x0, int y0, const mrpt::utils::TColor color, char type, unsigned int size=5, unsigned int width=1)
Draw a cross. 
This class creates a window as a graphical user interface (GUI) for displaying images to the user...
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf. 
void showImage(const mrpt::utils::CImage &img)
Show a given color or grayscale image on the window. 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
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...
void setWindowTitle(const std::string &str) MRPT_OVERRIDE
Changes the window title text. 
void quadListMakeUnique(std::vector< CvCBQuadPtr > &quads)
void colorImage(CImage &ret) const
Returns a RGB version of the grayscale image, or itself if it is already a RGB image. 
int icvGenerateQuads(vector< CvCBQuadPtr > &out_quads, vector< CvCBCornerPtr > &out_corners, const mrpt::utils::CImage &image, int flags, int dilation, bool firstRun)
double BASE_IMPEXP distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.