Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
biasClickImageCornersWx.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #ifdef WIN32
26 #include <Base/Common/BIASpragmaStart.hh>
27 #endif
28 #include <bias_config.h>
29 #include <Gui/ImageCanvasCheckerboardExtract.hh>
30 #include <Base/Image/Image.hh>
31 #include <Base/Image/ImageIO.hh>
32 #include <Base/Image/ImageConvert.hh>
33 #include <Image/ConvertHDR.hh>
34 #include <iostream>
35 #include <fstream>
36 #include <wx/wx.h>
37 #include <wx/spinctrl.h>
38 #include <Utils/Param.hh>
39 #include <Filter/Rescale.hh>
40 
41 #ifndef WIN32
42 #include <unistd.h>
43 #else //WIN32
44 #include "Base/Common/getopt_W32.h"
45 #endif //WIN32
46 
47 using namespace std;
48 using namespace BIAS;
49 
50 #define PARAM_FILE_NAME "clickcorners.param"
51 
52 #define HDR_STORAGETYPE float
53 /**
54  @file
55  @ingroup g_tools
56  @brief The tool allows to click corners/point in image and saves them on demand to a file, see biasClickImageCornersWx.cpp
57  @author ischiller 11/09
58 */
59 
60 namespace BIAS{
61 
62  enum {
63  // standard ids
64  ID_About= wxID_ABOUT,
65  ID_Exit = wxID_EXIT,
66  ID_Next = wxID_HIGHEST+2051,
68  ID_Save,
72  };
73 
74  class ClickImageCornersApp: public wxApp
75  {
76  virtual bool OnInit();
77  };
78 
79  /**
80  @class ClickCornersFrame
81  is derived from wxFrame, ICECCallBackInterface
82  */
83  class ClickCornersFrame :
84  public wxFrame, public BIAS::ICECCallbackInterface, public BIAS::Param
85  {
86  public:
87 
88  ClickCornersFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
89  virtual ~ClickCornersFrame();
90 
91  void Usage();
92  int Init(int argc, char* argv[]);
93  void Write();
94  void CheckerboardSelected(std::vector<BIAS::HomgPoint2D> & corners,
95  bool bOnlyFourPointsGiven, bool valid=true);
96  void HandleImage();
97  void OnRescaleImage(wxSpinEvent& event);
98 
99  void OnNext(wxCommandEvent& event);
100  void OnPrev(wxCommandEvent& event);
101  void OnSave(wxCommandEvent& event);
102  void OnInvalid(wxCommandEvent& event);
103  void OnHelp(wxCommandEvent& event);
104  void ShowText(const string text, int slot);
105 
106  protected:
108  string MatlabFilename_;
109  double fRescaleImageFactor_;
110  int corners_;
111  int colorDepth_;
112  bool bWriteDebug_;
113  std::vector<std::string> fileNames_;
114  vector<vector<BIAS::HomgPoint2D> > allCoords_;
115  vector<bool> bImageDone_;
117  unsigned int imageNumber_;
118  wxFlexGridSizer *Sizer_;
119  private:
120  DECLARE_EVENT_TABLE()
121  };
122 }//end namespace
123 
124 
125 
126 
127 ///////////////////////////////////////////////////////
128 //declaration
129 DECLARE_APP(ClickImageCornersApp)
130 
131 // implementation
132 IMPLEMENT_APP(ClickImageCornersApp)
133 
134 bool ClickImageCornersApp::OnInit()
135 {
136  ClickCornersFrame *frame_;
137  frame_ = new ClickCornersFrame(wxT("ClickCorners"), wxPoint(50,50),
138  wxSize(700,550) );
139 
140  // read params from file
141  int ret =0;
142  ret = frame_->Init(argc, WxToAsciiArray(argv, argc));
143  if(ret <0){
144  frame_->Usage();
145  exit(-1);
146  }
147  frame_->Show(TRUE);
148  frame_->HandleImage();
149  SetTopWindow(frame_);
150  return TRUE;
151 
152 }
153 
154 ///////////////////////////////////////////////////////
155 ClickCornersFrame::
156 ClickCornersFrame(const wxString& title,const wxPoint& pos,const wxSize& size):
157  wxFrame((wxFrame *)NULL, -1, title, pos, size)
158 {
159  // Sizer and ImageCanvas
160  Sizer_ = new wxFlexGridSizer(1,2,0,0);
161  Sizer_->AddGrowableCol(0);
162  Sizer_->AddGrowableRow(0);
163 
164  ic_=new ImageCanvasCheckerboardExtract(this, NULL, 1,-1,wxDefaultPosition, wxSize(640,480));
165  ic_->KeepScrollPosition(true);
166  fRescaleImageFactor_ = 1.0;
167 
168  wxSize buttonSize(65,30);
169  // create tool bar
170  wxToolBar* toolBar = CreateToolBar();
171  wxButton *pBNext= new wxButton(toolBar, ID_Next, wxT("Next"),wxDefaultPosition,buttonSize);
172  wxButton *pBPrev= new wxButton(toolBar, ID_Prev, wxT("Previous"),wxDefaultPosition,buttonSize);
173  wxButton *pBSave= new wxButton(toolBar, ID_Save, wxT("Save"),wxDefaultPosition,buttonSize);
174  wxButton *pBInvalid= new wxButton(toolBar, ID_Invalid, wxT("Invalid"),wxDefaultPosition,buttonSize);
175  wxButton *pBHelp= new wxButton(toolBar, ID_Help, wxT("Help"),wxDefaultPosition,buttonSize);
176  wxSpinCtrl *pRescaleImageSpinCtrl_ = new wxSpinCtrl(toolBar,ID_RescaleImage,
177  wxT("Rescale"), wxDefaultPosition,wxSize(60,30),
178  wxSP_ARROW_KEYS,1,60,10,wxT("10"));
179  pRescaleImageSpinCtrl_->SetToolTip(wxT("Rescale image for corners selection."));
180 
181  toolBar->AddControl(pBPrev);
182  toolBar->AddControl(pBNext);
183  toolBar->AddControl(pBSave);
184  toolBar->AddControl(pBInvalid);
185  toolBar->AddControl(pBHelp);
186  toolBar->AddControl(pRescaleImageSpinCtrl_);
187  toolBar->Realize();
188  //finally add to sizer
189  Sizer_->Add(ic_,0,wxALL|wxEXPAND, 5);
190  SetSizer(Sizer_);
191  Layout();
192  SetMinSize(wxSize(700,550));
193  Fit();
194  CreateStatusBar(2);
195 }
196 
197 ClickCornersFrame::
198 ~ClickCornersFrame(){
199  if(ic_ != NULL)
200  delete ic_;
201 
202  if(Sizer_ != NULL)
203  delete Sizer_;
204 }
205 
206 void ClickCornersFrame::
207 OnNext(wxCommandEvent& event){
208  if(imageNumber_ < fileNames_.size()-1 && bImageDone_[imageNumber_]){
209  imageNumber_++;
210  HandleImage();
211  }
212  else if(imageNumber_ == fileNames_.size()-1){
213  string message ="Done! Now save the corners.";
214  wxMessageBox(AsciiToWx(message),
215  wxT("Detector"), wxOK , this);
216  ShowText(message,0);
217  }
218  else
219  ShowText("Select Corners!",0);
220 }
221 
222 void ClickCornersFrame::
223 OnPrev(wxCommandEvent& event){
224  if(imageNumber_ >=1 && bImageDone_[imageNumber_]){
225  imageNumber_--;
226  HandleImage();
227  }
228  else
229  ShowText("Select Corners!",0);
230 }
231 
232 void ClickCornersFrame::
233 OnInvalid(wxCommandEvent& event){
234  std::vector<BIAS::HomgPoint2D> corners;
235  BIAS::HomgPoint2D c(-1,-1,-1);
236  corners.push_back(c);
237  CheckerboardSelected(corners,false,true);
238 }
239 
240 void ClickCornersFrame::
241 OnSave(wxCommandEvent& event){
242  Write();
243 }
244 
245 void ClickCornersFrame::
246 OnHelp(wxCommandEvent& event){
247  string message;
248  message = "This is the MIP corners clicking tool \nAfter selecting all corners in one image press \"Next\".\n\nFinally save the corners, pressing \"Save\".";
249 
250  wxMessageBox(AsciiToWx(message),
251  wxT("Detector"), wxOK , this);
252 }
253 
254 void ClickCornersFrame::
255 OnRescaleImage(wxSpinEvent& event)
256 {
257  fRescaleImageFactor_ = event.GetPosition()/10.0;
258  HandleImage();
259 }
260 
261 void ClickCornersFrame::
262 Usage()
263 {
264  cout <<"Usage: biasClickImageCornersWx -f Filename.m -x xnum -y ynum -d image1 image2 ..."<<endl
265  <<endl;
266  cout <<" The tool tries to find checkerboards in the input images" << endl
267  <<" finds corners also in fisheye distorted images and " << endl
268  <<" writes these to the Matlab file 'Filename.m'." << endl
269  <<" xnum and ynum are the number of the checkerboards inner corners."
270  << endl
271  <<" -d writes debug images." << endl
272  <<" Do not use .mip images since Matlab is unable to read them." << endl
273  <<endl<<endl;
274 }
275 
276 
277 int ClickCornersFrame::
278 Init(int argc, char* argv[])
279 {
280  MatlabFilename_ = "ExtractedCorners.m";
281  corners_ = 1;
282  bWriteDebug_ = false;
283  imageNumber_=0;
284 
285  int *colorDepth = AddParamInt("colorDepth", "color depth in bit", 8);
286  int *corners = AddParamInt("corners","Number of Points", 1,1,1000,'c');
287  string *imageList = AddParamString("ImageList","List with images","");
288  // update parameters from file with arguments from command line
289  if (argc > 1){
290  UpdateParameter(argc, argv, PARAM_FILE_NAME);
291  }
292  else
293  return -1;
294  Param::ParseListFile(*imageList,fileNames_);
295  allCoords_.resize(fileNames_.size());
296  bImageDone_.resize(fileNames_.size());
297  for(unsigned i=0;i<fileNames_.size();i++)
298  bImageDone_[i] = false;
299  corners_ = *corners;
300  colorDepth_ = *colorDepth;
301  //yCorners_ = *yc;
302  ic_->SetPatternParameters( corners_, 1);
303  ic_->ManuallySetSelectionMode(true);
304  imageNumber_=0;
305  return 0;
306 }
307 
308 void ClickCornersFrame::
309 HandleImage(){
310  BIAS::ImageBase image;
311  BIAS::Image<unsigned char> imageUC,imageUC2;
312 
313  if(BIAS::ImageIO::Load(fileNames_[imageNumber_],image)==0){
314 
315  if(colorDepth_ != 8){
316  Image<float> imageFl;
317  ImageConvert::ConvertST(image, imageFl, ImageBase::ST_float);
318  ConvertHDR<HDR_STORAGETYPE> hdrHandler;
319  hdrHandler.ToUnsignedCharGamma(imageFl, imageUC, 1.0, pow(2.0, colorDepth_));
320  } else if(image.GetStorageType() != ImageBase::ST_unsignedchar){
321  ImageConvert::ConvertST(image, imageUC, ImageBase::ST_unsignedchar);
322  } else {
323  imageUC = image;
324  }
325 
326  if(imageUC.GetColorModel() !=ImageBase::CM_Grey){
328  BIAS::ImageConvert::ToRGB(imageUC, dbImage2);
329  BIAS::ImageConvert::ToGrey(dbImage2,imageUC);
330  }
331 
332  if(fRescaleImageFactor_ != 1.0){
333  if(fRescaleImageFactor_ >1.0){
334  rescaler_.Upsample (imageUC, imageUC2,
335  imageUC.GetWidth() * fRescaleImageFactor_,
336  imageUC.GetHeight() * fRescaleImageFactor_);
337  }
338  else if(fRescaleImageFactor_ <1.0){
339  rescaler_.Downsample (imageUC, imageUC2,
340  imageUC.GetWidth() * fRescaleImageFactor_,
341  imageUC.GetHeight() * fRescaleImageFactor_);
342  }
343  ic_->Show(imageUC2,"Select");
344  }
345  else
346  ic_->Show(imageUC,"Select");
347 
348  ic_->SetPatternParameters (corners_,1);
349  ic_->ManuallySetSelectionMode(true);
350  if( bImageDone_[imageNumber_])
351  ic_->DisplayCheckerboardCorners(allCoords_[imageNumber_],fRescaleImageFactor_);
352  else
353  ic_->SelectCheckerboardCorners(*this,true,false);
354  }
355 }
356 
357 void ClickCornersFrame::
358 CheckerboardSelected(std::vector<BIAS::HomgPoint2D> & corners, bool bOnlyFourPointsGiven, bool valid){
359  if(bOnlyFourPointsGiven){
360  ShowText("Only four points, this is invalid!",0);
361  return;
362  }
363 
364  // delete old corners
365  allCoords_[imageNumber_].clear();
366  for(unsigned int k=0;k< corners.size();k++){
367  corners[k][0] /= fRescaleImageFactor_;
368  corners[k][1] /= fRescaleImageFactor_;
369  allCoords_[imageNumber_].push_back(corners[k]);
370  }
371  ShowText("Points selected!",0);
372  bImageDone_[imageNumber_] = true;
373 }
374 
375 
376 void ClickCornersFrame::
377 Write(){
378 
379  wxString fileName;
380  wxFileDialog dialog(this,wxT("Save Corners"),wxT(""),wxT(""),
381  wxT("Matlab (*.m)|*.m"),
382  wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
383  int ret = dialog.ShowModal();
384  if(ret == wxID_OK){
385  fileName = dialog.GetPath();
386  ofstream ofs(WxToAscii(fileName));
387  // ofs << "numpoints = [" << corners_ <<"];" << endl;
388 
389  // ofs << "imagenames = {";
390  // for (unsigned int i=0; i<fileNames_.size(); i++) {
391  // ofs << "'" << fileNames_[i] << "' ";
392  // }
393  // ofs << "};" << endl;
394 
395  // ofs << "xpos = [";
396  for (unsigned int i=0; i<allCoords_.size(); i++) {
397  for (unsigned int j=0; j<allCoords_[i].size(); j++) {
398  ofs << (allCoords_[i][j])[0] << " "<<(allCoords_[i][j])[1]<< endl;
399  }
400  }
401  ofs.close();
402  }
403 }
404 
405 void ClickCornersFrame::
406 ShowText(const string text, int slot){
407  if(GetStatusBar() != NULL)
408  GetStatusBar()->SetStatusText(AsciiToWx(text),slot);
409 }
410 
411 BEGIN_EVENT_TABLE(BIAS::ClickCornersFrame, wxFrame)
412  EVT_BUTTON (ID_Next, ClickCornersFrame::OnNext)
413  EVT_BUTTON (ID_Prev, ClickCornersFrame::OnPrev)
414  EVT_BUTTON (ID_Save, ClickCornersFrame::OnSave)
415  EVT_BUTTON (ID_Invalid, ClickCornersFrame::OnInvalid)
416  EVT_BUTTON (ID_Help, ClickCornersFrame::OnHelp)
417  EVT_SPINCTRL (ID_RescaleImage,ClickCornersFrame::OnRescaleImage)
418 END_EVENT_TABLE()
419 
420 #ifdef WIN32
421 #include <Base/Common/BIASpragmaEnd.hh>
422 #endif
This class handles conversions of HDR images to for example unsigned char.
Definition: ConvertHDR.hh:47
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
wxString AsciiToWx(const char *thestring)
Converts a C string to a wxString.
Definition: StringConv.hh:32
int ToUnsignedCharGamma(BIAS::Image< StorageType > &src, BIAS::Image< unsigned char > &dst, float gamma, unsigned int currentMaxVal)
Conversion to unsigned char image, leaves min/max part intact.
Definition: ConvertHDR.cpp:119
unsigned int GetWidth() const
Definition: ImageBase.hh:312
unsigned int GetHeight() const
Definition: ImageBase.hh:319
provides functionality for selection of checkerboard patterns
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
This class Param provides generic support for parameters.
Definition: Param.hh:231
callback interface for ImageCanvasCheckerBoardExtract
static int Load(const std::string &FileName, ImageBase &img)
first tries a call to Read MIP image and if that fails, tries to Import Image with all other availabl...
Definition: ImageIO.cpp:141
Class for converting an array of wxStrings to an array of non-const ASCII strings.
Definition: StringConv.hh:60
enum EStorageType GetStorageType() const
Definition: ImageBase.hh:414
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
static int ToRGB(const Image< StorageType > &source, Image< StorageType > &dest)
Create a RGB converted copy of source image in this.
static int ToGrey(const ImageBase &source, ImageBase &dest)
wrapper for the templated function ToGrey