Hugin trunk 0.1
Loading...
Searching...
No Matches
ImageVariableDialog.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
2
11/* This is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public
22 * License along with this software. If not, see
23 * <http://www.gnu.org/licenses/>.
24 *
25 */
26
28#include "base_wx/GraphTools.h"
29#include "base_wx/wxPlatform.h"
30#include "base_wx/wxutils.h"
31#include "panoinc.h"
33#include <map>
34#include <string>
35
36#include "hugin/huginApp.h"
38#include "base_wx/PanoCommand.h"
39
41{
42 // load our children. some children might need special
43 // initialization. this will be done later.
44 wxXmlResource::Get()->LoadDialog(this, parent, "image_variables_dialog");
45
46 //position
47 hugin_utils::RestoreFramePositionOnly(this, "ImageVariablesDialog");
48 m_pano=pano;
49 m_images=imgs;
51 InitValues();
52 // bind event handler
55 Bind(wxEVT_BUTTON, &ImageVariableDialog::OnShowDistortionGraph, this, XRCID("image_show_distortion_graph"));
56 Bind(wxEVT_BUTTON, &ImageVariableDialog::OnShowVignettingGraph, this, XRCID("image_show_vignetting_graph"));
57 Bind(wxEVT_BUTTON, &ImageVariableDialog::OnShowResponseGraph, this, XRCID("image_show_response_graph"));
58 Bind(wxEVT_CHOICE, &ImageVariableDialog::OnResponseSelected, this, XRCID("image_variable_responseType"));
59};
60
62{
63 hugin_utils::StoreFramePositionOnly(this, "ImageVariablesDialog");
64 wxConfigBase::Get()->Flush();
65};
66
68{
69 XRCCTRL(*this, "image_variable_notebook", wxNotebook)->SetSelection(i);
70};
71
72wxTextCtrl* GetImageVariableControl(const wxWindow* parent, const char* varname)
73{
74 return wxStaticCast(
75 parent->FindWindow(
76 wxXmlResource::GetXRCID(
77 wxString("image_variable_").append(wxString(varname, wxConvLocal)).c_str()
78 )
79 ), wxTextCtrl
80 );
81};
82
84{
85 if(m_images.empty())
86 {
87 return;
88 };
89 HuginBase::BaseSrcPanoImage::ResponseType responseType = m_pano->getImage(*m_images.begin()).getResponseType();
90 bool identical=true;
91
92 for (HuginBase::UIntSet::const_iterator it = m_images.begin(); it != m_images.end() && identical; ++it)
93 {
94 identical=(responseType==m_pano->getImage(*it).getResponseType());
95 };
96 if(identical)
97 {
98 XRCCTRL(*this, "image_variable_responseType", wxChoice)->SetSelection(responseType);
99 };
100
101 int degDigits = wxConfigBase::Get()->Read("/General/DegreeFractionalDigitsEdit",3);
102 int pixelDigits = wxConfigBase::Get()->Read("/General/PixelFractionalDigitsEdit",2);
103 int distDigitsEdit = wxConfigBase::Get()->Read("/General/DistortionFractionalDigitsEdit",5);
104
106
107 for (const char** varname = m_varNames; *varname != 0; ++varname)
108 {
109 // update parameters
111 if (strcmp(*varname, "y") == 0 || strcmp(*varname, "p") == 0 ||
112 strcmp(*varname, "r") == 0 || strcmp(*varname, "TrX") == 0 ||
113 strcmp(*varname, "TrY") == 0 || strcmp(*varname, "TrZ") == 0 )
114 {
116 };
117 if (strcmp(*varname, "v") == 0 || strcmp(*varname, "d") == 0 ||
118 strcmp(*varname, "e") == 0 )
119 {
121 }
122 double val=const_map_get(imgVarVector[*m_images.begin()],*varname).getValue();
123 bool identical=true;
124 for(HuginBase::UIntSet::const_iterator it=m_images.begin();it!=m_images.end() && identical;++it)
125 {
126 identical=(val==const_map_get(imgVarVector[*it],*varname).getValue());
127 };
128 if(identical)
129 {
130 GetImageVariableControl(this, *varname)->SetValue(hugin_utils::doubleTowxString(val,ndigits));
131 };
132 };
133 wxCommandEvent dummy;
135};
136
138{
139 // translation
140 XRCCTRL(*this, "image_variable_text_translation", wxStaticText)->Show(newLevel==GUI_EXPERT);
141 XRCCTRL(*this, "image_variable_text_translation_x", wxStaticText)->Show(newLevel==GUI_EXPERT);
142 XRCCTRL(*this, "image_variable_text_translation_y", wxStaticText)->Show(newLevel==GUI_EXPERT);
143 XRCCTRL(*this, "image_variable_text_translation_z", wxStaticText)->Show(newLevel==GUI_EXPERT);
144 XRCCTRL(*this, "image_variable_text_translation_Tpy", wxStaticText)->Show(newLevel==GUI_EXPERT);
145 XRCCTRL(*this, "image_variable_text_translation_Tpp", wxStaticText)->Show(newLevel==GUI_EXPERT);
146 XRCCTRL(*this, "image_variable_TrX", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
147 XRCCTRL(*this, "image_variable_TrY", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
148 XRCCTRL(*this, "image_variable_TrZ", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
149 XRCCTRL(*this, "image_variable_Tpy", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
150 XRCCTRL(*this, "image_variable_Tpp", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
151 // shear
152 XRCCTRL(*this, "image_variable_text_shear", wxStaticText)->Show(newLevel==GUI_EXPERT);
153 XRCCTRL(*this, "image_variable_text_shear_g", wxStaticText)->Show(newLevel==GUI_EXPERT);
154 XRCCTRL(*this, "image_variable_text_shear_t", wxStaticText)->Show(newLevel==GUI_EXPERT);
155 XRCCTRL(*this, "image_variable_g", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
156 XRCCTRL(*this, "image_variable_t", wxTextCtrl)->Show(newLevel==GUI_EXPERT);
157};
158
160{
161 std::vector<PanoCommand::PanoCommand*> commands;
163 for (const char** varname = m_varNames; *varname != 0; ++varname)
164 {
165 wxString s=GetImageVariableControl(this, *varname)->GetValue();
166 if(!s.empty())
167 {
168 double val;
170 {
171 if(strcmp(*varname, "v")==0)
172 {
173 if (val < 0.05)
174 {
175 hugin_utils::HuginMessageBox(_("The horizontal field of view must be positive."), _("Hugin"), wxICON_EXCLAMATION | wxOK, this);
176 return false;
177 };
178 switch(m_pano->getImage(*m_images.begin()).getProjection())
179 {
181 if(val>179)
182 {
183 val=179;
184 };
185 break;
187 if(val>190)
188 {
190 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),
191 _("Hugin"), wxICON_EXCLAMATION | wxYES_NO, this) == wxNO)
192 {
193 return false;
194 };
195 };
196 break;
197 default:
198 break;
199 };
200 };
201 varMap.insert(std::make_pair(std::string(*varname), HuginBase::Variable(std::string(*varname), val)));
202 }
203 else
204 {
205 wxLogError(_("Value must be numeric."));
206 return false;
207 };
208 };
209 };
210 int sel=XRCCTRL(*this, "image_variable_responseType", wxChoice)->GetSelection();
211 if(sel!=wxNOT_FOUND)
212 {
213 std::vector<HuginBase::SrcPanoImage> SrcImgs;
214 for (HuginBase::UIntSet::const_iterator it=m_images.begin(); it!=m_images.end(); ++it)
215 {
217 img.setResponseType((HuginBase::SrcPanoImage::ResponseType)sel);
218 SrcImgs.push_back(img);
219 }
220 commands.push_back(new PanoCommand::UpdateSrcImagesCmd( *m_pano, m_images, SrcImgs ));
221 }
222 if(!varMap.empty())
223 {
224 for(HuginBase::UIntSet::const_iterator it=m_images.begin();it!=m_images.end();++it)
225 {
226 commands.push_back(
228 );
229 };
230 };
231 if(!commands.empty())
232 {
234 return true;
235 }
236 else
237 {
238 return false;
239 };
240};
241
242void ImageVariableDialog::OnOk(wxCommandEvent & e)
243{
245 {
246 e.Skip();
247 };
248};
249
250void ImageVariableDialog::OnHelp(wxCommandEvent & e)
251{
252 // open help on appropriate page
253 switch(XRCCTRL(*this, "image_variable_notebook", wxNotebook)->GetSelection())
254 {
255 //lens parameters
256 case 1:
257 MainFrame::Get()->DisplayHelp("Lens_correction_model.html");
258 break;
259 case 2:
260 MainFrame::Get()->DisplayHelp("Vignetting.html");
261 break;
262 case 3:
263 MainFrame::Get()->DisplayHelp("Camera_response_curve.html");
264 break;
265 default:
266 MainFrame::Get()->DisplayHelp("Image_positioning_model.html");
267 break;
268 };
269};
270
272{
273 const bool showResponseParam = XRCCTRL(*this, "image_variable_responseType", wxChoice)->GetSelection() == 0;
274 wxTextCtrl* control = XRCCTRL(*this, "image_variable_Ra", wxTextCtrl);
275 control->Enable(showResponseParam);
276 control->Show(showResponseParam);
277 control = XRCCTRL(*this, "image_variable_Rb", wxTextCtrl);
278 control->Enable(showResponseParam);
279 control->Show(showResponseParam);
280 control = XRCCTRL(*this, "image_variable_Rc", wxTextCtrl);
281 control->Enable(showResponseParam);
282 control->Show(showResponseParam);
283 control = XRCCTRL(*this, "image_variable_Rd", wxTextCtrl);
284 control->Enable(showResponseParam);
285 control->Show(showResponseParam);
286 control = XRCCTRL(*this, "image_variable_Re", wxTextCtrl);
287 control->Enable(showResponseParam);
288 control->Show(showResponseParam);
289};
290
291const char *ImageVariableDialog::m_varNames[] = { "y", "p", "r", "TrX", "TrY", "TrZ", "Tpy", "Tpp",
292 "v", "a", "b", "c", "d", "e", "g", "t",
293 "Eev", "Er", "Eb",
294 "Vb", "Vc", "Vd", "Vx", "Vy",
295 "Ra", "Rb", "Rc", "Rd", "Re", 0};
296
298{
299 wxString stringa=GetImageVariableControl(this, "a")->GetValue();
300 wxString stringb=GetImageVariableControl(this, "b")->GetValue();
301 wxString stringc=GetImageVariableControl(this, "c")->GetValue();
302 if(stringa.empty() || stringb.empty() || stringc.empty())
303 {
304 wxBell();
305 return;
306 };
307 std::vector<double> radialDist(4 ,0);
309 {
310 wxBell();
311 return;
312 };
313 radialDist[3] = 1 - radialDist[0] - radialDist[1] - radialDist[2];
314
315 //create transformation
317 srcImage.setSize(m_pano->getImage(*(m_images.begin())).getSize());
318 // set projection to rectilinear, just in case, it should be the default value
319 srcImage.setProjection(HuginBase::SrcPanoImage::RECTILINEAR);
320 srcImage.setRadialDistortion(radialDist);
321
322 delete m_popup;
323 //show popup
325 wxWindow *button = (wxWindow*) e.GetEventObject();
326 wxPoint pos=button->ClientToScreen(wxPoint(0,0));
327 m_popup->Position(pos, button->GetSize());
328 m_popup->Popup();
329};
330
332{
333 wxString stringVb=GetImageVariableControl(this, "Vb")->GetValue();
334 wxString stringVc=GetImageVariableControl(this, "Vc")->GetValue();
335 wxString stringVd=GetImageVariableControl(this, "Vd")->GetValue();
336 if(stringVb.empty() || stringVc.empty() || stringVd.empty())
337 {
338 wxBell();
339 return;
340 };
341 std::vector<double> vigCorr(4,0);
342 vigCorr[0]=1.0;
344 {
345 wxBell();
346 return;
347 };
348 delete m_popup;
349 wxGraphTools::Graph graph(300, 200, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
350 graph.SetChartArea(10, 10, 290, 190);
351 graph.SetChartDisplay(0, 0.8, 1, 1);
352 graph.DrawGrid(6, 6);
353
354 //create ResponseTransform with vignetting only
356 srcImage.setRadialVigCorrCoeff(vigCorr);
357#define NRPOINTS 100
358 srcImage.setSize(vigra::Size2D(2*NRPOINTS, 2*NRPOINTS));
360 transform.enforceMonotonicity();
361
362 //now calc vignetting curve
363 std::vector<hugin_utils::FDiff2D> points;
364#define NRPOINTS 100
365 for(size_t i=0; i<=NRPOINTS; i++)
366 {
367 points.push_back(hugin_utils::FDiff2D(i/double(NRPOINTS),transform(1.0, hugin_utils::FDiff2D(NRPOINTS-i, NRPOINTS-i))));
368 };
369 graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 2);
370
371 //display popup
372 m_popup = new wxGraphTools::GraphPopupWindow(this, graph.GetGraph());
373 wxWindow *button = (wxWindow*) e.GetEventObject();
374 wxPoint pos=button->ClientToScreen(wxPoint(0,0));
375 m_popup->Position(pos, button->GetSize());
376 m_popup->Popup();
377};
378
380{
381 HuginBase::SrcPanoImage::ResponseType responseType=(HuginBase::SrcPanoImage::ResponseType)XRCCTRL(*this, "image_variable_responseType", wxChoice)->GetSelection();
382 wxString stringRa=GetImageVariableControl(this, "Ra")->GetValue();
383 wxString stringRb=GetImageVariableControl(this, "Rb")->GetValue();
384 wxString stringRc=GetImageVariableControl(this, "Rc")->GetValue();
385 wxString stringRd=GetImageVariableControl(this, "Rd")->GetValue();
386 wxString stringRe=GetImageVariableControl(this, "Re")->GetValue();
387 if(stringRa.empty() || stringRb.empty() || stringRc.empty() || stringRd.empty() || stringRe.empty())
388 {
389 wxBell();
390 return;
391 };
392 double Ra, Rb, Rc, Rd, Re;
395 {
396 wxBell();
397 return;
398 };
399 delete m_popup;
400 wxGraphTools::Graph graph(300, 200, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
401 graph.SetChartArea(10, 10, 290, 190);
402 graph.SetChartDisplay(0, 0, 1, 1);
403 graph.DrawGrid(6, 6);
404 switch(responseType)
405 {
407 {
408 //draw standard EMOR curve
409 std::vector<float> emor(5, 0.0);
410 std::vector<double> outLutStd;
413 graph.SetChartDisplay(0, 0, outLutStd.size()-1.0, 1.0);
414 std::vector<hugin_utils::FDiff2D> points;
415 for(size_t i=0; i<outLutStd.size(); i++)
416 {
418 };
419 graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 1);
420 outLutStd.clear();
421 points.clear();
422 // now draw our curve
423 emor[0]=Ra;
424 emor[1]=Rb;
425 emor[2]=Rc;
426 emor[3]=Rd;
427 emor[4]=Re;
428 std::vector<double> outLut;
431 graph.SetChartDisplay(0, 0, outLut.size()-1.0, 1.0);
432 for(size_t i=0; i<outLut.size(); i++)
433 {
434 points.push_back(hugin_utils::FDiff2D(i, outLut[i]));
435 };
436 graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 2);
437 };
438 break;
440 default:
441 {
442 std::vector<hugin_utils::FDiff2D> points;
443 points.push_back(hugin_utils::FDiff2D(0, 0));
444 points.push_back(hugin_utils::FDiff2D(1, 1));
445 graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 2);
446 };
447 break;
448 };
449 //show popup
450 m_popup = new wxGraphTools::GraphPopupWindow(this, graph.GetGraph());
451 wxWindow *button = (wxWindow*) e.GetEventObject();
452 wxPoint pos=button->ClientToScreen(wxPoint(0,0));
453 m_popup->Position(pos, button->GetSize());
454 m_popup->Popup();
455};
#define NRPOINTS
GuiLevel
Definition GuiLevel.h:32
@ GUI_EXPERT
Definition GuiLevel.h:35
wxTextCtrl * GetImageVariableControl(const wxWindow *parent, const char *varname)
Definition of dialog to edit image variables.
@ RESPONSE_LINEAR
linear response
@ RESPONSE_EMOR
empirical model of response
Model for a panorama.
Definition Panorama.h:153
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition Panorama.h:211
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
VariableMapVector getVariables() const
get variables of this panorama
Definition Panorama.cpp:118
radiometric transformation, includes exposure, vignetting and white balance.
All variables of a source image.
a variable has a value and a name.
void OnOk(wxCommandEvent &e)
Saves current state of all checkboxes when closing dialog with Ok.
void OnHelp(wxCommandEvent &e)
shows the help
static const char * m_varNames[]
void OnResponseSelected(wxCommandEvent &e)
response type changed
bool ApplyNewVariables()
applies the changed variables to the Panorama class, using CommandHistory
wxGraphTools::GraphPopupWindow * m_popup
void InitValues()
copy the variables from Panorama to dialog
void SelectTab(size_t i)
selects the tab with index i
void OnShowVignettingGraph(wxCommandEvent &e)
shows a popup with vignetting graph
ImageVariableDialog(wxWindow *parent, HuginBase::Panorama *pano, HuginBase::UIntSet imgs)
Constructor, read from xrc ressource; restore last uses settings and position.
HuginBase::Panorama * m_pano
~ImageVariableDialog()
destructor, saves position
void OnShowDistortionGraph(wxCommandEvent &e)
shows a popup with distortion graph
HuginBase::UIntSet m_images
void OnShowResponseGraph(wxCommandEvent &e)
shows a popup with response graph
void SetGuiLevel(GuiLevel newLevel)
sets the GuiLevel
static MainFrame * Get()
hack.. kind of a pseudo singleton...
void DisplayHelp(wxString section=wxEmptyString)
call help browser with given file
PanoCommand to combine other PanoCommands.
Definition PanoCommand.h:40
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
static GlobalCmdHist & getInstance()
update variables of a single image
simple popup to show graph
Definition GraphTools.h:39
help class to draw charts
Definition GraphTools.h:52
std::vector< VariableMap > VariableMapVector
std::set< unsigned int > UIntSet
std::map< std::string, Variable > VariableMap
bool str2double(const wxString &s, double &d)
void StoreFramePositionOnly(wxTopLevelWindow *frame, const wxString &basename)
Definition wxutils.cpp:163
wxString doubleTowxString(double d, int digits)
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition wxutils.cpp:176
void RestoreFramePositionOnly(wxTopLevelWindow *frame, const wxString &basename)
Definition wxutils.cpp:143
void createEMoRLUT(const std::vector< float > &params, VECTOR &lut)
Definition emor.h:44
void enforceMonotonicity(LUT &lut)
enforce monotonicity of an array (mostly used for lookup tables)
Definition lut.h:87
wxBitmap GetDistortionGraph(const HuginBase::SrcPanoImage &srcImage)
return wxBitmap with graph of distortion for given SrcPanoImage
include file for the hugin project
const Map::mapped_type & const_map_get(const Map &m, const typename Map::key_type &key)
Definition stl_utils.h:110
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41
platform/compiler specific stuff.