1 #include <Base/Common/W32Compat.hh>
4 #include <wx/spinctrl.h>
6 #include <wx/filename.h>
12 #include <Gui/StringConv.hh>
13 #include <Gui/ImageCanvas.hh>
14 #include <Base/Image/ImageIO.hh>
15 #include <Base/ImageUtils/ImageDraw.hh>
16 #include <Image/Camera.hh>
17 #include <Image/UnVignette.hh>
20 #define FRAME_DEFAULT_SIZE wxSize(700,580)
25 #undef WXWIN_COMPATIBILITY
27 #if !wxUSE_DRAG_AND_DROP
28 # error The dndFileTarget class requires drag and drop support in the WX library. Please recompile wxWidgets. __FILE__: __LINE__
51 ID_Load=wxID_HIGHEST+2231,
63 class MainFrame :
public wxFrame
66 friend class DragAndDropTarget;
68 MainFrame(
const wxString& title,
const wxPoint& pos,
const wxSize& size);
70 bool LoadImagesAndCalculate(
const wxArrayString &fileNames);
73 void FitSizetIfTooSmall();
78 wxArrayString ImageFileNames_;
88 wxStaticText* StaticLabel_;
89 wxTextCtrl* StepsTextCtrl_;
90 wxTextCtrl* PPXTextCtrl_;
91 wxTextCtrl* PPYTextCtrl_;
93 bool bUnVignetteParamsReady_;
97 wxString DefaultFile_;
106 std::vector<double> controlPoints_;
107 std::vector<double> VignettePercentage_;
109 int dGroundThruthWhite_;
115 int PrinciplePointX_;
116 int PrinciplePointY_;
121 void OnLoad(wxCommandEvent& event);
122 void OnExit(wxCommandEvent& event);
123 void OnAbout(wxCommandEvent& event);
125 void OnTimer(wxTimerEvent& event);
126 void OnIdle(wxIdleEvent& event);
127 void OnSize(wxSizeEvent& event);
129 void OnStepsEnter(wxCommandEvent& event);
131 void CalculateSteps(
int dImageNumber);
133 void SaveUnVignetted(wxCommandEvent& event);
134 void WriteCameraData(wxCommandEvent& event);
137 DECLARE_EVENT_TABLE()
140 BEGIN_EVENT_TABLE(MainFrame, wxFrame)
141 EVT_MENU (ID_Load, MainFrame::OnLoad)
142 EVT_MENU (ID_Exit, MainFrame::OnExit)
143 EVT_MENU (ID_About, MainFrame::OnAbout)
144 EVT_MENU (ID_WriteCameraData, MainFrame::WriteCameraData)
145 EVT_TEXT_ENTER (ID_Steps, MainFrame::OnStepsEnter)
146 EVT_TEXT_ENTER (ID_PPX, MainFrame::OnStepsEnter)
147 EVT_TEXT_ENTER (ID_PPY, MainFrame::OnStepsEnter)
149 EVT_BUTTON (ID_UnVig, MainFrame::SaveUnVignetted)
150 EVT_BUTTON (ID_WriteCameraData, MainFrame::WriteCameraData)
152 EVT_TIMER (ID_Timer, MainFrame::OnTimer)
153 EVT_IDLE (MainFrame::OnIdle)
154 EVT_SIZE (MainFrame::OnSize)
159 MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
160 : wxFrame((wxFrame*)NULL, -1, title, pos, size)
161 ,ImageCanvasUC_(NULL)
163 DefaultFile_ = wxT(
"test.pgm");
164 DefaultDir_ = wxT(
"");
165 dNumberOfSteps_ = 10;
166 PrinciplePointX_ = 0;
167 PrinciplePointY_ = 0;
168 dGroundThruthWhite_ = 0;
169 bUnVignetteParamsReady_ =
false;
170 bImageLoaded_ =
false;
172 Timer_.SetOwner(
this, ID_Timer);
175 wxMenu* fileMenu =
new wxMenu;
176 fileMenu->Append(ID_Load, wxT(
"&Open/Load...\tCtrl-O"), wxT(
"Open a file from disk for loading"));
177 fileMenu->Append(ID_WriteCameraData, wxT(
"&Write Camera Data...\tCtrl-W"), wxT(
"Save camera vignette parameters"));
178 fileMenu->AppendSeparator();
181 wxMenu* helpMenu =
new wxMenu;
182 helpMenu->Append(ID_About, wxT(
"&About...\tF1"));
185 wxMenuBar* menuBar =
new wxMenuBar;
186 menuBar->Append(fileMenu, wxT(
"&File"));
187 menuBar->Append(helpMenu, wxT(
"&Help"));
190 wxToolBar* toolBar = CreateToolBar();
191 toolBar->SetSize(1200,200);
192 StepsTextCtrl_ =
new wxTextCtrl(toolBar, ID_Steps, wxT(
"10"), wxDefaultPosition,wxDefaultSize,wxTE_PROCESS_ENTER);
193 toolBar->AddControl(
new wxStaticText(toolBar, -1, wxT(
" Nr. of Steps: ")));
194 toolBar->AddControl(StepsTextCtrl_);
196 toolBar->AddSeparator();
197 toolBar->AddControl(
new wxButton(toolBar, ID_UnVig, wxT(
"Save Unvignetted")));
198 toolBar->AddControl(
new wxButton(toolBar, ID_WriteCameraData, wxT(
"Write Cameradata")));
199 toolBar->AddSeparator();
200 PPXTextCtrl_ =
new wxTextCtrl(toolBar, ID_PPX, wxT(
"0"), wxDefaultPosition, wxDefaultSize,wxTE_PROCESS_ENTER);
201 PPYTextCtrl_ =
new wxTextCtrl(toolBar, ID_PPY, wxT(
"0"), wxDefaultPosition, wxDefaultSize,wxTE_PROCESS_ENTER);
203 toolBar->AddControl(
new wxStaticText(toolBar, -1, wxT(
" PPX: ")));
204 toolBar->AddControl(PPXTextCtrl_);
205 toolBar->AddControl(
new wxStaticText(toolBar, -1, wxT(
" PPY: ")));
206 toolBar->AddControl(PPYTextCtrl_);
212 const int numFields = 2;
213 CreateStatusBar(numFields);
214 int widths[] = { -3, -1 };
215 SetStatusWidths(numFields, widths);
216 SetStatusText(wxT(
"Welcome to Unvignette detection"), 0);
220 void MainFrame::WriteCameraData(wxCommandEvent& )
222 if(!bUnVignetteParamsReady_)
224 wxMessageDialog mDlg(
this,wxT(
"Camera unvignette parameters are not ready, compute first!"),
225 wxT(
"Not ready!"),wxOK);
229 std::ofstream OutStream;
231 wxFileDialog fileDialog(
233 wxT(
"Choose xml file to save Camera Data."),
235 wxT(
"UnVignetteParams.xml"),
237 wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
239 if (fileDialog.ShowModal() == wxID_OK)
242 fileDialog.GetPaths(paths);
244 SetStatusText(wxT(
"Writing Camera Data cancelled"));
248 DefaultDir_= fileDialog.GetDirectory();
250 OutStream.open(WxToAscii(paths.Last()),ios_base::out | ios_base::trunc);
251 OutStream << setprecision(10);
252 OutStream<<
"<VignetteCalib>\n";
253 for(
unsigned int i = 0;i<controlPoints_.size();i++)
254 OutStream<<
"<MeasPt Dist=\""<<controlPoints_[i]<<
"\" Fac=\""<<VignettePercentage_[i]<<
"\"/>"<<endl;
255 OutStream<<
"</VignetteCalib>"<<endl;
260 void MainFrame::SaveUnVignetted(wxCommandEvent& )
262 if(unVigImage_.IsEmpty())
264 wxMessageDialog mDlg(
this,wxT(
"No image loaded, load first!"),
265 wxT(
"Not ready!"),wxOK);
270 wxFileDialog fileDialog(
272 wxT(
"Choose image file to save unvignetted image."),
274 wxT(
"TestUnVignette.mip"),
276 wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
278 if (fileDialog.ShowModal() == wxID_OK)
281 fileDialog.GetPaths(paths);
283 SetStatusText(wxT(
"Writing unvignetted image cancelled"));
287 DefaultDir_= fileDialog.GetDirectory();
292 void MainFrame::OnStepsEnter(wxCommandEvent& )
294 LoadImagesAndCalculate(ImageFileNames_);
295 StepsTextCtrl_->SetFocus();
298 void MainFrame::CalculateSteps(
int dImageNumber)
300 ucImage_ = origImage_;
302 ImageWidth_ = ucImage_.GetWidth();
303 ImageHeight_ = ucImage_.GetHeight();
305 if(dImageNumber == 0){
306 controlPoints_.clear();
307 VignettePercentage_.clear();
310 double diagonal = sqrt(pow((
double)ImageWidth_,2)+pow((
double)ImageHeight_,2));
312 int step = int ( diagonal / (dNumberOfSteps_*2) );
314 int valueX=0, valueY=0;
315 double mean=0.0, mean1=0.0, mean2=0.0, mean3=0.0, mean4=0.0;
317 double alpha = atan((
double)ImageHeight_/(
double)ImageWidth_);
320 for(
int currentstep =0;currentstep <=dNumberOfSteps_;currentstep++)
323 for(
int corner=0;corner<4;corner++)
328 valueX = ImageWidth_/2 + PrinciplePointX_ - int(currentRadius * cos(alpha));
329 valueY= ImageHeight_/2 + PrinciplePointY_ - int(currentRadius * sin(alpha));
332 if(valueX<(ImageWidth_-1)&&valueY <(ImageHeight_-1)&& valueY >= 0 && valueX >= 0)
334 mean1 = CalcImageMean3x3(ucImage_,valueX,valueY);
335 if(mean1 >= 0 && dImageNumber == 0)
336 controlPoints_.push_back((
double)currentRadius/((
double)ImageWidth_/2));
337 else if(mean1 < 0.0){
345 valueX = int(currentRadius * cos(alpha) + ImageWidth_/2 + PrinciplePointX_);
346 valueY= ImageHeight_/2 + PrinciplePointY_ - int(currentRadius * sin(alpha));
347 mean2 = CalcImageMean3x3(ucImage_,valueX,valueY);
356 valueX = ImageWidth_/2 + PrinciplePointX_ - int(currentRadius * cos(alpha));
357 valueY= int(currentRadius * sin(alpha) + ImageHeight_/2 + PrinciplePointY_);
358 mean3 = CalcImageMean3x3(ucImage_,valueX,valueY);
366 valueX = int(currentRadius * cos(alpha) + ImageWidth_/2 + PrinciplePointX_);
367 valueY= int(currentRadius * sin(alpha) + ImageHeight_/2 + PrinciplePointY_);
368 mean4 = CalcImageMean3x3(ucImage_,valueX,valueY);
377 if(! (mean1>=0.0 && mean2>=0.0 && mean3>=0.0 && mean4>=0.0))
380 mean =(mean1+mean2+mean3+mean4)/4;
382 double percentage = 0.0;
384 dGroundThruthWhite_ = int(mean);
388 percentage = ((double)dGroundThruthWhite_/mean);
393 VignettePercentage_.push_back(percentage);
395 VignettePercentage_.push_back(0.0);
401 VignettePercentage_[currentstep] *= dImageNumber;
402 VignettePercentage_[currentstep] += percentage;
403 VignettePercentage_[currentstep] /=(dImageNumber+1);
409 ImageHeight_/2+ PrinciplePointY_,currentRadius);
411 currentRadius += step;
414 ImageCanvasUC_->Show(ucImage_, WxToAscii(fileName_));
415 if (ImageCanvasUC_) ImageCanvasUC_->SetFocus();
419 void MainFrame::UnVignette()
428 unVigImage_ = origImage_;
429 UnVignette_.Init(controlPoints_,VignettePercentage_,unVigImage_.GetWidth(),
430 unVigImage_.GetHeight(),PrinciplePointX_+unVigImage_.GetWidth()/2,
431 PrinciplePointY_+unVigImage_.GetHeight()/2,LEAST_SQUARES);
432 UnVignette_.Compute(unVigImage_);
434 bUnVignetteParamsReady_ =
true;
437 void MainFrame::RefitClients()
441 GetClientSize(&w, &h);
442 if (ImageCanvasUC_!=NULL)
443 ImageCanvasUC_->SetSize(0, 0, w, h);
446 bool MainFrame::LoadImagesAndCalculate(
const wxArrayString &fileNames)
448 dNumberOfSteps_ = atoi(WxToAscii(StepsTextCtrl_->GetValue()));
449 PrinciplePointX_ = atoi(WxToAscii(PPXTextCtrl_->GetValue()));
450 PrinciplePointY_ = atoi(WxToAscii(PPYTextCtrl_->GetValue()));
451 for(
unsigned int k=0;k<fileNames.Count();k++)
454 fileName_ = fileNames[k];
456 if (ImageIO::Load(WxToAscii(fileName_), origImage_)!=0)
459 msg <<
"Error loading " << fileName_;
467 if(ImageCanvasUC_ == NULL)
469 ImageCanvasUC_ =
new ImageCanvas(
this, GetStatusBar(), 1);
471 bImageLoaded_ =
true;
474 this->CalculateSteps(k);
476 this->RefitClients();
488 void MainFrame::OnLoad(wxCommandEvent& )
490 wxFileDialog fileDialog(
492 wxT(
"Choose file(s) to load"),
496 wxFD_OPEN | wxFD_MULTIPLE);
498 if (fileDialog.ShowModal() == wxID_OK)
502 fileDialog.GetPaths(ImageFileNames_);
504 LoadImagesAndCalculate(ImageFileNames_);
506 SetStatusText(wxT(
"Loading canceled"));
507 cout <<
"Canceled loading image" << endl;
510 DefaultDir_= fileDialog.GetDirectory();
520 if( (x>1) && (y>1) && (x<width-1) && (y<height-1))
522 double mean = ((double)img.
PixelValue(x-1,y-1) +
533 void MainFrame::OnExit(wxCommandEvent& ){}
534 void MainFrame::OnAbout(wxCommandEvent& )
538 msg <<
"The BIAS Vignette Detection Program\n\n"
539 <<
"http://www.mip.informatik.uni-kiel.de\n\n"
540 <<
"build on " << __DATE__ <<
" " << __TIME__ <<
"\n"
541 <<
"from file " << __FILE__ <<
"\n"
542 <<
"GUI using: " << wxVERSION_STRING <<
"\n"
543 <<
"Author : Ingo Schiller "<<
"\n"
546 wxMessageBox(
AsciiToWx(msg.str()), wxT(
"About biasdetectunvignettewx"),
547 wxOK | wxICON_INFORMATION,
this);
550 void MainFrame::OnTimer(wxTimerEvent& ){}
551 void MainFrame::OnIdle(wxIdleEvent& ){}
552 void MainFrame::OnSize(wxSizeEvent& ){ this->RefitClients();}
564 class DragAndDropTarget :
public wxFileDropTarget
567 DragAndDropTarget(MainFrame* frame);
569 virtual bool OnDropFiles(wxCoord x, wxCoord y,
const wxArrayString& filenames);
574 DragAndDropTarget::DragAndDropTarget(MainFrame* frame)
579 bool DragAndDropTarget::OnDropFiles(wxCoord , wxCoord ,
const wxArrayString& filenames)
581 BIASASSERT( Frame_ != NULL);
582 Frame_->ImageFileNames_ = filenames;
583 Frame_->LoadImagesAndCalculate(filenames);
595 class BiasDetectUnvignetteApp :
public wxApp
598 virtual bool OnInit();
601 bool BiasDetectUnvignetteApp::OnInit()
604 MainFrame* frame =
new MainFrame(wxT(
"BiasDetectUnvignetteApp"), wxPoint(50,50), FRAME_DEFAULT_SIZE );
608 DragAndDropTarget* dndTarget =
new DragAndDropTarget(frame);
609 frame->SetDropTarget(dndTarget);
619 IMPLEMENT_APP(BiasDetectUnvignetteApp)
wxString AsciiToWx(const char *thestring)
Converts a C string to a wxString.
Unvignette algorithm for images.
display image in wx application, provides zoom and investigation functionality
unsigned int GetWidth() const
StorageType PixelValue(const unsigned int x, const unsigned int y, const unsigned short int channel=0) const
Returns value of pixel at specific position, using specific channel as offset.
static int CircleCenter(Image< StorageType > &im, unsigned int CenterX, unsigned int CenterY, unsigned int Radius, const StorageType Value[]=NULL)
draws a circular line, either using Value or a good contrast value
unsigned int GetHeight() const
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
This is the base class for images in BIAS.