00001
00002
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "panoinc_WX.h"
00029 #include "panoinc.h"
00030
00031 #include "base_wx/platform.h"
00032 #include "base_wx/wxPlatform.h"
00033 #include "base_wx/LensTools.h"
00034 #include "huginapp/ImageCache.h"
00035 #include "LensCalFrame.h"
00036 #include <wx/app.h>
00037 #include "LensCalApp.h"
00038 #include "hugin/config_defaults.h"
00039 #include <algorithms/optimizer/PTOptimizer.h>
00040 #include "lensdb/LensDB.h"
00041 #include "base_wx/wxLensDB.h"
00042
00043 using namespace HuginBase;
00044
00045 const unsigned int cps_per_line=10;
00046
00047 #define DEFAULT_LENSCAL_SCALE 2.0
00048 #define DEFAULT_LENSCAL_THRESHOLD 4.0
00049 #define DEFAULT_RESIZE_DIMENSION 1600
00050 #define DEFAULT_MINLINELENGTH 0.3
00051
00052
00053 bool str2double(wxString s, double & d)
00054 {
00055 if (!hugin_utils::stringToDouble(std::string(s.mb_str(wxConvLocal)), d))
00056 {
00057 return false;
00058 }
00059 return true;
00060 }
00061
00063 bool FileDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
00064 {
00065 DEBUG_TRACE("OnDropFiles");
00066 LensCalFrame* frame=wxGetApp().GetLensCalFrame();
00067 if (!frame)
00068 return false;
00069
00070
00071 wxArrayString files;
00072 wxArrayString invalidFiles;
00073 for (unsigned int i=0; i< filenames.GetCount(); i++)
00074 {
00075 wxFileName file(filenames[i]);
00076 if (file.GetExt().CmpNoCase(wxT("jpg")) == 0 ||
00077 file.GetExt().CmpNoCase(wxT("jpeg")) == 0 ||
00078 file.GetExt().CmpNoCase(wxT("tif")) == 0 ||
00079 file.GetExt().CmpNoCase(wxT("tiff")) == 0 ||
00080 file.GetExt().CmpNoCase(wxT("png")) == 0 ||
00081 file.GetExt().CmpNoCase(wxT("bmp")) == 0 ||
00082 file.GetExt().CmpNoCase(wxT("gif")) == 0 ||
00083 file.GetExt().CmpNoCase(wxT("pnm")) == 0 ||
00084 file.GetExt().CmpNoCase(wxT("sun")) == 0 ||
00085 file.GetExt().CmpNoCase(wxT("hdr")) == 0 ||
00086 file.GetExt().CmpNoCase(wxT("viff")) == 0 )
00087 {
00088 if(containsInvalidCharacters(file.GetFullPath()))
00089 {
00090 invalidFiles.push_back(file.GetFullPath());
00091 }
00092 else
00093 {
00094 files.push_back(file.GetFullPath());
00095 };
00096 }
00097 }
00098 if(invalidFiles.size()>0)
00099 {
00100 ShowFilenameWarning(frame, invalidFiles);
00101 }
00102
00103 if (files.size() > 0)
00104 {
00105
00106 frame->AddImages(files);
00107 }
00108 return true;
00109 }
00110
00111
00112 BEGIN_EVENT_TABLE(LensCalFrame, wxFrame)
00113 EVT_LISTBOX(XRCID("lenscal_images_list"), LensCalFrame::OnImageSelected)
00114 EVT_MENU(XRCID("menu_save"), LensCalFrame::OnSaveProject)
00115 EVT_MENU(XRCID("menu_quit"), LensCalFrame::OnExit)
00116 EVT_BUTTON(XRCID("lenscal_add_image"), LensCalFrame::OnAddImage)
00117 EVT_BUTTON(XRCID("lenscal_remove_image"), LensCalFrame::OnRemoveImage)
00118 EVT_BUTTON(XRCID("lenscal_find_lines"), LensCalFrame::OnFindLines)
00119 EVT_BUTTON(XRCID("lenscal_reset"), LensCalFrame::OnReset)
00120 EVT_BUTTON(XRCID("lenscal_opt"), LensCalFrame::OnOptimize)
00121 EVT_BUTTON(XRCID("lenscal_save_lens"), LensCalFrame::OnSaveLens)
00122 EVT_BUTTON(XRCID("lenscal_refresh"), LensCalFrame::OnRefresh)
00123 EVT_CHOICE(XRCID("lenscal_preview_content"), LensCalFrame::OnSelectPreviewContent)
00124 EVT_CHECKBOX(XRCID("lenscal_show_lines"), LensCalFrame::OnShowLines)
00125 END_EVENT_TABLE()
00126
00127 LensCalFrame::LensCalFrame(wxWindow* parent)
00128 {
00129 DEBUG_TRACE("");
00130
00131
00132 wxXmlResource::Get()->LoadFrame(this, parent, wxT("lenscal_frame"));
00133 DEBUG_TRACE("");
00134
00135
00136 #ifdef __WXMAC__
00137 wxApp::s_macExitMenuItemId = XRCID("menu_quit");
00138 #endif
00139 SetMenuBar(wxXmlResource::Get()->LoadMenuBar(this, wxT("lenscal_menubar")));
00140
00141 m_choice_projection=XRCCTRL(*this,"lenscal_proj_choice",wxChoice);
00142 FillLensProjectionList(m_choice_projection);
00143 m_images_list=XRCCTRL(*this,"lenscal_images_list",wxListBox);
00144 m_preview=XRCCTRL(*this,"lenscal_preview",LensCalImageCtrl);
00145
00146 wxConfigBase* config = wxConfigBase::Get();
00147 config->Read(wxT("/LensCalFrame/EdgeScale"),&m_edge_scale,DEFAULT_LENSCAL_SCALE);
00148 config->Read(wxT("/LensCalFrame/EdgeThreshold"),&m_edge_threshold,DEFAULT_LENSCAL_THRESHOLD);
00149 m_resize_dimension=config->Read(wxT("/LensCalFrame/ResizeDimension"),DEFAULT_RESIZE_DIMENSION);
00150 config->Read(wxT("/LensCalFrame/MinLineLength"),&m_minlinelength,DEFAULT_MINLINELENGTH);
00151 ParametersToDisplay();
00152
00153 bool selected;
00154 config->Read(wxT("/LensCalFrame/Optimize_a"),&selected,false);
00155 XRCCTRL(*this,"lenscal_opt_a",wxCheckBox)->SetValue(selected);
00156 config->Read(wxT("/LensCalFrame/Optimize_b"),&selected,true);
00157 XRCCTRL(*this,"lenscal_opt_b",wxCheckBox)->SetValue(selected);
00158 config->Read(wxT("/LensCalFrame/Optimize_c"),&selected,false);
00159 XRCCTRL(*this,"lenscal_opt_c",wxCheckBox)->SetValue(selected);
00160 config->Read(wxT("/LensCalFrame/Optimize_de"),&selected,false);
00161 XRCCTRL(*this,"lenscal_opt_de",wxCheckBox)->SetValue(selected);
00162
00163
00164 #ifdef __WXMSW__
00165 wxIcon myIcon(GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
00166 #else
00167 wxIcon myIcon(GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
00168 #endif
00169 SetIcon(myIcon);
00170 SetTitle(_("Hugin Lens calibration GUI"));
00171
00172
00173 SetDropTarget(new FileDropTarget());
00174
00175
00176 const int fields (2);
00177 CreateStatusBar(fields);
00178 int widths[fields] = {-1, 85};
00179 SetStatusWidths( fields, &widths[0]);
00180
00181
00182
00183 #if defined __WXMAC__ || defined __WXMSW__
00184
00185 SetSizeHints(900, 675);
00186 #else
00187
00188 SetSizeHints(780, 455);
00189 #endif
00190
00191
00192 ImageCache::getInstance().setProgressDisplay(this);
00193 #if defined __WXMSW__
00194 unsigned long long mem = HUGIN_IMGCACHE_UPPERBOUND;
00195 unsigned long mem_low = config->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND);
00196 unsigned long mem_high = config->Read(wxT("/ImageCache/UpperBoundHigh"), (long) 0);
00197 if (mem_high > 0) {
00198 mem = ((unsigned long long) mem_high << 32) + mem_low;
00199 }
00200 else {
00201 mem = mem_low;
00202 }
00203 ImageCache::getInstance().SetUpperLimit(mem);
00204 #else
00205 ImageCache::getInstance().SetUpperLimit(config->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND));
00206 #endif
00207
00208 EnableButtons();
00209 XRCCTRL(*this,"lenscal_remove_image",wxButton)->Enable(false);
00210 }
00211
00212 LensCalFrame::~LensCalFrame()
00213 {
00214 DEBUG_TRACE("dtor");
00215 m_preview->SetEmptyImage();
00216 ImageCache::getInstance().setProgressDisplay(0);
00217 delete & ImageCache::getInstance();
00218
00219 wxConfigBase* config = wxConfigBase::Get();
00220 if(ReadInputs(false,true,false))
00221 {
00222 config->Write(wxT("/LensCalFrame/EdgeScale"),m_edge_scale);
00223 config->Write(wxT("/LensCalFrame/EdgeThreshold"),m_edge_threshold);
00224 config->Write(wxT("/LensCalFrame/ResizeDimension"),(int)m_resize_dimension);
00225 config->Write(wxT("/LensCalFrame/MinLineLength"),m_minlinelength);
00226 };
00227 config->Write(wxT("/LensCalFrame/Optimize_a"),XRCCTRL(*this,"lenscal_opt_a",wxCheckBox)->GetValue());
00228 config->Write(wxT("/LensCalFrame/Optimize_b"),XRCCTRL(*this,"lenscal_opt_b",wxCheckBox)->GetValue());
00229 config->Write(wxT("/LensCalFrame/Optimize_c"),XRCCTRL(*this,"lenscal_opt_c",wxCheckBox)->GetValue());
00230 config->Write(wxT("/LensCalFrame/Optimize_de"),XRCCTRL(*this,"lenscal_opt_de",wxCheckBox)->GetValue());
00231 StoreFramePosition(this, wxT("LensCalFrame"));
00232 config->Flush();
00233
00234 for(unsigned int i=0;i<m_images.size();i++)
00235 {
00236 delete m_images[i];
00237 };
00238 m_images.clear();
00239 LensDB::LensDB::Clean();
00240 DEBUG_TRACE("dtor end");
00241 }
00242
00243 void LensCalFrame::ParametersToDisplay()
00244 {
00245 XRCCTRL(*this,"lenscal_scale",wxTextCtrl)->SetValue(doubleTowxString(m_edge_scale,2));
00246 XRCCTRL(*this,"lenscal_threshold",wxTextCtrl)->SetValue(doubleTowxString(m_edge_threshold,2));
00247 XRCCTRL(*this,"lenscal_resizedim",wxTextCtrl)->SetValue(wxString::Format(wxT("%d"),m_resize_dimension));
00248 XRCCTRL(*this,"lenscal_minlinelength",wxTextCtrl)->SetValue(doubleTowxString(m_minlinelength,2));
00249 };
00250
00251 const wxString & LensCalFrame::GetXRCPath()
00252 {
00253 return wxGetApp().GetXRCPath();
00254 };
00255
00256 void LensCalFrame::resetProgress(double max)
00257 {
00258 m_progressMax = max;
00259 m_progress = 0;
00260 m_progressMsg = wxT("");
00261 }
00262
00263 bool LensCalFrame::increaseProgress(double delta)
00264 {
00265 m_progress += delta;
00266
00267
00268 int percentage = (int) floor(m_progress/m_progressMax*100);
00269 if (percentage > 100) percentage = 100;
00270
00271 return displayProgress();
00272 }
00273
00274 bool LensCalFrame::increaseProgress(double delta, const std::string & msg)
00275 {
00276 m_progress += delta;
00277 m_progressMsg = wxString(msg.c_str(), wxConvLocal);
00278
00279 return displayProgress();
00280 }
00281
00282
00283 void LensCalFrame::setMessage(const std::string & msg)
00284 {
00285 m_progressMsg = wxString(msg.c_str(), wxConvLocal);
00286 }
00287
00288 bool LensCalFrame::displayProgress()
00289 {
00290
00291 int percentage = (int) floor(m_progress/m_progressMax*100);
00292 if (percentage > 100) percentage = 100;
00293
00294 wxStatusBar *statbar = GetStatusBar();
00295 statbar->SetStatusText(wxString::Format(wxT("%s: %d%%"),m_progressMsg.c_str(), percentage),0);
00296 #ifdef __WXMSW__
00297 UpdateWindow(NULL);
00298 #endif
00299 return true;
00300 }
00301
00303 void LensCalFrame::updateProgressDisplay()
00304 {
00305 wxString msg;
00306
00307 for (std::vector<AppBase::ProgressTask>::reverse_iterator it = tasks.rbegin();
00308 it != tasks.rend(); ++it)
00309 {
00310 wxString cMsg;
00311 if (it->getProgress() > 0) {
00312 cMsg.Printf(wxT("%s %s [%3.0f%%]"),
00313 wxString(it->getShortMessage().c_str(), wxConvLocal).c_str(),
00314 wxString(it->getMessage().c_str(), wxConvLocal).c_str(),
00315 100 * it->getProgress());
00316 } else {
00317 cMsg.Printf(wxT("%s %s"),wxString(it->getShortMessage().c_str(), wxConvLocal).c_str(),
00318 wxString(it->getMessage().c_str(), wxConvLocal).c_str());
00319 }
00320
00321 if (it == tasks.rbegin()) {
00322 msg = cMsg;
00323 } else {
00324 msg.Append(wxT(" | "));
00325 msg.Append(cMsg);
00326 }
00327 }
00328 wxStatusBar *m_statbar = GetStatusBar();
00329 DEBUG_TRACE("Statusmb : " << msg.mb_str(wxConvLocal));
00330 m_statbar->SetStatusText(msg,0);
00331
00332 #ifdef __WXMSW__
00333 UpdateWindow(NULL);
00334 #endif
00335 }
00336
00337 void LensCalFrame::OnExit(wxCommandEvent &e)
00338 {
00339 Close();
00340 };
00341
00342 void LensCalFrame::AddImages(wxArrayString files)
00343 {
00344 wxArrayString wrongSize;
00345 wxArrayString wrongExif;
00346 for (unsigned int i=0; i<files.GetCount(); i++)
00347 {
00348 ImageLineList* image=new ImageLineList(files[i]);
00349
00350 if(m_images.size()>0)
00351 {
00352 const HuginBase::SrcPanoImage* image0=m_images[0]->GetPanoImage();
00353 const HuginBase::SrcPanoImage* image1=image->GetPanoImage();
00354 if(image0->getSize()!=image1->getSize())
00355 {
00356 wrongSize.push_back(files[i]);
00357 delete image;
00358 continue;
00359 };
00360 if(image0->hasEXIFread() && image1->hasEXIFread())
00361 {
00362 if(image0->getExifMake()!=image1->getExifMake() ||
00363 image0->getExifModel()!=image1->getExifModel() ||
00364 image0->getExifFocalLength()!=image1->getExifFocalLength() ||
00365 image0->getExifCropFactor()!=image1->getExifCropFactor())
00366 {
00367
00368 wrongExif.push_back(files[i]);
00369 };
00370 };
00371 };
00372 m_images.push_back(image);
00373 SetStatusText(wxString::Format(_("Added %s"),image->GetFilename().c_str()));
00374 if(image->GetPanoImage()->hasEXIFread())
00375 {
00376 XRCCTRL(*this,"lenscal_focallength",wxTextCtrl)->SetValue(
00377 hugin_utils::doubleTowxString(image->GetPanoImage()->getExifFocalLength(),2)
00378 );
00379 XRCCTRL(*this,"lenscal_cropfactor",wxTextCtrl)->SetValue(
00380 hugin_utils::doubleTowxString(image->GetPanoImage()->getExifCropFactor(),2)
00381 );
00382 SelectProjection(m_choice_projection,image->GetPanoImage()->getProjection());
00383 };
00384 }
00385 UpdateList(false);
00386 m_images_list->SetSelection(m_images_list->GetCount()-1);
00387 wxCommandEvent e;
00388 OnImageSelected(e);
00389 EnableButtons();
00390 if(wrongSize.size()>0)
00391 {
00392 wxString fileText;
00393 for(unsigned int i=0;i<wrongSize.size();i++)
00394 {
00395 wxFileName filename(wrongSize[i]);
00396 fileText.Append(filename.GetFullName());
00397 if(i<wrongSize.size()-1)
00398 fileText.Append(wxT(", "));
00399 };
00400 wxMessageBox(wxString::Format(_("The size of the images (%s) does not match the already added image(s)."),fileText.c_str()),
00401 _("Error"),wxOK|wxICON_EXCLAMATION,this);
00402 };
00403 if(wrongExif.size()>0)
00404 {
00405 wxString fileText;
00406 for(unsigned int i=0;i<wrongExif.size();i++)
00407 {
00408 wxFileName filename(wrongExif[i]);
00409 fileText.Append(filename.GetFullName());
00410 if(i<wrongExif.size()-1)
00411 fileText.Append(wxT(", "));
00412 };
00413 wxMessageBox(wxString::Format(_("The EXIF information of the added images (%s) is not consistent with the already added image(s).\nPlease check the image again, if you selected the correct images."),fileText.c_str()),
00414 _("Warning"),wxOK|wxICON_EXCLAMATION,this);
00415 };
00416 };
00417
00418 void LensCalFrame::OnAddImage(wxCommandEvent &e)
00419 {
00420 wxConfigBase* config = wxConfigBase::Get();
00421 wxString path = config->Read(wxT("/actualPath"), wxT(""));
00422 wxFileDialog dlg(this,_("Add images"),
00423 path, wxT(""),
00424 HUGIN_WX_FILE_IMG_FILTER,
00425 wxFD_OPEN | wxFD_MULTIPLE, wxDefaultPosition);
00426 dlg.SetDirectory(path);
00427
00428
00429 wxString img_ext;
00430 if (config->HasEntry(wxT("lastImageType"))){
00431 img_ext = config->Read(wxT("lastImageType")).c_str();
00432 }
00433 if (img_ext == wxT("all images"))
00434 dlg.SetFilterIndex(0);
00435 else if (img_ext == wxT("jpg"))
00436 dlg.SetFilterIndex(1);
00437 else if (img_ext == wxT("tiff"))
00438 dlg.SetFilterIndex(2);
00439 else if (img_ext == wxT("png"))
00440 dlg.SetFilterIndex(3);
00441 else if (img_ext == wxT("hdr"))
00442 dlg.SetFilterIndex(4);
00443 else if (img_ext == wxT("exr"))
00444 dlg.SetFilterIndex(5);
00445 else if (img_ext == wxT("all files"))
00446 dlg.SetFilterIndex(6);
00447 DEBUG_INFO ( "Image extention: " << img_ext.mb_str(wxConvLocal) )
00448
00449
00450 if (dlg.ShowModal() == wxID_OK)
00451 {
00452
00453 wxArrayString Pathnames;
00454 dlg.GetPaths(Pathnames);
00455
00456
00457 #ifdef __WXGTK__
00458
00459 config->Write(wxT("/actualPath"), wxPathOnly(Pathnames[0]));
00460 #else
00461 config->Write(wxT("/actualPath"), dlg.GetDirectory());
00462 #endif
00463
00464 wxArrayString invalidFiles;
00465 for(unsigned int i=0;i<Pathnames.GetCount(); i++)
00466 {
00467 if(containsInvalidCharacters(Pathnames[i]))
00468 {
00469 invalidFiles.push_back(Pathnames[i]);
00470 };
00471 };
00472 if(invalidFiles.size()>0)
00473 {
00474 ShowFilenameWarning(this, invalidFiles);
00475 }
00476 else
00477 {
00478 AddImages(Pathnames);
00479 };
00480 DEBUG_INFO ( wxString::Format(wxT("img_ext: %d"), dlg.GetFilterIndex()).mb_str(wxConvLocal) )
00481
00482 switch ( dlg.GetFilterIndex() )
00483 {
00484 case 0: config->Write(wxT("lastImageType"), wxT("all images")); break;
00485 case 1: config->Write(wxT("lastImageType"), wxT("jpg")); break;
00486 case 2: config->Write(wxT("lastImageType"), wxT("tiff")); break;
00487 case 3: config->Write(wxT("lastImageType"), wxT("png")); break;
00488 case 4: config->Write(wxT("lastImageType"), wxT("hdr")); break;
00489 case 5: config->Write(wxT("lastImageType"), wxT("exr")); break;
00490 case 6: config->Write(wxT("lastImageType"), wxT("all files")); break;
00491 }
00492 }
00493 else
00494 {
00495
00496 SetStatusText( _("Add Image: cancel"));
00497 }
00498 EnableButtons();
00499 };
00500
00501 void LensCalFrame::UpdateListString(unsigned int index)
00502 {
00503 wxFileName file(m_images[index]->GetFilename());
00504 m_images_list->SetString(index,wxString::Format(_("%s (%d lines)"),file.GetFullName().c_str(),m_images[index]->GetNrOfValidLines()));
00505 };
00506
00507 void LensCalFrame::UpdateList(bool restoreSelection)
00508 {
00509 int oldSelection=m_images_list->GetSelection();
00510 m_images_list->Clear();
00511 for(unsigned int i=0;i<m_images.size();i++)
00512 {
00513 wxFileName file(m_images[i]->GetFilename());
00514 wxString text=wxString::Format(_("%s (%d lines)"),file.GetFullName().c_str(),m_images[i]->GetNrOfValidLines());
00515 m_images_list->Append(text);
00516 };
00517 if(oldSelection!=wxNOT_FOUND && restoreSelection)
00518 {
00519 m_images_list->SetSelection(oldSelection);
00520 };
00521 wxCommandEvent e;
00522 OnImageSelected(e);
00523 };
00524
00525 void LensCalFrame::OnRemoveImage(wxCommandEvent &e)
00526 {
00527 int selection=m_images_list->GetSelection();
00528 if(selection!=wxNOT_FOUND)
00529 {
00530 delete m_images[selection];
00531 m_images.erase(m_images.begin()+selection);
00532 ImageCache::getInstance().softFlush();
00533 UpdateList(false);
00534 }
00535 else
00536 {
00537 wxBell();
00538 };
00539 EnableButtons();
00540 };
00541
00542 void LensCalFrame::EnableButtons()
00543 {
00544 bool enabling=m_images.size()>0;
00545 XRCCTRL(*this,"lenscal_find_lines",wxButton)->Enable(enabling);
00546 XRCCTRL(*this,"lenscal_opt",wxButton)->Enable(enabling);
00547 XRCCTRL(*this,"lenscal_save_lens",wxButton)->Enable(enabling);
00548 GetMenuBar()->Enable(XRCID("menu_save"),enabling);
00549 };
00550
00551 bool LensCalFrame::ReadInputs(bool readFocalLength,bool readOptions,bool readLensParameter)
00552 {
00553 if(readFocalLength)
00554 {
00555 m_projection=(SrcPanoImage::Projection)GetSelectedProjection(m_choice_projection);
00556 if(!str2double(XRCCTRL(*this,"lenscal_focallength",wxTextCtrl)->GetValue(),m_focallength))
00557 return false;
00558 if(m_focallength<1)
00559 return false;
00560 if(!str2double(XRCCTRL(*this,"lenscal_cropfactor",wxTextCtrl)->GetValue(),m_cropfactor))
00561 return false;
00562 if(m_cropfactor<0.1)
00563 return false;
00564 }
00565 if(readOptions)
00566 {
00567 if(!str2double(XRCCTRL(*this,"lenscal_scale",wxTextCtrl)->GetValue(),m_edge_scale))
00568 return false;
00569 if(!str2double(XRCCTRL(*this,"lenscal_threshold",wxTextCtrl)->GetValue(),m_edge_threshold))
00570 return false;
00571 double resize_dim;
00572 if(!str2double(XRCCTRL(*this,"lenscal_resizedim",wxTextCtrl)->GetValue(),resize_dim))
00573 return false;
00574 if(resize_dim<100)
00575 return false;
00576 m_resize_dimension=(unsigned int)resize_dim;
00577 if(!str2double(XRCCTRL(*this,"lenscal_minlinelength",wxTextCtrl)->GetValue(),m_minlinelength))
00578 return false;
00579 if(m_minlinelength<=0 || m_minlinelength>1)
00580 return false;
00581 };
00582 if(readLensParameter)
00583 {
00584 if(!str2double(XRCCTRL(*this,"lenscal_a",wxTextCtrl)->GetValue(),m_a))
00585 return false;
00586 if(!str2double(XRCCTRL(*this,"lenscal_b",wxTextCtrl)->GetValue(),m_b))
00587 return false;
00588 if(!str2double(XRCCTRL(*this,"lenscal_c",wxTextCtrl)->GetValue(),m_c))
00589 return false;
00590 if(!str2double(XRCCTRL(*this,"lenscal_d",wxTextCtrl)->GetValue(),m_d))
00591 return false;
00592 if(!str2double(XRCCTRL(*this,"lenscal_e",wxTextCtrl)->GetValue(),m_e))
00593 return false;
00594 }
00595 return true;
00596 };
00597
00598 void LensCalFrame::OnFindLines(wxCommandEvent &e)
00599 {
00600 if(!ReadInputs(true,true,false))
00601 {
00602 wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00603 return;
00604 }
00605 m_preview->SetLens(m_projection,m_focallength,m_cropfactor);
00606 for(unsigned int i=0;i<m_images.size();i++)
00607 {
00608 std::string filename(m_images[i]->GetFilename().mb_str(HUGIN_CONV_FILENAME));
00609 ImageCache::EntryPtr img=ImageCache::getInstance().getImage(filename);
00610 double scale;
00611 SetStatusText(_("Detecting edges..."));
00612 m_images[i]->SetEdgeImage(HuginLines::detectEdges(*(img->get8BitImage()),m_edge_scale,m_edge_threshold,m_resize_dimension,scale));
00613 SetStatusText(_("Finding lines..."));
00614 m_images[i]->SetLines(HuginLines::findLines(*(m_images[i]->GetEdgeImage()),m_minlinelength,m_focallength,m_cropfactor));
00615 m_images[i]->ScaleLines(scale);
00616 };
00617 SetStatusText(_("Finished"));
00618 UpdateList(true);
00619 };
00620
00621 void LensCalFrame::OnOptimize(wxCommandEvent &e)
00622 {
00623 if(!ReadInputs(true,false,true))
00624 {
00625 wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00626 return;
00627 }
00628 unsigned int count=0;
00629 for(unsigned int i=0;i<m_images.size();i++)
00630 count+=m_images[i]->GetNrOfValidLines();
00631 if(count==0)
00632 {
00633 wxMessageBox(_("There are no detected lines.\nPlease run \"Find lines\" first. If there are no lines found, change the parameters."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00634 return;
00635 };
00636 Optimize();
00637 };
00638
00639 Panorama LensCalFrame::GetPanorama()
00640 {
00641 HuginBase::Panorama pano;
00642 OptimizeVector optvec;
00643 unsigned int line_number=3;
00644 for(unsigned int i=0;i<m_images.size();i++)
00645 {
00646 SrcPanoImage image(*(m_images[i]->GetPanoImage()));
00647 image.setProjection(m_projection);
00648 image.setExifFocalLength(m_focallength);
00649 image.setExifCropFactor(m_cropfactor);
00650 image.setVar("a",m_a);
00651 image.setVar("b",m_b);
00652 image.setVar("c",m_c);
00653 image.setVar("d",m_d);
00654 image.setVar("e",m_e);
00655 double hfov=SrcPanoImage::calcHFOV(image.getProjection(),image.getExifFocalLength(),image.getExifCropFactor(),image.getSize());
00656 image.setHFOV(hfov);
00657 pano.addImage(image);
00658 std::set<std::string> imgopt;
00659 if(i==0)
00660 {
00661 if(XRCCTRL(*this,"lenscal_opt_a",wxCheckBox)->GetValue())
00662 imgopt.insert("a");
00663 if(XRCCTRL(*this,"lenscal_opt_b",wxCheckBox)->GetValue())
00664 imgopt.insert("b");
00665 if(XRCCTRL(*this,"lenscal_opt_c",wxCheckBox)->GetValue())
00666 imgopt.insert("c");
00667 if(XRCCTRL(*this,"lenscal_opt_de",wxCheckBox)->GetValue())
00668 {
00669 imgopt.insert("d");
00670 imgopt.insert("e");
00671 }
00672 };
00673 optvec.push_back(imgopt);
00674
00675 HuginLines::Lines lines=m_images[i]->GetLines();
00676 for(unsigned j=0;j<lines.size();j++)
00677 {
00678 if(lines[j].status==HuginLines::valid_line)
00679 {
00680 HuginBase::CPVector cpv=GetControlPoints(lines[j],i,line_number,cps_per_line);
00681 for(unsigned int k=0;k<cpv.size();k++)
00682 pano.addCtrlPoint(cpv[k]);
00683 line_number++;
00684 };
00685 };
00686 };
00687
00688 StandardImageVariableGroups variable_groups(pano);
00689 ImageVariableGroup & lenses = variable_groups.getLenses();
00690 if(pano.getNrOfImages()>1)
00691 {
00692 for(unsigned int i=1;i<pano.getNrOfImages();i++)
00693 {
00694 SrcPanoImage img=pano.getSrcImage(i);
00695 lenses.switchParts(i,lenses.getPartNumber(0));
00696 lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_ExposureValue, i);
00697 img.setExposureValue(0);
00698 lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceRed, i);
00699 lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceBlue, i);
00700 img.setWhiteBalanceRed(1);
00701 img.setWhiteBalanceBlue(1);
00702 pano.setSrcImage(i, img);
00703 };
00704 };
00705
00706 PanoramaOptions opts = pano.getOptions();
00707 opts.outputExposureValue = 0;
00708 opts.setProjection(HuginBase::PanoramaOptions::RECTILINEAR);
00709 pano.setOptions(opts);
00710
00711 pano.setOptimizeVector(optvec);
00712 return pano;
00713 };
00714
00715 void LensCalFrame::Optimize()
00716 {
00717 SetStatusText(_("Optimizing lens distortion parameters..."));
00718 Panorama pano=GetPanorama();
00719 HuginBase::PTools::optimize(pano);
00720
00721 const SrcPanoImage img=pano.getImage(0);
00722 m_a=img.getVar("a");
00723 m_b=img.getVar("b");
00724 m_c=img.getVar("c");
00725 m_d=img.getVar("d");
00726 m_e=img.getVar("e");
00727 XRCCTRL(*this,"lenscal_a",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_a,5));
00728 XRCCTRL(*this,"lenscal_b",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_b,5));
00729 XRCCTRL(*this,"lenscal_c",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_c,5));
00730 XRCCTRL(*this,"lenscal_d",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_d,3));
00731 XRCCTRL(*this,"lenscal_e",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_e,3));
00732 m_preview->SetLensDistortions(m_a,m_b,m_c,m_d,m_e);
00733 SetStatusText(_("Finished"));
00734 };
00735
00736 void LensCalFrame::SaveLensToIni()
00737 {
00738 wxFileDialog dlg(this,
00739 _("Save lens parameters file"),
00740 wxConfigBase::Get()->Read(wxT("/lensPath"),wxT("")), wxT(""),
00741 _("Lens Project Files (*.ini)|*.ini|All files (*)|*"),
00742 wxFD_SAVE, wxDefaultPosition);
00743 dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/lensPath"),wxT("")));
00744 if (dlg.ShowModal() == wxID_OK)
00745 {
00746 wxFileName filename(dlg.GetPath());
00747 if(!filename.HasExt())
00748 filename.SetExt(wxT("ini"));
00749 wxConfig::Get()->Write(wxT("/lensPath"), dlg.GetDirectory());
00750 if (filename.FileExists())
00751 {
00752 int d = wxMessageBox(wxString::Format(_("File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
00753 _("Save project"), wxYES_NO | wxICON_QUESTION);
00754 if (d != wxYES)
00755 {
00756 return;
00757 }
00758 }
00759 Panorama pano=GetPanorama();
00760 SaveLensParameters(filename.GetFullPath(),&pano,0);
00761 }
00762 };
00763
00764 void LensCalFrame::OnSaveLens(wxCommandEvent &e)
00765 {
00766 if(!ReadInputs(true,false,true))
00767 {
00768 wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00769 return;
00770 }
00771 unsigned int count=0;
00772 for(unsigned int i=0;i<m_images.size();i++)
00773 count+=m_images[i]->GetNrOfValidLines();
00774 if(count==0)
00775 {
00776 wxMessageBox(_("There are no detected lines.\nPlease run \"Find lines\" and \"Optimize\" before saving the lens data. If there are no lines found, change the parameters."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00777 return;
00778 };
00779
00780 wxArrayString choices;
00781 choices.push_back(_("Save lens parameters to ini file"));
00782 choices.push_back(_("Save lens parameters to lensfun database"));
00783 wxSingleChoiceDialog save_dlg(this,_("Saving lens data"),_("Save lens"),choices);
00784 if(save_dlg.ShowModal()==wxID_OK)
00785 {
00786 if(save_dlg.GetSelection()==0)
00787 {
00788 SaveLensToIni();
00789 }
00790 else
00791 {
00792 Panorama pano=GetPanorama();
00793 SaveLensParameters(this,pano.getImage(0),false);
00794 };
00795 };
00796 };
00797
00798 void LensCalFrame::OnSaveProject(wxCommandEvent &e)
00799 {
00800 if(!ReadInputs(true,false,true))
00801 {
00802 wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00803 return;
00804 }
00805
00806 wxFileDialog dlg(this,_("Save project file"),wxEmptyString,wxEmptyString,
00807 _("Project files (*.pto)|*.pto|All files (*)|*"), wxFD_SAVE, wxDefaultPosition);
00808 dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00809 if (dlg.ShowModal() == wxID_OK)
00810 {
00811 wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());
00812 wxFileName filename(dlg.GetPath());
00813 if(!filename.HasExt())
00814 filename.SetExt(wxT("pto"));
00815 if (filename.FileExists())
00816 {
00817 int d = wxMessageBox(wxString::Format(_("File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
00818 _("Save project"), wxYES_NO | wxICON_QUESTION);
00819 if (d != wxYES)
00820 {
00821 return;
00822 }
00823 }
00824 Panorama pano=GetPanorama();
00825 std::string path = getPathPrefix(std::string(filename.GetFullPath().mb_str(HUGIN_CONV_FILENAME)));
00826 std::ofstream script(filename.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
00827 script.exceptions ( std::ofstream::eofbit | std::ofstream::failbit | std::ofstream::badbit );
00828 PT::UIntSet all;
00829 fill_set(all, 0, pano.getNrOfImages()-1);
00830 pano.printPanoramaScript(script, pano.getOptimizeVector(), pano.getOptions(), all, false, path);
00831 script.close();
00832 };
00833 };
00834
00835 void LensCalFrame::OnImageSelected(wxCommandEvent &e)
00836 {
00837 bool selected=m_images_list->GetSelection()!=wxNOT_FOUND;
00838 XRCCTRL(*this,"lenscal_remove_image",wxButton)->Enable(selected);
00839 if(selected)
00840 {
00841 m_preview->SetImage(m_images[m_images_list->GetSelection()],m_images_list->GetSelection());
00842 }
00843 else
00844 {
00845 m_preview->SetEmptyImage();
00846 };
00847 };
00848
00849 void LensCalFrame::OnSelectPreviewContent(wxCommandEvent &e)
00850 {
00851 m_preview->SetMode((LensCalImageCtrl::LensCalPreviewMode)e.GetSelection());
00852 XRCCTRL(*this,"lenscal_refresh",wxButton)->Enable(m_preview->GetMode()==LensCalImageCtrl::mode_corrected);
00853 };
00854
00855 void LensCalFrame::OnShowLines(wxCommandEvent &e)
00856 {
00857 m_preview->SetShowLines(XRCCTRL(*this,"lenscal_show_lines",wxCheckBox)->GetValue());
00858 m_preview->Refresh(true);
00859 };
00860
00861 void LensCalFrame::OnReset(wxCommandEvent &e)
00862 {
00863 m_edge_scale=DEFAULT_LENSCAL_SCALE;
00864 m_edge_threshold=DEFAULT_LENSCAL_THRESHOLD;
00865 m_resize_dimension=DEFAULT_RESIZE_DIMENSION;
00866 m_minlinelength=DEFAULT_MINLINELENGTH;
00867 ParametersToDisplay();
00868 };
00869
00870 void LensCalFrame::OnRefresh(wxCommandEvent &e)
00871 {
00872 if(!ReadInputs(true,false,true))
00873 {
00874 wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00875 return;
00876 }
00877 m_preview->SetLens(m_projection,m_focallength,m_cropfactor);
00878 m_preview->SetLensDistortions(m_a,m_b,m_c,m_d,m_e);
00879 };
00880