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 "base_wx/GraphTools.h"
00035 #include "huginapp/ImageCache.h"
00036 #include "LensCalFrame.h"
00037 #include <wx/app.h>
00038 #include "LensCalApp.h"
00039 #include "hugin/config_defaults.h"
00040 #include <algorithms/optimizer/PTOptimizer.h>
00041 #include "lensdb/LensDB.h"
00042 #include "base_wx/wxLensDB.h"
00043 #include "panodata/StandardImageVariableGroups.h"
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 
00053 bool FileDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
00054 {
00055     DEBUG_TRACE("OnDropFiles");
00056     LensCalFrame* frame=wxGetApp().GetLensCalFrame();
00057     if (!frame) 
00058         return false;
00059 
00060     // try to add as images
00061     wxArrayString files;
00062     wxArrayString invalidFiles;
00063     for (unsigned int i=0; i< filenames.GetCount(); i++)
00064     {
00065         wxFileName file(filenames[i]);
00066         if (file.GetExt().CmpNoCase(wxT("jpg")) == 0 ||
00067             file.GetExt().CmpNoCase(wxT("jpeg")) == 0 ||
00068             file.GetExt().CmpNoCase(wxT("tif")) == 0 ||
00069             file.GetExt().CmpNoCase(wxT("tiff")) == 0 ||
00070             file.GetExt().CmpNoCase(wxT("png")) == 0 ||
00071             file.GetExt().CmpNoCase(wxT("bmp")) == 0 ||
00072             file.GetExt().CmpNoCase(wxT("gif")) == 0 ||
00073             file.GetExt().CmpNoCase(wxT("pnm")) == 0 ||
00074             file.GetExt().CmpNoCase(wxT("sun")) == 0 ||
00075             file.GetExt().CmpNoCase(wxT("hdr")) == 0 ||
00076             file.GetExt().CmpNoCase(wxT("viff")) == 0 )
00077         {
00078             if(containsInvalidCharacters(file.GetFullPath()))
00079             {
00080                 invalidFiles.push_back(file.GetFullPath());
00081             }
00082             else
00083             {
00084                 files.push_back(file.GetFullPath());
00085             };
00086         }
00087     }
00088     if(invalidFiles.size()>0)
00089     {
00090         ShowFilenameWarning(frame, invalidFiles);
00091     }
00092     // we got some images to add.
00093     if (files.size() > 0)
00094     {
00095         // use a Command to ensure proper undo and updating of GUI parts
00096         frame->AddImages(files);
00097     }
00098     return true;
00099 }
00100 
00101 // event table. this frame will recieve mostly global commands.
00102 BEGIN_EVENT_TABLE(LensCalFrame, wxFrame)
00103     EVT_LISTBOX(XRCID("lenscal_images_list"), LensCalFrame::OnImageSelected)
00104     EVT_MENU(XRCID("menu_save"), LensCalFrame::OnSaveProject)
00105     EVT_MENU(XRCID("menu_quit"), LensCalFrame::OnExit)
00106     EVT_BUTTON(XRCID("lenscal_add_image"), LensCalFrame::OnAddImage)
00107     EVT_BUTTON(XRCID("lenscal_remove_image"), LensCalFrame::OnRemoveImage)
00108     EVT_BUTTON(XRCID("lenscal_find_lines"), LensCalFrame::OnFindLines)
00109     EVT_BUTTON(XRCID("lenscal_reset"), LensCalFrame::OnReset)
00110     EVT_BUTTON(XRCID("lenscal_opt"), LensCalFrame::OnOptimize)
00111     EVT_BUTTON(XRCID("lenscal_show_distortion_graph"), LensCalFrame::OnShowDistortionGraph)
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     HuginBase::LensDB::LensDB::Clean();
00231     DEBUG_TRACE("dtor end");
00232 }
00233 
00234 void LensCalFrame::ParametersToDisplay()
00235 {
00236     XRCCTRL(*this,"lenscal_scale",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_edge_scale,2));
00237     XRCCTRL(*this, "lenscal_threshold", wxTextCtrl)->SetValue(hugin_utils::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(hugin_utils::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     const bool enabling = !m_images.empty();
00497     XRCCTRL(*this,"lenscal_find_lines",wxButton)->Enable(enabling);
00498     XRCCTRL(*this,"lenscal_opt",wxButton)->Enable(enabling);
00499     XRCCTRL(*this, "lenscal_show_distortion_graph", wxButton)->Enable(enabling);
00500     XRCCTRL(*this,"lenscal_save_lens",wxButton)->Enable(enabling);
00501     GetMenuBar()->Enable(XRCID("menu_save"),enabling);
00502 };
00503 
00504 bool LensCalFrame::ReadInputs(bool readFocalLength,bool readOptions,bool readLensParameter)
00505 {
00506     if(readFocalLength)
00507     {
00508         m_projection = (HuginBase::SrcPanoImage::Projection)GetSelectedValue(m_choice_projection);
00509         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_focallength", wxTextCtrl)->GetValue(), m_focallength))
00510             return false;
00511         if(m_focallength<1)
00512             return false;
00513         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_cropfactor", wxTextCtrl)->GetValue(), m_cropfactor))
00514             return false;
00515         if(m_cropfactor<0.1)
00516             return false;
00517     }
00518     if(readOptions)
00519     {
00520         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_scale", wxTextCtrl)->GetValue(), m_edge_scale))
00521             return false;
00522         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_threshold", wxTextCtrl)->GetValue(), m_edge_threshold))
00523             return false;
00524         double resize_dim;
00525         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_resizedim", wxTextCtrl)->GetValue(), resize_dim))
00526             return false;
00527         if(resize_dim<100)
00528             return false;
00529         m_resize_dimension=(unsigned int)resize_dim;
00530         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_minlinelength", wxTextCtrl)->GetValue(), m_minlinelength))
00531             return false;
00532         if(m_minlinelength<=0 || m_minlinelength>1)
00533             return false;
00534     };
00535     if(readLensParameter)
00536     {
00537         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_a", wxTextCtrl)->GetValue(), m_a))
00538             return false;
00539         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_b", wxTextCtrl)->GetValue(), m_b))
00540             return false;
00541         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_c", wxTextCtrl)->GetValue(), m_c))
00542             return false;
00543         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_d", wxTextCtrl)->GetValue(), m_d))
00544             return false;
00545         if (!hugin_utils::str2double(XRCCTRL(*this, "lenscal_e", wxTextCtrl)->GetValue(), m_e))
00546             return false;
00547     }
00548     return true;
00549 };
00550 
00551 void LensCalFrame::OnFindLines(wxCommandEvent &e)
00552 {
00553     if(!ReadInputs(true,true,false))
00554     {
00555         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00556         return;
00557     }
00558     m_preview->SetLens(m_projection,m_focallength,m_cropfactor);
00559     for(unsigned int i=0;i<m_images.size();i++)
00560     {
00561         std::string filename(m_images[i]->GetFilename().mb_str(HUGIN_CONV_FILENAME));
00562         ImageCache::EntryPtr img=ImageCache::getInstance().getImage(filename);
00563         double scale;
00564         SetStatusText(_("Detecting edges..."));
00565         m_images[i]->SetEdgeImage(HuginLines::detectEdges(*(img->get8BitImage()),m_edge_scale,m_edge_threshold,m_resize_dimension,scale));
00566         SetStatusText(_("Finding lines..."));
00567         m_images[i]->SetLines(HuginLines::findLines(*(m_images[i]->GetEdgeImage()),m_minlinelength,m_focallength,m_cropfactor));
00568         m_images[i]->ScaleLines(scale);
00569     };
00570     SetStatusText(_("Finished"));
00571     UpdateList(true);
00572 };
00573 
00574 void LensCalFrame::OnOptimize(wxCommandEvent &e)
00575 {
00576     if(!ReadInputs(true,false,true))
00577     {
00578         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00579         return;
00580     }
00581     unsigned int count=0;
00582     for(unsigned int i=0;i<m_images.size();i++)
00583         count+=m_images[i]->GetNrOfValidLines();
00584     if(count==0)
00585     {
00586         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);
00587         return;
00588     };
00589     Optimize();
00590 };
00591 
00592 void LensCalFrame::OnShowDistortionGraph(wxCommandEvent &e)
00593 {
00594     if (m_images.empty())
00595     {
00596         return;
00597     };
00598     if (!ReadInputs(true, false, true))
00599     {
00600         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."), _("Warning"), wxOK | wxICON_INFORMATION, this);
00601         return;
00602     };
00603     delete m_popup;
00604     HuginBase::SrcPanoImage image(*(m_images[0]->GetPanoImage()));
00605     image.setProjection(m_projection);
00606     image.setExifFocalLength(m_focallength);
00607     image.setCropFactor(m_cropfactor);
00608     image.setVar("a", m_a);
00609     image.setVar("b", m_b);
00610     image.setVar("c", m_c);
00611     image.setVar("d", m_d);
00612     image.setVar("e", m_e);
00613     image.setHFOV(HuginBase::SrcPanoImage::calcHFOV(image.getProjection(), image.getExifFocalLength(), image.getCropFactor(), image.getSize()));
00614 
00615     m_popup=new wxGraphTools::GraphPopupWindow(this, wxGraphTools::GetDistortionGraph(image));
00616     wxWindow *button = (wxWindow*)e.GetEventObject();
00617     wxPoint pos = button->ClientToScreen(wxPoint(0, 0));
00618     m_popup->Position(pos, button->GetSize());
00619     m_popup->Popup();
00620 };
00621 
00622 HuginBase::Panorama LensCalFrame::GetPanorama()
00623 {
00624     HuginBase::Panorama pano;
00625     HuginBase::OptimizeVector optvec;
00626     unsigned int line_number=3; 
00627     for(unsigned int i=0;i<m_images.size();i++)
00628     {
00629         HuginBase::SrcPanoImage image(*(m_images[i]->GetPanoImage()));
00630         image.setProjection(m_projection);
00631         image.setExifFocalLength(m_focallength);
00632         image.setCropFactor(m_cropfactor);
00633         image.setVar("a",m_a);
00634         image.setVar("b",m_b);
00635         image.setVar("c",m_c);
00636         image.setVar("d",m_d);
00637         image.setVar("e",m_e);
00638         double hfov = HuginBase::SrcPanoImage::calcHFOV(image.getProjection(), image.getExifFocalLength(), image.getCropFactor(), image.getSize());
00639         image.setHFOV(hfov);
00640         pano.addImage(image);
00641         std::set<std::string> imgopt;
00642         if(i==0)
00643         {
00644             if(XRCCTRL(*this,"lenscal_opt_a",wxCheckBox)->GetValue())
00645                 imgopt.insert("a");
00646             if(XRCCTRL(*this,"lenscal_opt_b",wxCheckBox)->GetValue())
00647                 imgopt.insert("b");
00648             if(XRCCTRL(*this,"lenscal_opt_c",wxCheckBox)->GetValue())
00649                 imgopt.insert("c");
00650             if(XRCCTRL(*this,"lenscal_opt_de",wxCheckBox)->GetValue())
00651             {
00652                 imgopt.insert("d");
00653                 imgopt.insert("e");
00654             }
00655         };
00656         optvec.push_back(imgopt);
00657         //now generate control points from lines
00658         HuginLines::Lines lines=m_images[i]->GetLines();
00659         for(unsigned j=0;j<lines.size();j++)
00660         {
00661             if(lines[j].status==HuginLines::valid_line)
00662             {
00663                 HuginBase::CPVector cpv=GetControlPoints(lines[j],i,line_number,cps_per_line);
00664                 for(unsigned int k=0;k<cpv.size();k++)
00665                     pano.addCtrlPoint(cpv[k]);
00666                 line_number++;
00667             };
00668         };
00669     };
00670     //assign all images the same lens number
00671     HuginBase::StandardImageVariableGroups variable_groups(pano);
00672     HuginBase::ImageVariableGroup & lenses = variable_groups.getLenses();
00673     if(pano.getNrOfImages()>1)
00674     {
00675         for(unsigned int i=1;i<pano.getNrOfImages();i++)
00676         {
00677             HuginBase::SrcPanoImage img = pano.getSrcImage(i);
00678             lenses.switchParts(i,lenses.getPartNumber(0));
00679             lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_ExposureValue, i);
00680             img.setExposureValue(0);
00681             lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceRed, i);
00682             lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceBlue, i);
00683             img.setWhiteBalanceRed(1);
00684             img.setWhiteBalanceBlue(1);
00685             pano.setSrcImage(i, img);
00686         };
00687     };
00688     //set default exposure value
00689     HuginBase::PanoramaOptions opts = pano.getOptions();
00690     opts.outputExposureValue = 0;
00691     opts.setProjection(HuginBase::PanoramaOptions::RECTILINEAR);
00692     pano.setOptions(opts);
00693 
00694     pano.setOptimizeVector(optvec);
00695     return pano;
00696 };
00697 
00698 void LensCalFrame::Optimize()
00699 {
00700     SetStatusText(_("Optimizing lens distortion parameters..."));
00701     HuginBase::Panorama pano = GetPanorama();
00702     HuginBase::PTools::optimize(pano);
00703 
00704     const HuginBase::SrcPanoImage img = pano.getImage(0);
00705     m_a=img.getVar("a");
00706     m_b=img.getVar("b");
00707     m_c=img.getVar("c");
00708     m_d=img.getVar("d");
00709     m_e=img.getVar("e");
00710     XRCCTRL(*this,"lenscal_a",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_a,5));
00711     XRCCTRL(*this,"lenscal_b",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_b,5));
00712     XRCCTRL(*this,"lenscal_c",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_c,5));
00713     XRCCTRL(*this,"lenscal_d",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_d,3));
00714     XRCCTRL(*this,"lenscal_e",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_e,3));
00715     m_preview->SetLensDistortions(m_a,m_b,m_c,m_d,m_e);
00716     SetStatusText(_("Finished"));
00717 };
00718 
00719 void LensCalFrame::SaveLensToIni()
00720 {
00721     wxFileDialog dlg(this,
00722                         _("Save lens parameters file"),
00723                         wxConfigBase::Get()->Read(wxT("/lensPath"),wxT("")), wxT(""),
00724                         _("Lens Project Files (*.ini)|*.ini|All files (*)|*"),
00725                         wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
00726     dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/lensPath"),wxT("")));
00727     if (dlg.ShowModal() == wxID_OK)
00728     {
00729         wxFileName filename(dlg.GetPath());
00730         if(!filename.HasExt())
00731             filename.SetExt(wxT("ini"));
00732         wxConfig::Get()->Write(wxT("/lensPath"), dlg.GetDirectory());  // remember for later
00733         if (filename.FileExists())
00734         {
00735             int d = wxMessageBox(wxString::Format(_("File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
00736                                  _("Save project"), wxYES_NO | wxICON_QUESTION);
00737             if (d != wxYES)
00738             {
00739                 return;
00740             }
00741         }
00742         HuginBase::Panorama pano = GetPanorama();
00743         SaveLensParameters(filename.GetFullPath(),&pano,0);
00744     }
00745 };
00746 
00747 void LensCalFrame::OnSaveLens(wxCommandEvent &e)
00748 {
00749     if(!ReadInputs(true,false,true))
00750     {
00751         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00752         return;
00753     }
00754     unsigned int count=0;
00755     for(unsigned int i=0;i<m_images.size();i++)
00756         count+=m_images[i]->GetNrOfValidLines();
00757     if(count==0)
00758     {
00759         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);
00760         return;
00761     };
00762 
00763     wxArrayString choices;
00764     choices.push_back(_("Save lens parameters to ini file"));
00765     choices.push_back(_("Save lens parameters to lens database"));
00766     wxSingleChoiceDialog save_dlg(this,_("Saving lens data"),_("Save lens"),choices);
00767     if(save_dlg.ShowModal()==wxID_OK)
00768     {
00769         if(save_dlg.GetSelection()==0)
00770         {
00771             SaveLensToIni();
00772         }
00773         else
00774         {
00775             HuginBase::Panorama pano = GetPanorama();
00776             SaveLensParameters(this,pano.getImage(0),false);
00777         };
00778     };
00779 };
00780 
00781 void LensCalFrame::OnSaveProject(wxCommandEvent &e)
00782 {
00783     if(!ReadInputs(true,false,true))
00784     {
00785         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00786         return;
00787     }
00788 
00789     wxFileDialog dlg(this,_("Save project file"),wxEmptyString,wxEmptyString,
00790                      _("Project files (*.pto)|*.pto|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
00791     dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00792     if (dlg.ShowModal() == wxID_OK)
00793     {
00794         wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00795         wxFileName filename(dlg.GetPath());
00796         if(!filename.HasExt())
00797             filename.SetExt(wxT("pto"));
00798         if (filename.FileExists())
00799         {
00800             int d = wxMessageBox(wxString::Format(_("File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
00801                                  _("Save project"), wxYES_NO | wxICON_QUESTION);
00802             if (d != wxYES)
00803             {
00804                 return;
00805             }
00806         }
00807         HuginBase::Panorama pano = GetPanorama();
00808         std::string path = hugin_utils::getPathPrefix(std::string(filename.GetFullPath().mb_str(HUGIN_CONV_FILENAME)));
00809         std::ofstream script(filename.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
00810         script.exceptions ( std::ofstream::eofbit | std::ofstream::failbit | std::ofstream::badbit );
00811         HuginBase::UIntSet all;
00812         fill_set(all, 0, pano.getNrOfImages()-1);
00813         pano.printPanoramaScript(script, pano.getOptimizeVector(), pano.getOptions(), all, false, path);
00814         script.close();
00815     };
00816 };
00817 
00818 void LensCalFrame::OnImageSelected(wxCommandEvent &e)
00819 {
00820     bool selected=m_images_list->GetSelection()!=wxNOT_FOUND;
00821     XRCCTRL(*this,"lenscal_remove_image",wxButton)->Enable(selected);
00822     if(selected)
00823     {
00824         m_preview->SetImage(m_images[m_images_list->GetSelection()],m_images_list->GetSelection());
00825     }
00826     else
00827     {
00828         m_preview->SetEmptyImage();
00829     };
00830 };
00831 
00832 void LensCalFrame::OnSelectPreviewContent(wxCommandEvent &e)
00833 {
00834     m_preview->SetMode((LensCalImageCtrl::LensCalPreviewMode)e.GetSelection());
00835     XRCCTRL(*this,"lenscal_refresh",wxButton)->Enable(m_preview->GetMode()==LensCalImageCtrl::mode_corrected);
00836 };
00837 
00838 void LensCalFrame::OnShowLines(wxCommandEvent &e)
00839 {
00840     m_preview->SetShowLines(XRCCTRL(*this,"lenscal_show_lines",wxCheckBox)->GetValue());
00841     m_preview->Refresh(true);
00842 };
00843 
00844 void LensCalFrame::OnReset(wxCommandEvent &e)
00845 {
00846     m_edge_scale=DEFAULT_LENSCAL_SCALE;
00847     m_edge_threshold=DEFAULT_LENSCAL_THRESHOLD;
00848     m_resize_dimension=DEFAULT_RESIZE_DIMENSION;
00849     m_minlinelength=DEFAULT_MINLINELENGTH;
00850     ParametersToDisplay();
00851 };
00852 
00853 void LensCalFrame::OnRefresh(wxCommandEvent &e)
00854 {
00855     if(!ReadInputs(true,false,true))
00856     {
00857         wxMessageBox(_("There are invalid values in the input boxes.\nPlease check your inputs."),_("Warning"),wxOK | wxICON_INFORMATION, this);
00858         return;
00859     }
00860     m_preview->SetLens(m_projection,m_focallength,m_cropfactor);
00861     m_preview->SetLensDistortions(m_a,m_b,m_c,m_d,m_e);
00862 };
00863 

Generated on 23 Sep 2017 for Hugintrunk by  doxygen 1.4.7