Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ImageCanvasCheckerboardExtract.cpp
1 #include <Base/Common/BIASpragmaStart.hh>
2 #include "ImageCanvasCheckerboardExtract.hh"
3 #include <FeatureDetector/CheckerboardDetector.hh>
4 #include <FeatureDetector/CheckerboardDetectorCrossFilter.hh>
5 #include <Base/Image/ImageConvert.hh>
6 #include <Base/ImageUtils/ImageDraw.hh>
7 #include <Base/Image/ColourRGB.hh>
8 #include <Base/Geometry/HomgPoint2D.hh>
9 #include <Utils/IOUtils.hh>
10 #include <Base/Common/BIASpragmaEnd.hh>
11 using namespace BIAS;
12 using namespace std;
13 
14 
16 {}
17 
19 {}
20 
22 CheckerboardSelected(std::vector<BIAS::HomgPoint2D > &corners,
23  bool bOnlyFourPointsGiven, bool valid)
24 {
25  BIASERR("error: function of derived class should be called");
26 }
27 
28 /////////////////////////////////////////////////////////////////
29 
32  wxStatusBar* sbar,
33  int sbarid, wxWindowID id,
34  const wxPoint& pos,
35  const wxSize& size,
36  long style,
37  const wxString& name)
38  : ImageCanvas(parent, sbar, sbarid, id, pos, size, style, name)
39 {
41  SelectCheckerboard_=false;
42  CallbackObj_=NULL;
43  bEnforceAllCorners_=false;
44  SelectCheckerboard_=false;
45  DisplayCheckerboard_ = false;
46  bSelectable_=true;
48 }
49 
52 {
54  CallbackObj_ = NULL;
55 }
56 
57 
59 SetPatternParameters (unsigned int xCorners, unsigned int yCorners) {
60  xCorners_ = xCorners;
61  yCorners_ = yCorners;
64  for(unsigned i=0;i<allCheckerboardCorners_.size();i++)
65  allCheckerboardCorners_[i] = HomgPoint2D(0.0,0.0,1.0);
66 }
68 EnableCornerSelection(bool selectable){
69  bSelectable_ = selectable;
70 }
71 
74  bool allCorners,bool autoInvalidate)
75 {
76  //signal that we are in selection mode
77  SelectCheckerboard_ = true;
78  DisplayCheckerboard_ = false;
80  bEnforceAllCorners_= allCorners;
81  CallbackObj_=&obj;
82 
83  //Here we try to automatically extract the checkerboard
84  t_CoordVecf coords;
85  const int numCorners = xCorners_*yCorners_;
86  coords.resize(numCorners, std::pair<float,float>(0.0f,0.0f));
87  //int memory = IOUtils::GetApplicationMemory();
88  int res = -1;
89  if(numCorners > 5)
91  case 0:// Use OpenCV:
92  res = CheckerboardDetector::Compute(rgbim_,xCorners_,yCorners_,coords);
93  break;
94 
95  case 1: // Use OpenCV with CrossFilter fallback:
96  res = CheckerboardDetector::Compute(rgbim_,xCorners_,yCorners_,coords);
97  if (res != 0)
99  break;
100 
101  case 2: // Use CrossFilter
103  break;
104  }
105  // int memorydiff = IOUtils::GetApplicationMemory()-memory;
106  // cout<<"After Compute = +"<<memorydiff*4<<"kB "<<memorydiff/256<<"MB"<<endl;
107  if(res!= 0){
108  if(autoInvalidate){
109  for(unsigned i=0;i<allCheckerboardCorners_.size();i++)
110  allCheckerboardCorners_[i] = HomgPoint2D(-1.0,-1.0,1.0); //invalid
111  SelectCheckerboard_ = false;
112  NumLeftClicks_=0;
114  // int memorydiff = IOUtils::GetApplicationMemory()-memory;
115  // cout<<"detecting failed auto = +"<<memorydiff*4<<"kB "<<memorydiff/256<<"MB"<<endl;
116  return;
117  }
118  else{
119  for(unsigned i=0;i<allCheckerboardCorners_.size();i++)
120  allCheckerboardCorners_[i] = HomgPoint2D(0.0,0.0,1.0);
121  // int memorydiff = IOUtils::GetApplicationMemory()-memory;
122  // cout<<"detecting failed = +"<<memorydiff*4<<"kB "<<memorydiff/256<<"MB"<<endl;
123  return;
124  }
125  }
126  else{
127  for(unsigned int i=0;i< coords.size();i++){
129  HomgPoint2D(coords[i].first,coords[i].second,1);
130  }
131  //draw it
133  //reset flags
134  SelectCheckerboard_=false;
136  NumLeftClicks_=0;
137  //signal
139 #ifdef WIN32
140  this->Refresh();
141 #else
142  wxPaintEvent pe;
143  wxPostEvent(this->GetEventHandler(),pe);
144 #endif
145  }
146  // memorydiff = IOUtils::GetApplicationMemory()-memory;
147  // cout<<"detecting corners = +"<<memorydiff*4<<"kB "<<memorydiff/256<<"MB"<<endl;
148 
149 }
150 
151 
153 DisplayCheckerboardCorners(std::vector<HomgPoint2D > &corners,
154  double rescaleFactor){
155 
156  bool oldAllC = bEnforceAllCorners_;
157  bEnforceAllCorners_ = true;
158  DisplayCheckerboard_ = true;
159  SelectCheckerboard_=false;
160  NumLeftClicks_ = 0;
161  if(corners.size() != allCheckerboardCorners_.size()){
162  BIASERR("Inconsistent number of corners:"<<corners.size()<<" vs. "
163  <<allCheckerboardCorners_.size());
164  return;
165  }
166  for(unsigned i=0;i<corners.size();i++)
167  allCheckerboardCorners_[i] = corners[i];
168  DrawCheckerboardCorners_(rescaleFactor);
169  bEnforceAllCorners_ = oldAllC;
170 }
171 
174  double rescaleFactor){
175  //performance warning : double copy of corners
176 
177  for(unsigned i=0;i<corners.size();i++)
178  allCheckerboardCorners_[i] = HomgPoint2D(corners[i][0],corners[i][1],1.0);
180 }
181 
183  if (detector >= 0 && detector <= 2)
184  checkerboardDetectorMethod_ = detector;
185 }
186 
187 BEGIN_EVENT_TABLE (ImageCanvasCheckerboardExtract, ImageCanvas)
188  EVT_LEFT_DOWN (ImageCanvasCheckerboardExtract::OnLeftMouseButton)
189  EVT_RIGHT_DOWN (ImageCanvasCheckerboardExtract::OnRightMouseButton)
190  EVT_MOTION (ImageCanvasCheckerboardExtract::OnMouseMove)
191  EVT_PAINT (ImageCanvasCheckerboardExtract::OnPaint)
192 END_EVENT_TABLE()
193 
194 
196 OnLeftMouseButton(wxMouseEvent &event)
197 {
198  if(bSelectable_ && SelectCheckerboard_){
199  wxClientDC dc(this);
200  PrepareDC(dc);
201  wxPoint pos = event.GetPosition();
202  double x = dc.DeviceToLogicalX( pos.x );
203  double y = dc.DeviceToLogicalY( pos.y );
204  // cout<<"Selected:"<<x<<","<<y<<endl;
205  HomgPoint2D point(x,y),pointZero(0.0,0.0);
206 
207  if(bEnforceAllCorners_){
208  allCheckerboardCorners_[NumLeftClicks_] = point;
209  if(NumLeftClicks_ == 0){
210  for(unsigned i=1;i<allCheckerboardCorners_.size();i++)
211  allCheckerboardCorners_[i] = HomgPoint2D(0.0,0.0,1.0);
212  }
213  NumLeftClicks_++;
214 
215  DrawCheckerboardCorners_();
216  if(NumLeftClicks_ == xCorners_*yCorners_){
217  SelectCheckerboard_=false;
218  DisplayCheckerboard_ = true;
219  NumLeftClicks_=0;
220  CallbackObj_->CheckerboardSelected(allCheckerboardCorners_,false,true);
221  }
222  }//end if(bEnforceAllCorners_)
223  else{
224  if(NumLeftClicks_ == 0){
225  allCheckerboardCorners_[0] = point;
226  allCheckerboardCorners_[xCorners_-1]=pointZero;
227  allCheckerboardCorners_[(xCorners_*yCorners_-1)] =pointZero;
228  allCheckerboardCorners_[(yCorners_-1)*(xCorners_)] =pointZero;
229  }
230  else if (NumLeftClicks_ == 1){
231  allCheckerboardCorners_[xCorners_-1] = point;
232  }
233  else if (NumLeftClicks_ == 2){
234  allCheckerboardCorners_[(xCorners_*yCorners_-1)] = point;
235  }
236  else if (NumLeftClicks_ == 3){
237  allCheckerboardCorners_[(yCorners_-1)*(xCorners_)] = point;
238  }
239  NumLeftClicks_++;
240 
241  if(NumLeftClicks_ == 4){
242  DrawCheckerboardCorners_();
243  SelectCheckerboard_=false;
244  DisplayCheckerboard_ = true;
245  NumLeftClicks_=0;
246  CallbackObj_->CheckerboardSelected(allCheckerboardCorners_,true,true);
247  }
248  }
249  }//end if(selectable && ....)
250  else
251  event.Skip();
252 }
253 
254 
255 
257 OnRightMouseButton(wxMouseEvent &event)
258 {
259  if(bSelectable_){
260  //if we come from display, we allow to define new corners
262  SelectCheckerboard_ = true;
263  DisplayCheckerboard_= false;
264  }
266  NumLeftClicks_ = 0;
267  for(unsigned i=0;i<allCheckerboardCorners_.size();i++)
268  allCheckerboardCorners_[i] = HomgPoint2D(0.0,0.0,1.0);
269 
270  RefreshDrawIm_();
271 
272 #ifdef WIN32
273  this->Refresh();
274 #else
275  wxPaintEvent pe;
276  wxPostEvent(this->GetEventHandler(),pe);
277 #endif
278  }
279  }
280  else
281  event.Skip();
282 }
283 
285 OnPaint(wxPaintEvent &event)
286 {
287  ImageCanvas::OnPaint(event);
288 }
289 
290 
292 OnMouseMove(wxMouseEvent &event)
293 {
296  wxClientDC dc(this);
297  PrepareDC(dc);
298 
299  wxPoint pos = event.GetPosition();
300  int x = dc.DeviceToLogicalX( pos.x );
301  int y = dc.DeviceToLogicalY( pos.y );
302 
303  HomgPoint2D point(x,y,1);
304 
305  if(NumLeftClicks_ == 0){
306  allCheckerboardCorners_[0] = point;
307  }
308  else if (NumLeftClicks_ == 1){
310  }
311  else if (NumLeftClicks_ == 2){
313  }
314  else if (NumLeftClicks_ == 3){
316  }
317 
319  }
320 
321  event.Skip();
322 }
323 
325 DrawCheckerboardCorners_(double rescaleFactor)
326 {
327  unsigned char red[]={255, 0, 0};
328  unsigned char green[]={0,255, 0};
329  unsigned char blue[]={0,0,255};
330 
331  RefreshDrawIm_();
332 
333  unsigned nrCorners = allCheckerboardCorners_.size()-1;
334 
336  for(unsigned i =0 ;i<allCheckerboardCorners_.size();i++){
337  stringstream text;
338  text<<i;
339 
340  if((rgbim_.GetWidth() % 4) == 0){
342  Text(rgbim_,text.str().c_str(),
343  (unsigned)(allCheckerboardCorners_[i][0]*rescaleFactor),
344  (unsigned)(allCheckerboardCorners_[i][1]*rescaleFactor),
345  ColourRGB<unsigned char>(255, 0, 0));
346  }
347  if(i==0)
350  (unsigned)(allCheckerboardCorners_[i][0]*rescaleFactor),
351  (unsigned)(allCheckerboardCorners_[i][1]*rescaleFactor), 3,green);
352  else if(i==nrCorners)
355  (unsigned)(allCheckerboardCorners_[i][0]*rescaleFactor),
356  (unsigned)(allCheckerboardCorners_[i][1]*rescaleFactor), 3,blue);
357 
358  else
361  (unsigned)(allCheckerboardCorners_[i][0]*rescaleFactor),
362  (unsigned)(allCheckerboardCorners_[i][1]*rescaleFactor), 3,red);
363  }
364  }
365  else{
366  unsigned int start[2], stop[2];
367 
368  if(allCheckerboardCorners_[0][0]>0.0 &&
369  allCheckerboardCorners_[0][1]>0.0 &&
372  {
373  start[0] = (int)(allCheckerboardCorners_[0][0]*rescaleFactor);
374  start[1] = (int)(allCheckerboardCorners_[0][1]*rescaleFactor);
375  stop[0] = (int)(allCheckerboardCorners_[xCorners_-1][0]*rescaleFactor);
376  stop[1] = (int)(allCheckerboardCorners_[xCorners_-1][1]*rescaleFactor);
377  ImageDraw<unsigned char>::Line(rgbim_, start,stop, green);
378 
381  start[0] = (int)(allCheckerboardCorners_[xCorners_-1][0]*rescaleFactor);
382  start[1] = (int)(allCheckerboardCorners_[xCorners_-1][1]*rescaleFactor);
383  stop[0] = (int)(allCheckerboardCorners_[(xCorners_*yCorners_-1)][0]*rescaleFactor);
384  stop[1] = (int)(allCheckerboardCorners_[(xCorners_*yCorners_-1)][1]*rescaleFactor);
385  ImageDraw<unsigned char>::Line(rgbim_,start,stop, green);
386  }
387  if(allCheckerboardCorners_[(yCorners_-1)*(xCorners_)][0]>0.0 &&
389  start[0] = (int)(allCheckerboardCorners_[(xCorners_*yCorners_-1)][0]*rescaleFactor);
390  start[1] = (int)(allCheckerboardCorners_[(xCorners_*yCorners_-1)][1]*rescaleFactor);
391  stop[0] = (int)(allCheckerboardCorners_[(yCorners_-1)*(xCorners_)][0]*rescaleFactor);
392  stop[1] = (int)(allCheckerboardCorners_[(yCorners_-1)*(xCorners_)][1]*rescaleFactor);
393  ImageDraw<unsigned char>::Line(rgbim_,start,stop, blue);
394  start[0] = (int)(allCheckerboardCorners_[(yCorners_-1)*(xCorners_)][0]*rescaleFactor);
395  start[1] = (int)(allCheckerboardCorners_[(yCorners_-1)*(xCorners_)][1]*rescaleFactor);
396  stop[0] = (int)(allCheckerboardCorners_[0][0]*rescaleFactor);
397  stop[1] = (int)(allCheckerboardCorners_[0][1]*rescaleFactor);
398  ImageDraw<unsigned char>::Line(rgbim_,start,stop, red);
399 
400  }
401  }
402  }
403 
404 #ifdef WIN32
405  this->Refresh();
406 #else
407  wxPaintEvent pe;
408  wxPostEvent(this->GetEventHandler(),pe);
409 #endif
410 }
411 
413 {
414  Image<unsigned char> tmprgb;
417  BIASERR("error converting image");
418  }
419  } else {
420  tmprgb=origim_;
421  }
422  Show(origim_, tmprgb, ImageName_);
423 }
BIAS::ImageBase origim_
Definition: ImageCanvas.hh:156
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
void SetPatternParameters(unsigned int xCorners, unsigned int yCorners)
static int Compute(BIAS::Image< unsigned char > &img, const unsigned int &xCorners, const unsigned int &yCorners, t_CoordVecf &coords, const bool &saveDebugImage=false)
Detects a (recommended asymmetric) checkerboard pattern.
virtual void OnPaint(wxPaintEvent &event)
display image in wx application, provides zoom and investigation functionality
Definition: ImageCanvas.hh:38
static int CircleCenterFilled(Image< StorageType > &im, unsigned int CenterX, unsigned int CenterY, unsigned int Radius, const StorageType Value[])
draws a filled circle using Value
Definition: ImageDraw.cpp:1023
std::vector< std::pair< float, float > > t_CoordVecf
helper vector of coordinates
unsigned int GetWidth() const
Definition: ImageBase.hh:312
virtual void OnRightMouseButton(wxMouseEvent &event)
void SelectCheckerboardCorners(ICECCallbackInterface &obj, bool allCorners, bool autoInvalidate=false)
Call SelectCheckerboardCorners with an object derived from ICECallbackInterface.
std::vector< BIAS::HomgPoint2D > allCheckerboardCorners_
static int Line(Image< StorageType > &im, const unsigned int start[2], const unsigned int end[2], const StorageType value[])
lines
Definition: ImageDraw.cpp:404
void DrawCheckerboardCorners_(double rescaleFactor=1.0)
color values, 3 channels, order: red,green,blue
Definition: ImageBase.hh:131
provides functionality for selection of checkerboard patterns
std::string ImageName_
Definition: ImageCanvas.hh:185
virtual void CheckerboardSelected(std::vector< HomgPoint2D > &corners, bool bOnlyFourPointsGiven, bool valid=true)
this function should be overloaded
ImageCanvasCheckerboardExtract(wxWindow *parent, wxStatusBar *sbar=NULL, int sbarid=0, wxWindowID id=-1, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(640, 480), long style=wxHSCROLL|wxVSCROLL|wxFULL_REPAINT_ON_RESIZE, const wxString &name=AsciiToWx("CheckerboardExtract"))
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
BIAS::Image< unsigned char > rgbim_
Definition: ImageCanvas.hh:157
callback interface for ImageCanvasCheckerBoardExtract
static int Compute(const BIAS::Image< unsigned char > &img, const unsigned int &xCorners, const unsigned int &yCorners, t_CoordVecf &coords, const bool &saveDebugImage=false)
Detects a (recommended asymmetric) checkerboard pattern.
static int Convert(BIAS::ImageBase &source, BIAS::ImageBase &dest, enum BIAS::ImageBase::EColorModel targetColorModel, bool bPlanar=false)
main general conversion function, calls desired specialized functions, always initializes the destIma...
virtual void Show(BIAS::Image< unsigned char > &im, std::string name="")
void SetCheckerboardDetector(int detector)
Set the checkerboard detector method.
void DisplayCheckerboardCorners(std::vector< BIAS::Vector2< double > > &corners, double rescaleFactor=1.0)
Call DisplayCheckerboardCorners with an object derived from ICECallbackInterface. ...
static void Text(BIAS::Image< StorageType > &dstImg, const std::string &message, const int &posX=0, const int &posY=20, const ColourRGB< StorageType > &colorRGB=ColourRGB< StorageType >(255, 255, 255), const int fontface=1, const double hscale=1.0, const double vscale=1.0, const double shear=0, const int thickness=1, const int linetype=8)
OpenCV: Draw Text into image.
Definition: ImageDraw.cpp:1384
class BIASGeometryBase_EXPORT HomgPoint2D