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

Generated on 1 Sep 2015 for Hugintrunk by  doxygen 1.4.7