Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
CheckerboardDetector.cpp
1 // author Jan Woetzel (c) 2006
2 #include "CheckerboardDetector.hh"
3 #include <Base/Common/W32Compat.hh>
4 #include <math.h>
5 #include <string>
6 #include <iostream>
7 #include <fstream>
8 #include <iomanip>
9 #include <sstream>
10 
11 //BIAS
12 #include <Base/Debug/Error.hh>
13 #include <Base/Math/Vector3.hh>
14 #include <Base/Image/ImageIO.hh>
15 #include <Base/Image/ImageConvert.hh>
16 
17 //OpenCV
18 #include <cv.h>
19 #include <highgui.h>
20 
21 using namespace std;
22 using namespace BIAS;
23 
24 
25 // Global parameters for checkerboard detection algorithm
26 int CheckerboardDetector::cornerDetectorFlags_ = CV_CALIB_CB_ADAPTIVE_THRESH;
27 int CheckerboardDetector::subPixelIterations_ = 100;
28 double CheckerboardDetector::subPixelAccuracy_ = 0.1;
29 
30 
31 int CheckerboardDetector::
32 Compute(const BIAS::Image<unsigned char> &img,
33  const unsigned int &xCorners, const unsigned int &yCorners,
34  t_CoordVecf &coords, const bool &saveDebugImage)
35 {
36  // allocate memory for corners
37  const int numCorners = xCorners*yCorners;
38  if ((int)coords.size() != numCorners)
39  coords.resize(numCorners, std::pair<float,float>(0.0f, 0.0f));
40 
41  // conversion required from BIAS image to CV image
42  IplImage* gray = NULL;
44  ImageConvert::ToGrey(img, imgGrey);
45  ImageConvert::BIAS2ipl(imgGrey, gray);
46  BIASASSERT(gray != NULL); // loaded?
47 
48  // checkerboard detection
49  int cornersFound = 0;
50  int res = cvFindChessboardCorners(gray, cvSize(xCorners, yCorners),
51  (CvPoint2D32f*)&(coords[0].first),
52  &cornersFound, cornerDetectorFlags_);
53 
54  if (res == 0) {
55  //BIASWARN("Could not find all "<<xCorners<<"x"<<yCorners<<" inner corners!");
56  return -3;
57  }
58 
59  // subpixel refinement
60  cvFindCornerSubPix(gray, (CvPoint2D32f*)&coords[0].first,
61  cornersFound, cvSize(5,5), cvSize(-1,-1),
62  cvTermCriteria(CV_TERMCRIT_ITER, //+CV_TERMCRIT_EPS,
63  subPixelIterations_, subPixelAccuracy_));
64 
65  // create and save debug image
66  if (saveDebugImage) {
68  IplImage *image=NULL;
69  ImageConvert::ToRGB(img, imgRGB);
70  //remember to delete image which is created in BIAS2ipl
71  ImageConvert::BIAS2ipl(imgRGB, image);
72  BIASASSERT(image != NULL); // loaded?
73  // confirm correctness of points
74  DrawPoints(image, (CvPoint2D32f*)&coords[0].first,
75  cornersFound, xCorners, yCorners);
76  cvSaveImage("out__findChessBoardCornerGuesses.jpg", image);
77  cvReleaseImage(&image);
78  }
79 
80  // release memory
81  cvReleaseImage(&gray);
82  return 0;
83 }
84 
85 
86 void CheckerboardDetector::
87 DrawPoints(void* imgVoid, void* ptArrayVoid, //t_CoordVecf &coords,
88  int numPts, const int xCorners, const int yCorners,
89  const bool DRAW_IDEAL_OVERLAY, const bool DRAW_AXES,
90  const bool DRAW_POINT_LABEL)
91 {
92 
93  CvArr* img = (CvArr*)imgVoid;
94  CvPoint2D32f *ptArray = (CvPoint2D32f*)ptArrayVoid;
95  CvPoint pt;
96  CvPoint ptOld;
97  CvFont font;
98  if (DRAW_POINT_LABEL) {
99  cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0f, 1.0f);
100  }
101 
102  // init old as first
103  if (numPts > 0) {
104  ptOld.x = (int)ptArray[0].x;
105  ptOld.y = (int)ptArray[0].y;
106  }
107  for (int i = 0; i < numPts; i++) {
108  int clr = (int)((float)i / numPts * 255.0);
109  pt.x = (int)ptArray[i].x;
110  pt.y = (int)ptArray[i].y;
111  cvCircle(img, pt, 3, CV_RGB(255-clr,0,clr), CV_FILLED);
112 
113  if (DRAW_POINT_LABEL){
114  // label the point
115  stringstream ssID;
116  ssID << i;
117  cvPutText(img, ssID.str().c_str(), pt, &font, CV_RGB(0,0,255));
118  }
119 
120  // next
121  ptOld=pt;
122  }
123 
124  if (DRAW_IDEAL_OVERLAY) {
125  // mark ideal pattern
126  // horizontal lines
127  for (int xx = 0; xx < xCorners*yCorners; xx += xCorners) {
128  cvLine(img, cvPointFrom32f(ptArray[xx]),
129  cvPointFrom32f(ptArray[xx+xCorners-1]),
130  CV_RGB(0,0,255), 1, CV_AA);
131  }
132  // vertical lines
133  for (int yy = 0; yy < xCorners; yy += 1) {
134  cvLine(img, cvPointFrom32f(ptArray[yy]),
135  cvPointFrom32f(ptArray[yy+xCorners*(yCorners-1)]),
136  CV_RGB(0,0,255), 1, CV_AA);
137  }
138  }
139 
140  if (DRAW_AXES) {
141  CvFont fontBig;
142  cvInitFont(&fontBig, CV_FONT_HERSHEY_PLAIN, 5.0f, 5.0f, 0, 2, CV_AA);
143  cvPutText(img, "0", cvPointFrom32f(ptArray[0]), &fontBig, CV_RGB(0,0,255));
144  cvLine(img, cvPointFrom32f(ptArray[0]), cvPointFrom32f(ptArray[xCorners-1]),
145  CV_RGB(255,0,0), 1, CV_AA);
146  cvPutText(img, "X", cvPointFrom32f(ptArray[xCorners-1]),
147  &fontBig, CV_RGB(255,0,0));
148  cvLine(img, cvPointFrom32f(ptArray[0]),
149  cvPointFrom32f(ptArray[xCorners*(yCorners-1)]),
150  CV_RGB(0,255,0), 1, CV_AA);
151  cvPutText(img, "Y", cvPointFrom32f(ptArray[xCorners*(yCorners-1)]),
152  &fontBig, CV_RGB(0,255,0));
153  }
154 
155  cvNamedWindow("img", 1);
156  cvMoveWindow("img", 0, 0);
157  cvShowImage("img", img);
158  cvWaitKey(1000);
159  cvDestroyAllWindows();
160 }
std::vector< std::pair< float, float > > t_CoordVecf
helper vector of coordinates