ImageVariableDialog.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00011 /*  This is free software; you can redistribute it and/or
00012  *  modify it under the terms of the GNU General Public
00013  *  License as published by the Free Software Foundation; either
00014  *  version 2 of the License, or (at your option) any later version.
00015  *
00016  *  This software is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *  Lesser General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public
00022  *  License along with this software. If not, see
00023  *  <http://www.gnu.org/licenses/>.
00024  *
00025  */
00026 
00027 #include "hugin/ImageVariableDialog.h"
00028 #include "base_wx/GraphTools.h"
00029 #include "base_wx/wxPlatform.h"
00030 #include "panoinc.h"
00031 #include "photometric/ResponseTransform.h"
00032 #include <map>
00033 #include <string>
00034 
00035 #include "hugin/huginApp.h"
00036 #include "base_wx/CommandHistory.h"
00037 #include "base_wx/PanoCommand.h"
00038 
00039 BEGIN_EVENT_TABLE(ImageVariableDialog,wxDialog)
00040     EVT_BUTTON(wxID_OK, ImageVariableDialog::OnOk)
00041     EVT_BUTTON(wxID_HELP, ImageVariableDialog::OnHelp)
00042     EVT_BUTTON(XRCID("image_show_distortion_graph"), ImageVariableDialog::OnShowDistortionGraph)
00043     EVT_BUTTON(XRCID("image_show_vignetting_graph"), ImageVariableDialog::OnShowVignettingGraph)
00044     EVT_BUTTON(XRCID("image_show_response_graph"), ImageVariableDialog::OnShowResponseGraph)
00045 END_EVENT_TABLE()
00046 
00047 ImageVariableDialog::ImageVariableDialog(wxWindow *parent, HuginBase::Panorama* pano, HuginBase::UIntSet imgs)
00048 {
00049     // load our children. some children might need special
00050     // initialization. this will be done later.
00051     wxXmlResource::Get()->LoadDialog(this, parent, wxT("image_variables_dialog"));
00052 
00053 #ifdef __WXMSW__
00054     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
00055 #else
00056     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
00057 #endif
00058     SetIcon(myIcon);
00059     wxConfigBase * cfg = wxConfigBase::Get();
00060     //position
00061     int x = cfg->Read(wxT("/ImageVariablesDialog/positionX"),-1l);
00062     int y = cfg->Read(wxT("/ImageVariablesDialog/positionY"),-1l);
00063     if ( y >= 0 && x >= 0) 
00064     {
00065         this->Move(x, y);
00066     } 
00067     else 
00068     {
00069         this->Move(0, 44);
00070     };
00071     m_pano=pano;
00072     m_images=imgs;
00073     m_popup=NULL;
00074     InitValues();
00075 };
00076 
00077 ImageVariableDialog::~ImageVariableDialog()
00078 {
00079     wxConfigBase * cfg = wxConfigBase::Get();
00080     wxPoint ps = this->GetPosition();
00081     cfg->Write(wxT("/ImageVariablesDialog/positionX"), ps.x);
00082     cfg->Write(wxT("/ImageVariablesDialog/positionY"), ps.y);
00083     cfg->Flush();
00084 };
00085 
00086 void ImageVariableDialog::SelectTab(size_t i)
00087 {
00088     XRCCTRL(*this, "image_variable_notebook", wxNotebook)->SetSelection(i);
00089 };
00090 
00091 wxTextCtrl* GetImageVariableControl(const wxWindow* parent, const char* varname)
00092 {
00093     return wxStaticCast(
00094                 parent->FindWindow(
00095                     wxXmlResource::GetXRCID(
00096                         wxString(wxT("image_variable_")).append(wxString(varname, wxConvLocal)).c_str()
00097                     )
00098                 ), wxTextCtrl
00099            );
00100 };
00101 
00102 void ImageVariableDialog::InitValues()
00103 {
00104     if(m_images.size()==0)
00105     {
00106         return;
00107     };
00108     HuginBase::BaseSrcPanoImage::ResponseType responseType = m_pano->getImage(*m_images.begin()).getResponseType();
00109     bool identical=true;
00110 
00111     for (HuginBase::UIntSet::const_iterator it = m_images.begin(); it != m_images.end() && identical; ++it)
00112     {
00113         identical=(responseType==m_pano->getImage(*it).getResponseType());
00114     };
00115     if(identical)
00116     {
00117         XRCCTRL(*this, "image_variable_responseType", wxChoice)->SetSelection(responseType);
00118     };
00119 
00120     int degDigits = wxConfigBase::Get()->Read(wxT("/General/DegreeFractionalDigitsEdit"),3);
00121     int pixelDigits = wxConfigBase::Get()->Read(wxT("/General/PixelFractionalDigitsEdit"),2);
00122     int distDigitsEdit = wxConfigBase::Get()->Read(wxT("/General/DistortionFractionalDigitsEdit"),5);
00123     
00124     HuginBase::VariableMapVector imgVarVector = m_pano->getVariables();
00125 
00126     for (const char** varname = m_varNames; *varname != 0; ++varname)
00127     {
00128         // update parameters
00129         int ndigits = distDigitsEdit;
00130         if (strcmp(*varname, "y") == 0 || strcmp(*varname, "p") == 0 ||
00131             strcmp(*varname, "r") == 0 || strcmp(*varname, "TrX") == 0 ||
00132             strcmp(*varname, "TrY") == 0 || strcmp(*varname, "TrZ") == 0 )
00133         {
00134             ndigits=degDigits;
00135         };
00136         if (strcmp(*varname, "v") == 0 || strcmp(*varname, "d") == 0 ||
00137             strcmp(*varname, "e") == 0 )
00138         {
00139             ndigits = pixelDigits;
00140         }
00141         double val=const_map_get(imgVarVector[*m_images.begin()],*varname).getValue();
00142         bool identical=true;
00143         for(HuginBase::UIntSet::const_iterator it=m_images.begin();it!=m_images.end() && identical;++it)
00144         {
00145             identical=(val==const_map_get(imgVarVector[*it],*varname).getValue());
00146         };
00147         if(identical)
00148         {
00149             GetImageVariableControl(this, *varname)->SetValue(hugin_utils::doubleTowxString(val,ndigits));
00150         };
00151     };
00152 };
00153 
00154 void ImageVariableDialog::SetGuiLevel(GuiLevel newLevel)
00155 {
00156     // translation
00157     XRCCTRL(*this, "image_variable_text_translation", wxStaticText)->Show(newLevel==GUI_EXPERT);
00158     XRCCTRL(*this, "image_variable_text_translation_x", wxStaticText)->Show(newLevel==GUI_EXPERT);
00159     XRCCTRL(*this, "image_variable_text_translation_y", wxStaticText)->Show(newLevel==GUI_EXPERT);
00160     XRCCTRL(*this, "image_variable_text_translation_z", wxStaticText)->Show(newLevel==GUI_EXPERT);
00161     XRCCTRL(*this, "image_variable_text_translation_Tpy", wxStaticText)->Show(newLevel==GUI_EXPERT);
00162     XRCCTRL(*this, "image_variable_text_translation_Tpp", wxStaticText)->Show(newLevel==GUI_EXPERT);
00163     XRCCTRL(*this, "image_variable_TrX", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
00164     XRCCTRL(*this, "image_variable_TrY", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
00165     XRCCTRL(*this, "image_variable_TrZ", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
00166     XRCCTRL(*this, "image_variable_Tpy", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
00167     XRCCTRL(*this, "image_variable_Tpp", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
00168     // shear
00169     XRCCTRL(*this, "image_variable_text_shear", wxStaticText)->Show(newLevel==GUI_EXPERT);
00170     XRCCTRL(*this, "image_variable_text_shear_g", wxStaticText)->Show(newLevel==GUI_EXPERT);
00171     XRCCTRL(*this, "image_variable_text_shear_t", wxStaticText)->Show(newLevel==GUI_EXPERT);
00172     XRCCTRL(*this, "image_variable_g", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
00173     XRCCTRL(*this, "image_variable_t", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
00174 };
00175 
00176 bool ImageVariableDialog::ApplyNewVariables()
00177 {
00178     std::vector<PanoCommand::PanoCommand*> commands;
00179     HuginBase::VariableMap varMap;
00180     for (const char** varname = m_varNames; *varname != 0; ++varname)
00181     {
00182         wxString s=GetImageVariableControl(this, *varname)->GetValue();
00183         if(!s.empty())
00184         {
00185             double val;
00186             if(hugin_utils::str2double(s,val))
00187             {
00188                 if(strcmp(*varname, "v")==0)
00189                 {
00190                     switch(m_pano->getImage(*m_images.begin()).getProjection())
00191                     {
00192                         case HuginBase::SrcPanoImage::RECTILINEAR:
00193                             if(val>179)
00194                             {
00195                                 val=179;
00196                             };
00197                             break;
00198                         case HuginBase::SrcPanoImage::FISHEYE_ORTHOGRAPHIC:
00199                             if(val>190)
00200                             {
00201                                 if(wxMessageBox(
00202                                     wxString::Format(_("You have given a field of view of %.2f degrees.\n But the orthographic projection is limited to a field of view of 180 degress.\nDo you want still use that high value?"), val),
00203 #ifdef __WXMSW__
00204                                     _("Hugin"),
00205 #else
00206                                     wxT(""),
00207 #endif
00208                                     wxICON_EXCLAMATION | wxYES_NO)==wxNO)
00209                                 {
00210                                     return false;
00211                                 };
00212                             };
00213                             break;
00214                         default:
00215                             break;
00216                     };
00217                 };
00218                 varMap.insert(std::make_pair(std::string(*varname), HuginBase::Variable(std::string(*varname), val)));
00219             }
00220             else
00221             {
00222                 wxLogError(_("Value must be numeric."));
00223                 return false;
00224             };
00225         };
00226     };
00227     int sel=XRCCTRL(*this, "image_variable_responseType", wxChoice)->GetSelection();
00228     if(sel!=wxNOT_FOUND)
00229     {
00230         std::vector<HuginBase::SrcPanoImage> SrcImgs;
00231         for (HuginBase::UIntSet::const_iterator it=m_images.begin(); it!=m_images.end(); ++it)
00232         {
00233             HuginBase::SrcPanoImage img=m_pano->getSrcImage(*it);
00234             img.setResponseType((HuginBase::SrcPanoImage::ResponseType)sel);
00235             SrcImgs.push_back(img);
00236         }
00237         commands.push_back(new PanoCommand::UpdateSrcImagesCmd( *m_pano, m_images, SrcImgs ));
00238     }
00239     if(varMap.size()>0)
00240     {
00241         for(HuginBase::UIntSet::const_iterator it=m_images.begin();it!=m_images.end();++it)
00242         {
00243             commands.push_back(
00244                 new PanoCommand::UpdateImageVariablesCmd(*m_pano,*it,varMap)
00245                 );
00246         };
00247     };
00248     if(commands.size()>0)
00249     {
00250         PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::CombinedPanoCommand(*m_pano, commands));
00251         return true;
00252     }
00253     else
00254     {
00255         return false;
00256     };
00257 };
00258 
00259 void ImageVariableDialog::OnOk(wxCommandEvent & e)
00260 {
00261     if(ApplyNewVariables())
00262     {
00263         e.Skip();
00264     };
00265 };
00266 
00267 void ImageVariableDialog::OnHelp(wxCommandEvent & e)
00268 {
00269     // open help on appropriate page
00270     switch(XRCCTRL(*this, "image_variable_notebook", wxNotebook)->GetSelection())
00271     {
00272         //lens parameters
00273         case 1:
00274             MainFrame::Get()->DisplayHelp(wxT("Lens_correction_model.html"));
00275             break;
00276         case 2:
00277             MainFrame::Get()->DisplayHelp(wxT("Vignetting.html"));
00278             break;
00279         case 3:
00280             MainFrame::Get()->DisplayHelp(wxT("Camera_response_curve.html"));
00281             break;
00282         default:
00283             MainFrame::Get()->DisplayHelp(wxT("Image_positioning_model.html"));
00284             break;
00285     };
00286 };
00287 
00288 const char *ImageVariableDialog::m_varNames[] = { "y", "p", "r", "TrX", "TrY", "TrZ", "Tpy", "Tpp", 
00289                                   "v", "a", "b", "c", "d", "e", "g", "t",
00290                                   "Eev", "Er", "Eb", 
00291                                   "Vb", "Vc", "Vd", "Vx", "Vy",
00292                                   "Ra", "Rb", "Rc", "Rd", "Re", 0};
00293 
00294 void ImageVariableDialog::OnShowDistortionGraph(wxCommandEvent & e)
00295 {
00296     wxString stringa=GetImageVariableControl(this, "a")->GetValue();
00297     wxString stringb=GetImageVariableControl(this, "b")->GetValue();
00298     wxString stringc=GetImageVariableControl(this, "c")->GetValue();
00299     if(stringa.empty() || stringb.empty() || stringc.empty())
00300     {
00301         wxBell();
00302         return;
00303     };
00304     std::vector<double> radialDist(4 ,0);
00305     if(!hugin_utils::str2double(stringa, radialDist[0]) || !hugin_utils::str2double(stringb, radialDist[1]) || !hugin_utils::str2double(stringc, radialDist[2]))
00306     {
00307         wxBell();
00308         return;
00309     };
00310     radialDist[3] = 1 - radialDist[0] - radialDist[1] - radialDist[2];
00311 
00312     //create transformation
00313     HuginBase::SrcPanoImage srcImage;
00314     srcImage.setSize(m_pano->getImage(*(m_images.begin())).getSize());
00315     // set projection to rectilinear, just in case, it should be the default value
00316     srcImage.setProjection(HuginBase::SrcPanoImage::RECTILINEAR);
00317     srcImage.setRadialDistortion(radialDist);
00318 
00319     delete m_popup;
00320     //show popup
00321     m_popup = new wxGraphTools::GraphPopupWindow(this, wxGraphTools::GetDistortionGraph(srcImage));
00322     wxWindow *button = (wxWindow*) e.GetEventObject();
00323     wxPoint pos=button->ClientToScreen(wxPoint(0,0));
00324     m_popup->Position(pos, button->GetSize());
00325     m_popup->Popup();
00326 };
00327 
00328 void ImageVariableDialog::OnShowVignettingGraph(wxCommandEvent & e)
00329 {
00330     wxString stringVb=GetImageVariableControl(this, "Vb")->GetValue();
00331     wxString stringVc=GetImageVariableControl(this, "Vc")->GetValue();
00332     wxString stringVd=GetImageVariableControl(this, "Vd")->GetValue();
00333     if(stringVb.empty() || stringVc.empty() || stringVd.empty())
00334     {
00335         wxBell();
00336         return;
00337     };
00338     std::vector<double> vigCorr(4,0);
00339     vigCorr[0]=1.0;
00340     if(!hugin_utils::str2double(stringVb, vigCorr[1]) || !hugin_utils::str2double(stringVc, vigCorr[2]) || !hugin_utils::str2double(stringVd,  vigCorr[3]))
00341     {
00342         wxBell();
00343         return;
00344     };
00345     delete m_popup;
00346     wxGraphTools::Graph graph(300, 200, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
00347     graph.SetChartArea(10, 10, 290, 190);
00348     graph.SetChartDisplay(0, 0.8, 1, 1);
00349     graph.DrawGrid(6, 6);
00350 
00351     //create ResponseTransform with vignetting only
00352     HuginBase::SrcPanoImage srcImage;
00353     srcImage.setRadialVigCorrCoeff(vigCorr);
00354 #define NRPOINTS 100
00355     srcImage.setSize(vigra::Size2D(2*NRPOINTS, 2*NRPOINTS));
00356     HuginBase::Photometric::ResponseTransform<double> transform(srcImage);
00357     transform.enforceMonotonicity();
00358 
00359     //now calc vignetting curve
00360     std::vector<hugin_utils::FDiff2D> points;
00361 #define NRPOINTS 100
00362     for(size_t i=0; i<=NRPOINTS; i++)
00363     {
00364         points.push_back(hugin_utils::FDiff2D(i/double(NRPOINTS),transform(1.0, hugin_utils::FDiff2D(NRPOINTS-i, NRPOINTS-i))));
00365     };
00366     graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 2);
00367 
00368     //display popup
00369     m_popup = new wxGraphTools::GraphPopupWindow(this, graph.GetGraph());
00370     wxWindow *button = (wxWindow*) e.GetEventObject();
00371     wxPoint pos=button->ClientToScreen(wxPoint(0,0));
00372     m_popup->Position(pos, button->GetSize());
00373     m_popup->Popup();
00374 };
00375 
00376 void ImageVariableDialog::OnShowResponseGraph(wxCommandEvent & e)
00377 {
00378     HuginBase::SrcPanoImage::ResponseType responseType=(HuginBase::SrcPanoImage::ResponseType)XRCCTRL(*this, "image_variable_responseType", wxChoice)->GetSelection();
00379     wxString stringRa=GetImageVariableControl(this, "Ra")->GetValue();
00380     wxString stringRb=GetImageVariableControl(this, "Rb")->GetValue();
00381     wxString stringRc=GetImageVariableControl(this, "Rc")->GetValue();
00382     wxString stringRd=GetImageVariableControl(this, "Rd")->GetValue();
00383     wxString stringRe=GetImageVariableControl(this, "Re")->GetValue();
00384     if(stringRa.empty() || stringRb.empty() || stringRc.empty() || stringRd.empty() || stringRe.empty())
00385     {
00386         wxBell();
00387         return;
00388     };
00389     double Ra, Rb, Rc, Rd, Re;
00390     if(!hugin_utils::str2double(stringRa, Ra) || !hugin_utils::str2double(stringRb, Rb) || !hugin_utils::str2double(stringRc, Rc) ||
00391         !hugin_utils::str2double(stringRd, Rd) || !hugin_utils::str2double(stringRe, Re))
00392     {
00393         wxBell();
00394         return;
00395     };
00396     delete m_popup;
00397     wxGraphTools::Graph graph(300, 200, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
00398     graph.SetChartArea(10, 10, 290, 190);
00399     graph.SetChartDisplay(0, 0, 1, 1);
00400     graph.DrawGrid(6, 6);
00401     switch(responseType)
00402     {
00403         case HuginBase::SrcPanoImage::RESPONSE_EMOR:
00404             {
00405                 //draw standard EMOR curve
00406                 std::vector<float> emor(5, 0.0);
00407                 std::vector<double> outLutStd;
00408                 vigra_ext::EMoR::createEMoRLUT(emor, outLutStd);
00409                 vigra_ext::enforceMonotonicity(outLutStd);
00410                 graph.SetChartDisplay(0, 0, outLutStd.size()-1.0, 1.0);
00411                 std::vector<hugin_utils::FDiff2D> points;
00412                 for(size_t i=0; i<outLutStd.size(); i++)
00413                 {
00414                     points.push_back(hugin_utils::FDiff2D(i, outLutStd[i]));
00415                 };
00416                 graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 1);
00417                 outLutStd.clear();
00418                 points.clear();
00419                 // now draw our curve
00420                 emor[0]=Ra;
00421                 emor[1]=Rb;
00422                 emor[2]=Rc;
00423                 emor[3]=Rd;
00424                 emor[4]=Re;
00425                 std::vector<double> outLut;
00426                 vigra_ext::EMoR::createEMoRLUT(emor, outLut);
00427                 vigra_ext::enforceMonotonicity(outLut);
00428                 graph.SetChartDisplay(0, 0, outLut.size()-1.0, 1.0);
00429                 for(size_t i=0; i<outLut.size(); i++)
00430                 {
00431                     points.push_back(hugin_utils::FDiff2D(i, outLut[i]));
00432                 };
00433                 graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 2);
00434             };
00435             break;
00436         case HuginBase::SrcPanoImage::RESPONSE_LINEAR:
00437         default:
00438             {
00439                 std::vector<hugin_utils::FDiff2D> points;
00440                 points.push_back(hugin_utils::FDiff2D(0, 0));
00441                 points.push_back(hugin_utils::FDiff2D(1, 1));
00442                 graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 2);
00443             };
00444             break;
00445     };
00446     //show popup
00447     m_popup = new wxGraphTools::GraphPopupWindow(this, graph.GetGraph());
00448     wxWindow *button = (wxWindow*) e.GetEventObject();
00449     wxPoint pos=button->ClientToScreen(wxPoint(0,0));
00450     m_popup->Position(pos, button->GetSize());
00451     m_popup->Popup();
00452 };

Generated on 16 Dec 2017 for Hugintrunk by  doxygen 1.4.7