LensCalFrame.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00011 /* 
00012  *  This program is free software; you can redistribute it and/or
00013  *  modify it under the terms of the GNU General Public
00014  *  License as published by the Free Software Foundation; either
00015  *  version 2 of the License, or (at your option) any later version.
00016  *
00017  *  This software is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  *  General Public License for more details.
00021  *
00022  *  You should have received a copy of the GNU General Public
00023  *  License along with this software. If not, see
00024  *  <http://www.gnu.org/licenses/>.
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 #include "panodata/StandardImageVariableGroups.h"
00043 
00044 const unsigned int cps_per_line=10;
00045 
00046 #define DEFAULT_LENSCAL_SCALE 2.0
00047 #define DEFAULT_LENSCAL_THRESHOLD 4.0
00048 #define DEFAULT_RESIZE_DIMENSION 1600
00049 #define DEFAULT_MINLINELENGTH 0.3
00050 
00052 bool FileDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
00053 {
00054     DEBUG_TRACE("OnDropFiles");
00055     LensCalFrame* frame=wxGetApp().GetLensCalFrame();
00056     if (!frame) 
00057         return false;
00058 
00059     // try to add as images
00060     wxArrayString files;
00061     wxArrayString invalidFiles;
00062     for (unsigned int i=0; i< filenames.GetCount(); i++)
00063     {
00064         wxFileName file(filenames[i]);
00065         if (file.GetExt().CmpNoCase(wxT("jpg")) == 0 ||
00066             file.GetExt().CmpNoCase(wxT("jpeg")) == 0 ||
00067             file.GetExt().CmpNoCase(wxT("tif")) == 0 ||
00068             file.GetExt().CmpNoCase(wxT("tiff")) == 0 ||
00069             file.GetExt().CmpNoCase(wxT("png")) == 0 ||
00070             file.GetExt().CmpNoCase(wxT("bmp")) == 0 ||
00071             file.GetExt().CmpNoCase(wxT("gif")) == 0 ||
00072             file.GetExt().CmpNoCase(wxT("pnm")) == 0 ||
00073             file.GetExt().CmpNoCase(wxT("sun")) == 0 ||
00074             file.GetExt().CmpNoCase(wxT("hdr")) == 0 ||
00075             file.GetExt().CmpNoCase(wxT("viff")) == 0 )
00076         {
00077             if(containsInvalidCharacters(file.GetFullPath()))
00078             {
00079                 invalidFiles.push_back(file.GetFullPath());
00080             }
00081             else
00082             {
00083                 files.push_back(file.GetFullPath());
00084             };
00085         }
00086     }
00087     if(invalidFiles.size()>0)
00088     {
00089         ShowFilenameWarning(frame, invalidFiles);
00090     }
00091     // we got some images to add.
00092     if (files.size() > 0)
00093     {
00094         // use a Command to ensure proper undo and updating of GUI parts
00095         frame->AddImages(files);
00096     }
00097     return true;
00098 }
00099 
00100 // event table. this frame will recieve mostly global commands.
00101 BEGIN_EVENT_TABLE(LensCalFrame, wxFrame)
00102     EVT_LISTBOX(XRCID("lenscal_images_list"), LensCalFrame::OnImageSelected)
00103     EVT_MENU(XRCID("menu_save"), LensCalFrame::OnSaveProject)
00104     EVT_MENU(XRCID("menu_quit"), LensCalFrame::OnExit)
00105     EVT_BUTTON(XRCID("lenscal_add_image"), LensCalFrame::OnAddImage)
00106     EVT_BUTTON(XRCID("lenscal_remove_image"), LensCalFrame::OnRemoveImage)
00107     EVT_BUTTON(XRCID("lenscal_find_lines"), LensCalFrame::OnFindLines)
00108     EVT_BUTTON(XRCID("lenscal_reset"), LensCalFrame::OnReset)
00109     EVT_BUTTON(XRCID("lenscal_opt"), LensCalFrame::OnOptimize)
00110     EVT_BUTTON(XRCID("lenscal_save_lens"), LensCalFrame::OnSaveLens)
00111     EVT_BUTTON(XRCID("lenscal_refresh"), LensCalFrame::OnRefresh)
00112     EVT_CHOICE(XRCID("lenscal_preview_content"), LensCalFrame::OnSelectPreviewContent)
00113     EVT_CHECKBOX(XRCID("lenscal_show_lines"), LensCalFrame::OnShowLines)
00114 END_EVENT_TABLE()
00115 
00116 LensCalFrame::LensCalFrame(wxWindow* parent)
00117 {
00118     DEBUG_TRACE("");
00119     // load our children. some children might need special
00120     // initialization. this will be done later.
00121     wxXmlResource::Get()->LoadFrame(this, parent, wxT("lenscal_frame"));
00122     DEBUG_TRACE("");
00123 
00124     // load our menu bar
00125 #ifdef __WXMAC__
00126     wxApp::s_macExitMenuItemId = XRCID("menu_quit");
00127 #endif
00128     SetMenuBar(wxXmlResource::Get()->LoadMenuBar(this, wxT("lenscal_menubar")));
00129 
00130     m_choice_projection=XRCCTRL(*this,"lenscal_proj_choice",wxChoice);
00131     FillLensProjectionList(m_choice_projection);
00132     m_images_list=XRCCTRL(*this,"lenscal_images_list",wxListBox);
00133     m_preview=XRCCTRL(*this,"lenscal_preview",LensCalImageCtrl);
00134 
00135     wxConfigBase* config = wxConfigBase::Get();
00136     config->Read(wxT("/LensCalFrame/EdgeScale"),&m_edge_scale,DEFAULT_LENSCAL_SCALE);
00137     config->Read(wxT("/LensCalFrame/EdgeThreshold"),&m_edge_threshold,DEFAULT_LENSCAL_THRESHOLD);
00138     m_resize_dimension=config->Read(wxT("/LensCalFrame/ResizeDimension"),DEFAULT_RESIZE_DIMENSION);
00139     config->Read(wxT("/LensCalFrame/MinLineLength"),&m_minlinelength,DEFAULT_MINLINELENGTH);
00140     ParametersToDisplay();
00141 
00142     bool selected;
00143     config->Read(wxT("/LensCalFrame/Optimize_a"),&selected,false);
00144     XRCCTRL(*this,"lenscal_opt_a",wxCheckBox)->SetValue(selected);
00145     config->Read(wxT("/LensCalFrame/Optimize_b"),&selected,true);
00146     XRCCTRL(*this,"lenscal_opt_b",wxCheckBox)->SetValue(selected);
00147     config->Read(wxT("/LensCalFrame/Optimize_c"),&selected,false);
00148     XRCCTRL(*this,"lenscal_opt_c",wxCheckBox)->SetValue(selected);
00149     config->Read(wxT("/LensCalFrame/Optimize_de"),&selected,false);
00150     XRCCTRL(*this,"lenscal_opt_de",wxCheckBox)->SetValue(selected);
00151 
00152     // set the minimize icon
00153 #ifdef __WXMSW__
00154     wxIcon myIcon(GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
00155 #else
00156     wxIcon myIcon(GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
00157 #endif
00158     SetIcon(myIcon);
00159     SetTitle(_("Hugin Lens calibration GUI"));
00160 
00161     // create a new drop handler. wxwindows deletes the automatically
00162     SetDropTarget(new FileDropTarget());
00163 
00164     // create a status bar
00165     const int fields (2);
00166     CreateStatusBar(fields);
00167     int widths[fields] = {-1, 85};
00168     SetStatusWidths( fields, &widths[0]);
00169 
00170     // Set sizing characteristics
00171     //set minumum size
00172 #if defined __WXMAC__ || defined __WXMSW__
00173     // a minimum nice looking size; smaller than this would clutter the layout.
00174     SetSizeHints(900, 675);
00175 #else
00176     // For ASUS eeePc
00177     SetSizeHints(780, 455); //set minumum size
00178 #endif
00179 
00180     // set progress display for image cache.
00181     ImageCache::getInstance().setProgressDisplay(this);
00182 #if defined __WXMSW__
00183     unsigned long long mem = HUGIN_IMGCACHE_UPPERBOUND;
00184     unsigned long mem_low = config->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND);
00185     unsigned long mem_high = config->Read(wxT("/ImageCache/UpperBoundHigh"), (long) 0);
00186     if (mem_high > 0) {
00187       mem = ((unsigned long long) mem_high << 32) + mem_low;
00188     }
00189     else {
00190       mem = mem_low;
00191     }
00192     ImageCache::getInstance().SetUpperLimit(mem);
00193 #else
00194     ImageCache::getInstance().SetUpperLimit(config->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND));
00195 #endif
00196     //disable buttons
00197     EnableButtons();
00198     XRCCTRL(*this,"lenscal_remove_image",wxButton)->Enable(false);
00199 }
00200 
00201 LensCalFrame::~LensCalFrame()
00202 {
00203     DEBUG_TRACE("dtor");
00204     m_preview->SetEmptyImage();
00205     ImageCache::getInstance().setProgressDisplay(0);
00206     delete & ImageCache::getInstance();
00207     // get the global config object
00208     wxConfigBase* config = wxConfigBase::Get();
00209     if(ReadInputs(false,true,false))
00210     {
00211         config->Write(wxT("/LensCalFrame/EdgeScale"),m_edge_scale);
00212         config->Write(wxT("/LensCalFrame/EdgeThreshold"),m_edge_threshold);
00213         config->Write(wxT("/LensCalFrame/ResizeDimension"),(int)m_resize_dimension);
00214         config->Write(wxT("/LensCalFrame/MinLineLength"),m_minlinelength);
00215     };
00216     config->Write(wxT("/LensCalFrame/Optimize_a"),XRCCTRL(*this,"lenscal_opt_a",wxCheckBox)->GetValue());
00217     config->Write(wxT("/LensCalFrame/Optimize_b"),XRCCTRL(*this,"lenscal_opt_b",wxCheckBox)->GetValue());
00218     config->Write(wxT("/LensCalFrame/Optimize_c"),XRCCTRL(*this,"lenscal_opt_c",wxCheckBox)->GetValue());
00219     config->Write(wxT("/LensCalFrame/Optimize_de"),XRCCTRL(*this,"lenscal_opt_de",wxCheckBox)->GetValue());
00220     StoreFramePosition(this, wxT("LensCalFrame"));
00221     config->Flush();
00222     //cleanup
00223     for(unsigned int i=0;i<m_images.size();i++)
00224     {
00225         delete m_images[i];
00226     };
00227     m_images.clear();
00228     HuginBase::LensDB::LensDB::Clean();
00229     DEBUG_TRACE("dtor end");
00230 }
00231 
00232 void LensCalFrame::ParametersToDisplay()
00233 {
00234     XRCCTRL(*this,"lenscal_scale",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_edge_scale,2));
00235     XRCCTRL(*this, "lenscal_threshold", wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_edge_threshold, 2));
00236     XRCCTRL(*this, "lenscal_resizedim", wxTextCtrl)->SetValue(wxString::Format(wxT("%d"), m_resize_dimension));
00237     XRCCTRL(*this, "lenscal_minlinelength", wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_minlinelength, 2));
00238 };
00239 
00240 const wxString & LensCalFrame::GetXRCPath()
00241 {
00242      return wxGetApp().GetXRCPath();
00243 };
00244 
00246 void LensCalFrame::updateProgressDisplay()
00247 {
00248     wxString msg;
00249     if (!m_message.empty())
00250     {
00251         msg = wxGetTranslation(wxString(m_message.c_str(), wxConvLocal));
00252         if (!m_filename.empty())
00253         {
00254             msg.Append(wxT(" "));
00255             msg.Append(wxString(ProgressDisplay::m_filename.c_str(), HUGIN_CONV_FILENAME));
00256         };
00257     };
00258     GetStatusBar()->SetStatusText(msg, 0);
00259 
00260 #ifdef __WXMSW__
00261     UpdateWindow(NULL);
00262 #endif
00263 }
00264 
00265 void LensCalFrame::OnExit(wxCommandEvent &e)
00266 {
00267     Close();
00268 };
00269 
00270 void LensCalFrame::AddImages(wxArrayString files)
00271 {
00272     wxArrayString wrongSize;
00273     wxArrayString wrongExif;
00274     for (unsigned int i=0; i<files.GetCount(); i++)
00275     {
00276         ImageLineList* image=new ImageLineList(files[i]);
00277         //check input
00278         {
00279             // check for black/white images
00280             const HuginBase::FileMetaData metadata = image->GetPanoImage()->getFileMetadata();
00281             HuginBase::FileMetaData::const_iterator it = metadata.find("pixeltype");
00282             if (it != metadata.end())
00283             {
00284                 if (it->second == "BILEVEL")
00285                 {
00286                     wxMessageBox(wxString::Format(_("File \"%s\" is a black/white image.\nHugin does not support this image type. Skipping this image.\nConvert image to grayscale image and try loading again."), files[i].c_str()),
00287                         _("Warning"), wxOK | wxICON_EXCLAMATION, this);
00288                     delete image;
00289                     continue;
00290                 };
00291             };
00292         };
00293         if(m_images.size()>0)
00294         {
00295             const HuginBase::SrcPanoImage* image0=m_images[0]->GetPanoImage();
00296             const HuginBase::SrcPanoImage* image1=image->GetPanoImage();
00297             if(image0->getSize()!=image1->getSize())
00298             {
00299                 wrongSize.push_back(files[i]);
00300                 delete image;
00301                 continue;
00302             };
00303             if(!image0->getExifMake().empty() && !image1->getExifMake().empty() &&
00304                !image0->getExifModel().empty() && !image1->getExifModel().empty() &&
00305                image0->getExifFocalLength()>0 && image1->getExifFocalLength()>0 &&
00306                image0->getCropFactor()>0 && image1->getCropFactor()>0                 
00307               )
00308             {
00309                 if(image0->getExifMake()!=image1->getExifMake() ||
00310                     image0->getExifModel()!=image1->getExifModel() ||
00311                     image0->getExifFocalLength()!=image1->getExifFocalLength() ||
00312                     image0->getCropFactor()!=image1->getCropFactor())
00313                 {
00314                     //only show a warning, but continue processing
00315                     wrongExif.push_back(files[i]);
00316                 };
00317             };
00318         };
00319         m_images.push_back(image);
00320         SetStatusText(wxString::Format(_("Added %s"),image->GetFilename().c_str()));
00321         if (image->GetPanoImage()->getExifFocalLength() > 0)
00322         {
00323             XRCCTRL(*this, "lenscal_focallength", wxTextCtrl)->SetValue(
00324                 hugin_utils::doubleTowxString(image->GetPanoImage()->getExifFocalLength(), 2)
00325                 );
00326         };
00327         if (image->GetPanoImage()->getExifCropFactor() > 0)
00328         {
00329             XRCCTRL(*this, "lenscal_cropfactor", wxTextCtrl)->SetValue(
00330                 hugin_utils::doubleTowxString(image->GetPanoImage()->getCropFactor(), 2)
00331                 );
00332         };
00333         SelectListValue(m_choice_projection,image->GetPanoImage()->getProjection());
00334     }
00335     UpdateList(false);
00336     m_images_list->SetSelection(m_images_list->GetCount()-1);
00337     wxCommandEvent e;
00338     OnImageSelected(e);
00339     EnableButtons();
00340     if(wrongSize.size()>0)
00341     {
00342         wxString fileText;
00343         for(unsigned int i=0;i<wrongSize.size();i++)
00344         {
00345             wxFileName filename(wrongSize[i]);
00346             fileText.Append(filename.GetFullName());
00347             if(i<wrongSize.size()-1)
00348                 fileText.Append(wxT(", "));
00349         };
00350         wxMessageBox(wxString::Format(_("The size of the images (%s) does not match the already added image(s)."),fileText.c_str()),
00351             _("Error"),wxOK|wxICON_EXCLAMATION,this);
00352     };
00353     if(wrongExif.size()>0)
00354     {
00355         wxString fileText;
00356         for(unsigned int i=0;i<wrongExif.size();i++)
00357         {
00358             wxFileName filename(wrongExif[i]);
00359             fileText.Append(filename.GetFullName());
00360             if(i<wrongExif.size()-1)
00361                 fileText.Append(wxT(", "));
00362         };
00363         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()),
00364             _("Warning"),wxOK|wxICON_EXCLAMATION,this);
00365     };
00366 };
00367 
00368 void LensCalFrame::OnAddImage(wxCommandEvent &e)
00369 {
00370     wxConfigBase* config = wxConfigBase::Get();
00371     wxString path = config->Read(wxT("/actualPath"), wxT(""));
00372     wxFileDialog dlg(this,_("Add images"),
00373                      path, wxT(""),
00374                      HUGIN_WX_FILE_IMG_FILTER,
00375                      wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST | wxFD_PREVIEW, wxDefaultPosition);
00376     dlg.SetDirectory(path);
00377 
00378     // remember the image extension
00379     wxString img_ext;
00380     if (config->HasEntry(wxT("lastImageType"))){
00381       img_ext = config->Read(wxT("lastImageType")).c_str();
00382     }
00383     if (img_ext == wxT("all images"))
00384       dlg.SetFilterIndex(0);
00385     else if (img_ext == wxT("jpg"))
00386       dlg.SetFilterIndex(1);
00387     else if (img_ext == wxT("tiff"))
00388       dlg.SetFilterIndex(2);
00389     else if (img_ext == wxT("png"))
00390       dlg.SetFilterIndex(3);
00391     else if (img_ext == wxT("hdr"))
00392       dlg.SetFilterIndex(4);
00393     else if (img_ext == wxT("exr"))
00394       dlg.SetFilterIndex(5);
00395     else if (img_ext == wxT("all files"))
00396       dlg.SetFilterIndex(6);
00397     DEBUG_INFO ( "Image extention: " << img_ext.mb_str(wxConvLocal) )
00398 
00399     // call the file dialog
00400     if (dlg.ShowModal() == wxID_OK)
00401     {
00402         // get the selections
00403         wxArrayString Pathnames;
00404         dlg.GetPaths(Pathnames);
00405 
00406         // save the current path to config
00407 #ifdef __WXGTK__
00408         //workaround a bug in GTK, see https://bugzilla.redhat.com/show_bug.cgi?id=849692 and http://trac.wxwidgets.org/ticket/14525
00409         config->Write(wxT("/actualPath"), wxPathOnly(Pathnames[0]));
00410 #else
00411         config->Write(wxT("/actualPath"), dlg.GetDirectory());
00412 #endif
00413 
00414         wxArrayString invalidFiles;
00415         for(unsigned int i=0;i<Pathnames.GetCount(); i++)
00416         {
00417             if(containsInvalidCharacters(Pathnames[i]))
00418             {
00419                 invalidFiles.push_back(Pathnames[i]);
00420             };
00421         };
00422         if(invalidFiles.size()>0)
00423         {
00424             ShowFilenameWarning(this, invalidFiles);
00425         }
00426         else
00427         {
00428             AddImages(Pathnames);
00429         };
00430         DEBUG_INFO ( wxString::Format(wxT("img_ext: %d"), dlg.GetFilterIndex()).mb_str(wxConvLocal) )
00431         // save the image extension
00432         switch ( dlg.GetFilterIndex() )
00433         {
00434             case 0: config->Write(wxT("lastImageType"), wxT("all images")); break;
00435             case 1: config->Write(wxT("lastImageType"), wxT("jpg")); break;
00436             case 2: config->Write(wxT("lastImageType"), wxT("tiff")); break;
00437             case 3: config->Write(wxT("lastImageType"), wxT("png")); break;
00438             case 4: config->Write(wxT("lastImageType"), wxT("hdr")); break;
00439             case 5: config->Write(wxT("lastImageType"), wxT("exr")); break;
00440             case 6: config->Write(wxT("lastImageType"), wxT("all files")); break;
00441         }
00442     }
00443     else
00444     {
00445         // nothing to open
00446         SetStatusText( _("Add Image: cancel"));
00447     }
00448     EnableButtons();
00449 };
00450 
00451 void LensCalFrame::UpdateListString(unsigned int index)
00452 {
00453     wxFileName file(m_images[index]->GetFilename());
00454     m_images_list->SetString(index,wxString::Format(_("%s (%d lines)"),file.GetFullName().c_str(),m_images[index]->GetNrOfValidLines()));
00455 };
00456 
00457 void LensCalFrame::UpdateList(bool restoreSelection)
00458 {
00459     int oldSelection=m_images_list->GetSelection();
00460     m_images_list->Clear();
00461     for(unsigned int i=0;i<m_images.size();i++)
00462     {
00463         wxFileName file(m_images[i]->GetFilename());
00464         wxString text=wxString::Format(_("%s (%d lines)"),file.GetFullName().c_str(),m_images[i]->GetNrOfValidLines());
00465         m_images_list->Append(text);
00466     };
00467     if(oldSelection!=wxNOT_FOUND && restoreSelection)
00468     {
00469         m_images_list->SetSelection(oldSelection);
00470     };
00471     wxCommandEvent e;
00472     OnImageSelected(e);
00473 };
00474 
00475 void LensCalFrame::OnRemoveImage(wxCommandEvent &e)
00476 {
00477     int selection=m_images_list->GetSelection();
00478     if(selection!=wxNOT_FOUND)
00479     {
00480         delete m_images[selection];
00481         m_images.erase(m_images.begin()+selection);
00482         ImageCache::getInstance().softFlush();
00483         UpdateList(false);
00484     }
00485     else
00486     {
00487         wxBell();
00488     };
00489     EnableButtons();
00490 };
00491 
00492 void LensCalFrame::EnableButtons()
00493 {
00494     bool enabling=m_images.size()>0;
00495     XRCCTRL(*this,"lenscal_find_lines",wxButton)->Enable(enabling);
00496     XRCCTRL(*this,"lenscal_opt",wxButton)->Enable(enabling);
00497     XRCCTRL(*this,"lenscal_save_lens",wxButton)->Enable(enabling);
00498     GetMenuBar()->Enable(XRCID("menu_save"),enabling);
00499 };
00500 
00501 bool LensCalFrame::ReadInputs(bool readFocalLength,bool readOptions,bool readLensParameter)
00502 {
00503     if(readFocalLength)
00504     {
00505         m_projection = (HuginBase::SrcPanoImage::Projection)GetSelectedValue(m_choice_projection);
00506         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_focallength", wxTextCtrl)->GetValue(), m_focallength))
00507             return false;
00508         if(m_focallength<1)
00509             return false;
00510         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_cropfactor", wxTextCtrl)->GetValue(), m_cropfactor))
00511             return false;
00512         if(m_cropfactor<0.1)
00513             return false;
00514     }
00515     if(readOptions)
00516     {
00517         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_scale", wxTextCtrl)->GetValue(), m_edge_scale))
00518             return false;
00519         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_threshold", wxTextCtrl)->GetValue(), m_edge_threshold))
00520             return false;
00521         double resize_dim;
00522         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_resizedim", wxTextCtrl)->GetValue(), resize_dim))
00523             return false;
00524         if(resize_dim<100)
00525             return false;
00526         m_resize_dimension=(unsigned int)resize_dim;
00527         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_minlinelength", wxTextCtrl)->GetValue(), m_minlinelength))
00528             return false;
00529         if(m_minlinelength<=0 || m_minlinelength>1)
00530             return false;
00531     };
00532     if(readLensParameter)
00533     {
00534         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_a", wxTextCtrl)->GetValue(), m_a))
00535             return false;
00536         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_b", wxTextCtrl)->GetValue(), m_b))
00537             return false;
00538         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_c", wxTextCtrl)->GetValue(), m_c))
00539             return false;
00540         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_d", wxTextCtrl)->GetValue(), m_d))
00541             return false;
00542         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_e", wxTextCtrl)->GetValue(), m_e))
00543             return false;
00544     }
00545     return true;
00546 };
00547 
00548 void LensCalFrame::OnFindLines(wxCommandEvent &e)
00549 {
00550     if(!ReadInputs(true,true,false))
00551     {
00552         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00553         return;
00554     }
00555     m_preview->SetLens(m_projection,m_focallength,m_cropfactor);
00556     for(unsigned int i=0;i<m_images.size();i++)
00557     {
00558         std::string filename(m_images[i]->GetFilename().mb_str(HUGIN_CONV_FILENAME));
00559         ImageCache::EntryPtr img=ImageCache::getInstance().getImage(filename);
00560         double scale;
00561         SetStatusText(_("Detecting edges..."));
00562         m_images[i]->SetEdgeImage(HuginLines::detectEdges(*(img->get8BitImage()),m_edge_scale,m_edge_threshold,m_resize_dimension,scale));
00563         SetStatusText(_("Finding lines..."));
00564         m_images[i]->SetLines(HuginLines::findLines(*(m_images[i]->GetEdgeImage()),m_minlinelength,m_focallength,m_cropfactor));
00565         m_images[i]->ScaleLines(scale);
00566     };
00567     SetStatusText(_("Finished"));
00568     UpdateList(true);
00569 };
00570 
00571 void LensCalFrame::OnOptimize(wxCommandEvent &e)
00572 {
00573     if(!ReadInputs(true,false,true))
00574     {
00575         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00576         return;
00577     }
00578     unsigned int count=0;
00579     for(unsigned int i=0;i<m_images.size();i++)
00580         count+=m_images[i]->GetNrOfValidLines();
00581     if(count==0)
00582     {
00583         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);
00584         return;
00585     };
00586     Optimize();
00587 };
00588 
00589 HuginBase::Panorama LensCalFrame::GetPanorama()
00590 {
00591     HuginBase::Panorama pano;
00592     HuginBase::OptimizeVector optvec;
00593     unsigned int line_number=3; 
00594     for(unsigned int i=0;i<m_images.size();i++)
00595     {
00596         HuginBase::SrcPanoImage image(*(m_images[i]->GetPanoImage()));
00597         image.setProjection(m_projection);
00598         image.setExifFocalLength(m_focallength);
00599         image.setCropFactor(m_cropfactor);
00600         image.setVar("a",m_a);
00601         image.setVar("b",m_b);
00602         image.setVar("c",m_c);
00603         image.setVar("d",m_d);
00604         image.setVar("e",m_e);
00605         double hfov = HuginBase::SrcPanoImage::calcHFOV(image.getProjection(), image.getExifFocalLength(), image.getCropFactor(), image.getSize());
00606         image.setHFOV(hfov);
00607         pano.addImage(image);
00608         std::set<std::string> imgopt;
00609         if(i==0)
00610         {
00611             if(XRCCTRL(*this,"lenscal_opt_a",wxCheckBox)->GetValue())
00612                 imgopt.insert("a");
00613             if(XRCCTRL(*this,"lenscal_opt_b",wxCheckBox)->GetValue())
00614                 imgopt.insert("b");
00615             if(XRCCTRL(*this,"lenscal_opt_c",wxCheckBox)->GetValue())
00616                 imgopt.insert("c");
00617             if(XRCCTRL(*this,"lenscal_opt_de",wxCheckBox)->GetValue())
00618             {
00619                 imgopt.insert("d");
00620                 imgopt.insert("e");
00621             }
00622         };
00623         optvec.push_back(imgopt);
00624         //now generate control points from lines
00625         HuginLines::Lines lines=m_images[i]->GetLines();
00626         for(unsigned j=0;j<lines.size();j++)
00627         {
00628             if(lines[j].status==HuginLines::valid_line)
00629             {
00630                 HuginBase::CPVector cpv=GetControlPoints(lines[j],i,line_number,cps_per_line);
00631                 for(unsigned int k=0;k<cpv.size();k++)
00632                     pano.addCtrlPoint(cpv[k]);
00633                 line_number++;
00634             };
00635         };
00636     };
00637     //assign all images the same lens number
00638     HuginBase::StandardImageVariableGroups variable_groups(pano);
00639     HuginBase::ImageVariableGroup & lenses = variable_groups.getLenses();
00640     if(pano.getNrOfImages()>1)
00641     {
00642         for(unsigned int i=1;i<pano.getNrOfImages();i++)
00643         {
00644             HuginBase::SrcPanoImage img = pano.getSrcImage(i);
00645             lenses.switchParts(i,lenses.getPartNumber(0));
00646             lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_ExposureValue, i);
00647             img.setExposureValue(0);
00648             lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceRed, i);
00649             lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceBlue, i);
00650             img.setWhiteBalanceRed(1);
00651             img.setWhiteBalanceBlue(1);
00652             pano.setSrcImage(i, img);
00653         };
00654     };
00655     //set default exposure value
00656     HuginBase::PanoramaOptions opts = pano.getOptions();
00657     opts.outputExposureValue = 0;
00658     opts.setProjection(HuginBase::PanoramaOptions::RECTILINEAR);
00659     pano.setOptions(opts);
00660 
00661     pano.setOptimizeVector(optvec);
00662     return pano;
00663 };
00664 
00665 void LensCalFrame::Optimize()
00666 {
00667     SetStatusText(_("Optimizing lens distortion parameters..."));
00668     HuginBase::Panorama pano = GetPanorama();
00669     HuginBase::PTools::optimize(pano);
00670 
00671     const HuginBase::SrcPanoImage img = pano.getImage(0);
00672     m_a=img.getVar("a");
00673     m_b=img.getVar("b");
00674     m_c=img.getVar("c");
00675     m_d=img.getVar("d");
00676     m_e=img.getVar("e");
00677     XRCCTRL(*this,"lenscal_a",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_a,5));
00678     XRCCTRL(*this,"lenscal_b",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_b,5));
00679     XRCCTRL(*this,"lenscal_c",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_c,5));
00680     XRCCTRL(*this,"lenscal_d",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_d,3));
00681     XRCCTRL(*this,"lenscal_e",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_e,3));
00682     m_preview->SetLensDistortions(m_a,m_b,m_c,m_d,m_e);
00683     SetStatusText(_("Finished"));
00684 };
00685 
00686 void LensCalFrame::SaveLensToIni()
00687 {
00688     wxFileDialog dlg(this,
00689                         _("Save lens parameters file"),
00690                         wxConfigBase::Get()->Read(wxT("/lensPath"),wxT("")), wxT(""),
00691                         _("Lens Project Files (*.ini)|*.ini|All files (*)|*"),
00692                         wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
00693     dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/lensPath"),wxT("")));
00694     if (dlg.ShowModal() == wxID_OK)
00695     {
00696         wxFileName filename(dlg.GetPath());
00697         if(!filename.HasExt())
00698             filename.SetExt(wxT("ini"));
00699         wxConfig::Get()->Write(wxT("/lensPath"), dlg.GetDirectory());  // remember for later
00700         if (filename.FileExists())
00701         {
00702             int d = wxMessageBox(wxString::Format(_("File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
00703                                  _("Save project"), wxYES_NO | wxICON_QUESTION);
00704             if (d != wxYES)
00705             {
00706                 return;
00707             }
00708         }
00709         HuginBase::Panorama pano = GetPanorama();
00710         SaveLensParameters(filename.GetFullPath(),&pano,0);
00711     }
00712 };
00713 
00714 void LensCalFrame::OnSaveLens(wxCommandEvent &e)
00715 {
00716     if(!ReadInputs(true,false,true))
00717     {
00718         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00719         return;
00720     }
00721     unsigned int count=0;
00722     for(unsigned int i=0;i<m_images.size();i++)
00723         count+=m_images[i]->GetNrOfValidLines();
00724     if(count==0)
00725     {
00726         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);
00727         return;
00728     };
00729 
00730     wxArrayString choices;
00731     choices.push_back(_("Save lens parameters to ini file"));
00732     choices.push_back(_("Save lens parameters to lens database"));
00733     wxSingleChoiceDialog save_dlg(this,_("Saving lens data"),_("Save lens"),choices);
00734     if(save_dlg.ShowModal()==wxID_OK)
00735     {
00736         if(save_dlg.GetSelection()==0)
00737         {
00738             SaveLensToIni();
00739         }
00740         else
00741         {
00742             HuginBase::Panorama pano = GetPanorama();
00743             SaveLensParameters(this,pano.getImage(0),false);
00744         };
00745     };
00746 };
00747 
00748 void LensCalFrame::OnSaveProject(wxCommandEvent &e)
00749 {
00750     if(!ReadInputs(true,false,true))
00751     {
00752         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00753         return;
00754     }
00755 
00756     wxFileDialog dlg(this,_("Save project file"),wxEmptyString,wxEmptyString,
00757                      _("Project files (*.pto)|*.pto|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
00758     dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00759     if (dlg.ShowModal() == wxID_OK)
00760     {
00761         wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00762         wxFileName filename(dlg.GetPath());
00763         if(!filename.HasExt())
00764             filename.SetExt(wxT("pto"));
00765         if (filename.FileExists())
00766         {
00767             int d = wxMessageBox(wxString::Format(_("File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
00768                                  _("Save project"), wxYES_NO | wxICON_QUESTION);
00769             if (d != wxYES)
00770             {
00771                 return;
00772             }
00773         }
00774         HuginBase::Panorama pano = GetPanorama();
00775         std::string path = hugin_utils::getPathPrefix(std::string(filename.GetFullPath().mb_str(HUGIN_CONV_FILENAME)));
00776         std::ofstream script(filename.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
00777         script.exceptions ( std::ofstream::eofbit | std::ofstream::failbit | std::ofstream::badbit );
00778         HuginBase::UIntSet all;
00779         fill_set(all, 0, pano.getNrOfImages()-1);
00780         pano.printPanoramaScript(script, pano.getOptimizeVector(), pano.getOptions(), all, false, path);
00781         script.close();
00782     };
00783 };
00784 
00785 void LensCalFrame::OnImageSelected(wxCommandEvent &e)
00786 {
00787     bool selected=m_images_list->GetSelection()!=wxNOT_FOUND;
00788     XRCCTRL(*this,"lenscal_remove_image",wxButton)->Enable(selected);
00789     if(selected)
00790     {
00791         m_preview->SetImage(m_images[m_images_list->GetSelection()],m_images_list->GetSelection());
00792     }
00793     else
00794     {
00795         m_preview->SetEmptyImage();
00796     };
00797 };
00798 
00799 void LensCalFrame::OnSelectPreviewContent(wxCommandEvent &e)
00800 {
00801     m_preview->SetMode((LensCalImageCtrl::LensCalPreviewMode)e.GetSelection());
00802     XRCCTRL(*this,"lenscal_refresh",wxButton)->Enable(m_preview->GetMode()==LensCalImageCtrl::mode_corrected);
00803 };
00804 
00805 void LensCalFrame::OnShowLines(wxCommandEvent &e)
00806 {
00807     m_preview->SetShowLines(XRCCTRL(*this,"lenscal_show_lines",wxCheckBox)->GetValue());
00808     m_preview->Refresh(true);
00809 };
00810 
00811 void LensCalFrame::OnReset(wxCommandEvent &e)
00812 {
00813     m_edge_scale=DEFAULT_LENSCAL_SCALE;
00814     m_edge_threshold=DEFAULT_LENSCAL_THRESHOLD;
00815     m_resize_dimension=DEFAULT_RESIZE_DIMENSION;
00816     m_minlinelength=DEFAULT_MINLINELENGTH;
00817     ParametersToDisplay();
00818 };
00819 
00820 void LensCalFrame::OnRefresh(wxCommandEvent &e)
00821 {
00822     if(!ReadInputs(true,false,true))
00823     {
00824         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00825         return;
00826     }
00827     m_preview->SetLens(m_projection,m_focallength,m_cropfactor);
00828     m_preview->SetLensDistortions(m_a,m_b,m_c,m_d,m_e);
00829 };
00830 

Generated on 7 Dec 2016 for Hugintrunk by  doxygen 1.4.7