Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PerspectivePanel.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
10 /* This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This software is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public
21  * License along with this software. If not, see
22  * <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #include "PerspectivePanel.h"
27 #include "ToolboxApp.h"
28 #include "base_wx/platform.h"
29 #include "wx/clrpicker.h"
30 #include "hugin/config_defaults.h"
31 #include "base_wx/wxPlatform.h"
32 #include "panodata/Panorama.h"
34 #include "base_wx/PTWXDlg.h"
40 #include "lines/FindLines.h"
41 #include "wx/stdpaths.h"
42 #include "base_wx/Executor.h"
43 #include "base_wx/wxutils.h"
44 
46 class PerspectiveDropTarget : public wxFileDropTarget
47 {
48 public:
49  PerspectiveDropTarget(PerspectivePanel* parent) : wxFileDropTarget()
50  {
51  m_perspectivePanel = parent;
52  }
53 
54  bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
55  {
56  // try to add as images
57  if (filenames.size() == 1)
58  {
59  wxFileName file(filenames[0]);
60  if (file.GetExt().CmpNoCase("jpg") == 0 ||
61  file.GetExt().CmpNoCase("jpeg") == 0 ||
62  file.GetExt().CmpNoCase("tif") == 0 ||
63  file.GetExt().CmpNoCase("tiff") == 0 ||
64  file.GetExt().CmpNoCase("png") == 0 ||
65  file.GetExt().CmpNoCase("bmp") == 0 ||
66  file.GetExt().CmpNoCase("gif") == 0 ||
67  file.GetExt().CmpNoCase("pnm") == 0)
68  {
69  m_perspectivePanel->SetImage(filenames[0]);
70  return true;
71  }
72  else
73  {
74  wxBell();
75  };
76  }
77  else
78  {
79  wxBell();
80  };
81  return false;
82  }
83 private:
85 };
86 
87 bool PerspectivePanel::Create(wxWindow* parent, MyExecPanel* logWindow)
88 {
89  if (!wxPanel::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, "panel"))
90  {
91  return false;
92  };
93  // create image control
95  m_preview->Create(this);
96  // set to scale to window
97  m_preview->setScale(0);
98  // load from xrc file
99  wxXmlResource::Get()->LoadPanel(this, "perspective_panel");
100  // connect image control
101  wxXmlResource::Get()->AttachUnknownControl("perspective_preview_window", m_preview, this);
102  // add to sizer
103  wxPanel* mainPanel = XRCCTRL(*this, "perspective_panel", wxPanel);
104  wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL);
105  topsizer->Add(mainPanel, wxSizerFlags(1).Expand());
106  SetSizer(topsizer);
107  // remember some pointer to controls for easier access
108  m_focallengthTextCtrl = XRCCTRL(*this, "perspective_focallength", wxTextCtrl);
109  m_cropTextCtrl = XRCCTRL(*this, "perspective_cropfactor", wxTextCtrl);
110  m_previewChoice = XRCCTRL(*this, "perspective_preview", wxChoice);
111  m_zoomChoice = XRCCTRL(*this, "perspective_choice_zoom", wxChoice);
112  m_rotationChoice = XRCCTRL(*this, "perspective_rotation", wxChoice);
113  m_modeChoice = XRCCTRL(*this, "perspective_mode", wxChoice);
114  m_findLineButton = XRCCTRL(*this, "perspective_find_lines", wxButton);
115  m_helpTextCtrl = XRCCTRL(*this, "perspective_help_text", wxStaticText);
116  m_outputButton = XRCCTRL(*this, "perspective_output", wxButton);
117  m_logWindow = logWindow;
118 
119  wxConfigBase* config = wxConfigBase::Get();
120  //load and set colour
121  wxColour colour, defaultColour;
122  defaultColour.Set(HUGIN_MASK_COLOUR_POINT_SELECTED);
123  colour = config->Read("/ToolboxFrame/Perspective/LineColour", defaultColour.GetAsString(wxC2S_HTML_SYNTAX));
124  XRCCTRL(*this, "perspective_color_picker", wxColourPickerCtrl)->SetColour(colour);
125  m_preview->SetLineColour(colour);
126  m_degDigits = config->Read("/General/DegreeFractionalDigitsEdit", 3);
127 
128  // bind event handler
129  Bind(wxEVT_BUTTON, &PerspectivePanel::OnLoadImage, this, XRCID("perspective_load"));
130  Bind(wxEVT_BUTTON, &PerspectivePanel::OnSavePTO, this, XRCID("perspective_output_pto"));
131  m_outputButton->Bind(wxEVT_BUTTON, &PerspectivePanel::OnSaveOutput, this);
132  m_previewChoice->Bind(wxEVT_CHOICE, &PerspectivePanel::OnPreview, this);
133  m_zoomChoice->Bind(wxEVT_CHOICE, &PerspectivePanel::OnZoom, this);
134  m_modeChoice->Bind(wxEVT_CHOICE, &PerspectivePanel::OnModeChanged, this);
135  Bind(wxEVT_CHOICE, &PerspectivePanel::OnCropChanged, this, XRCID("perspective_crop"));
136  m_rotationChoice->Bind(wxEVT_CHOICE, &PerspectivePanel::OnRotationChanged, this);
137  m_findLineButton->Bind(wxEVT_BUTTON, &PerspectivePanel::OnFindLines, this);
138  Bind(wxEVT_COLOURPICKER_CHANGED, &PerspectivePanel::OnColourChanged, this, XRCID("perspective_color_picker"));
139  // update help text
140  wxCommandEvent commandEvent;
141  OnModeChanged(commandEvent);
142  // allow dropping files
143  SetDropTarget(new PerspectiveDropTarget(this));
144  return true;
145 }
146 
147 void PerspectivePanel::OnZoom(wxCommandEvent& e)
148 {
149  double factor;
150  switch (e.GetSelection())
151  {
152  case 0:
153  factor = 1;
154  break;
155  case 1:
156  // fit to window
157  factor = 0;
158  break;
159  case 2:
160  factor = 2;
161  break;
162  case 3:
163  factor = 1.5;
164  break;
165  case 4:
166  factor = 0.75;
167  break;
168  case 5:
169  factor = 0.5;
170  break;
171  case 6:
172  factor = 0.25;
173  break;
174  default:
175  DEBUG_ERROR("unknown scale factor");
176  factor = 1;
177  }
178  m_preview->setScale(factor);
179 }
180 
181 void PerspectivePanel::OnPreview(wxCommandEvent& e)
182 {
183  if (m_previewChoice->GetSelection() == 1)
184  {
185  // preview mode
186  HuginBase::Panorama pano;
187  if (GetPanorama(pano))
188  {
189  // disable zoom choice in preview mode
190  m_zoomChoice->Enable(e.GetSelection() == 0);
191  m_preview->SetRemappedMode(pano);
192  }
193  else
194  {
195  // could not create pano, reset selection
196  m_previewChoice->SetSelection(0);
197  m_zoomChoice->Enable();
199  }
200  }
201  else
202  {
203  // show original
204  m_zoomChoice->Enable();
206  };
207  Refresh();
208  e.Skip();
209 }
210 
211 void PerspectivePanel::SetImage(const wxString& filename)
212 {
213  // update label for display of filename
214  XRCCTRL(*this, "perspective_filename", wxStaticText)->SetLabel(filename);
215  Layout();
216  // create HuginBase::SrcPanoImage and load values from EXIF
218  const std::string filenameString(filename.mb_str(HUGIN_CONV_FILENAME));
219  m_srcImage.setFilename(filenameString);
221  m_focallengthTextCtrl->Clear();
222  m_cropTextCtrl->Clear();
224  if (m_srcImage.readEXIF())
225  {
226  bool ok = m_srcImage.applyEXIFValues();
227  // load crop factor from database if unknown
228  if (m_srcImage.getCropFactor() < 0.1)
229  {
231  ok = (m_srcImage.getExifFocalLength() > 0 && m_srcImage.getCropFactor() > 0.1);
232  };
233  // update values in control
234  const double focallength = HuginBase::SrcPanoImage::calcFocalLength(m_srcImage.getProjection(), m_srcImage.getHFOV(), m_srcImage.getCropFactor(), m_srcImage.getSize());;
235  const double cropFactor = m_srcImage.getCropFactor();
236  if (focallength > 0 && focallength < 10000)
237  {
238  // use ChangeValue explicit, SetValue would create EVT_TEXT event which collides with our TextKillFocusHandler
240  };
241  if (cropFactor > 0 && cropFactor < 1000)
242  {
243  m_cropTextCtrl->ChangeValue(hugin_utils::doubleTowxString(cropFactor, m_degDigits));
244  };
245  const double rotation = m_srcImage.getExifOrientation();
246  if (rotation == 90)
247  {
249  }
250  else
251  {
252  if (rotation == 180)
253  {
255  }
256  else
257  {
258  if (rotation == 270)
259  {
261  };
262  };
263  };
264  };
265  m_preview->setImage(filenameString, GetRotation());
266  // reset preview mode to original
267  wxCommandEvent e;
268  m_previewChoice->SetSelection(0);
269  OnPreview(e);
270 }
271 
272 void PerspectivePanel::OnLoadImage(wxCommandEvent& e)
273 {
274  wxConfigBase* config = wxConfigBase::Get();
275  wxString path = config->Read("/actualPath", "");
276  wxFileDialog dlg(this, _("Add images"), path, wxEmptyString, GetFileDialogImageFilters(), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_PREVIEW, wxDefaultPosition);
277  dlg.SetDirectory(path);
278 
279  // remember the image extension
280  wxString img_ext;
281  if (config->HasEntry("lastImageType"))
282  {
283  img_ext = config->Read("lastImageType").c_str();
284  }
285  if (img_ext == "all images")
286  dlg.SetFilterIndex(0);
287  else if (img_ext == "jpg")
288  dlg.SetFilterIndex(1);
289  else if (img_ext == "tiff")
290  dlg.SetFilterIndex(2);
291  else if (img_ext == "png")
292  dlg.SetFilterIndex(3);
293  else if (img_ext == "hdr")
294  dlg.SetFilterIndex(4);
295  else if (img_ext == "exr")
296  dlg.SetFilterIndex(5);
297  else if (img_ext == "all files")
298  dlg.SetFilterIndex(6);
299 
300  // call the file dialog
301  if (dlg.ShowModal() == wxID_OK)
302  {
303  // display the selected image
304  SetImage(dlg.GetPath());
305  // save the current path to config
306  config->Write("/actualPath", dlg.GetDirectory());
307  // save the image extension
308  switch (dlg.GetFilterIndex())
309  {
310  case 0: config->Write("lastImageType", "all images"); break;
311  case 1: config->Write("lastImageType", "jpg"); break;
312  case 2: config->Write("lastImageType", "tiff"); break;
313  case 3: config->Write("lastImageType", "png"); break;
314  case 4: config->Write("lastImageType", "hdr"); break;
315  case 5: config->Write("lastImageType", "exr"); break;
316  case 6: config->Write("lastImageType", "all files"); break;
317  };
318  };
319 }
320 
321 void PerspectivePanel::OnColourChanged(wxColourPickerEvent& e)
322 {
323  m_preview->SetLineColour(e.GetColour());
324  wxConfigBase::Get()->Write("/ToolboxFrame/Perspective/LineColour", e.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
325 }
326 
327 void PerspectivePanel::OnCropChanged(wxCommandEvent& e)
328 {
329  if (!m_preview->IsOriginalShown())
330  {
331  // refresh preview
332  OnPreview(e);
333  };
334 }
335 
336 void PerspectivePanel::OnRotationChanged(wxCommandEvent& e)
337 {
339  if (!m_preview->IsOriginalShown())
340  {
341  // refresh preview
342  OnPreview(e);
343  };
344 }
345 
346 void PerspectivePanel::OnModeChanged(wxCommandEvent& e)
347 {
348  const bool isRectMode = m_modeChoice->GetSelection() == 0;
349  m_preview->SetRectMode(isRectMode);
350  if (!m_preview->IsOriginalShown())
351  {
352  // set mode back to original
353  m_previewChoice->SetSelection(0);
354  // refresh preview
355  OnPreview(e);
356  };
357  m_findLineButton->Enable(!isRectMode);
358  m_findLineButton->Show(!isRectMode);
359  // update help text
360  m_helpTextCtrl->SetLabel(GetStatusString());
361  m_helpTextCtrl->Wrap(XRCCTRL(*this, "perspective_color_picker", wxColourPickerCtrl)->GetSize().GetWidth());
362  Layout();
363 }
364 
365 void PerspectivePanel::OnFindLines(wxCommandEvent& e)
366 {
367  HuginBase::Panorama pano;
368  // get unoptimized pano
369  if (GetPanorama(pano, false))
370  {
371  // find lines
372  HuginBase::CPVector lines;
373  if (wxGetKeyState(WXK_COMMAND))
374  {
375  lines = HuginLines::GetVerticalLines(pano, 0, *(m_preview->getCachedImage()->get8BitImage()), *(m_preview->getCachedImage()->mask), 10);
376  }
377  else
378  {
379  lines = HuginLines::GetLines(pano, 0, *(m_preview->getCachedImage()->get8BitImage()), *(m_preview->getCachedImage()->mask));
380  };
381  if (!lines.empty())
382  {
383  // add them to image control
384  m_preview->AddLines(lines);
385  // reset preview mode to original
386  m_previewChoice->SetSelection(0);
387  OnPreview(e);
388  };
389  };
390 }
391 
392 void PerspectivePanel::OnSavePTO(wxCommandEvent& e)
393 {
394  HuginBase::Panorama pano;
395  wxConfigBase* config = wxConfigBase::Get();
396  wxString path = config->Read("/actualPath", "");
397 
398  if (GetPanorama(pano))
399  {
400  wxFileDialog dlg(this, _("Save project file"), path, wxEmptyString,
401  _("Project files (*.pto)|*.pto|All files (*)|*"),
402  wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
403  if (dlg.ShowModal() == wxID_OK)
404  {
405  wxConfig::Get()->Write("/actualPath", dlg.GetDirectory()); // remember for later
406  wxString fn = dlg.GetPath();
407  if (fn.Right(4).CmpNoCase(".pto") != 0)
408  {
409  fn.Append(".pto");
410  if (wxFile::Exists(fn))
411  {
412  if (!hugin_utils::AskUserOverwrite(fn , _("Hugin toolbox"), this))
413  {
414  return;
415  };
416  };
417  };
418  const std::string script(fn.mb_str(HUGIN_CONV_FILENAME));
419  pano.WritePTOFile(script, hugin_utils::getPathPrefix(script));
420  };
421  };
422  m_preview->SendSizeEvent();
423 }
424 
425 void PerspectivePanel::OnSaveOutput(wxCommandEvent& e)
426 {
427  HuginBase::Panorama pano;
428  if (GetPanorama(pano))
429  {
430  wxConfigBase* config = wxConfigBase::Get();
431  wxString path = config->Read("/actualPath", "");
432  wxFileDialog dlg(this, _("Save output"), path, wxEmptyString, GetMainImageFilters(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
433  dlg.SetDirectory(path);
434 
435  // remember the image extension
436  wxString img_ext;
437  if (config->HasEntry("lastImageType"))
438  {
439  img_ext = config->Read("lastImageType").c_str();
440  };
441  if (img_ext == "jpg")
442  {
443  dlg.SetFilterIndex(0);
444  }
445  else
446  {
447  if (img_ext == "tiff")
448  {
449  dlg.SetFilterIndex(1);
450  }
451  else
452  {
453  if (img_ext == "png")
454  {
455  dlg.SetFilterIndex(2);
456  };
457  };
458  };
459  wxFileName outputfilename(wxString(m_srcImage.getFilename().c_str(), HUGIN_CONV_FILENAME));
460  wxString inputFilename = outputfilename.GetFullPath();
461  outputfilename.SetName(outputfilename.GetName() + "_corrected");
462  dlg.SetFilename(outputfilename.GetFullPath());
463  // call the file dialog
464  if (dlg.ShowModal() == wxID_OK)
465  {
466  std::string outputFilename(dlg.GetPath().mb_str(HUGIN_CONV_FILENAME));
467  // save the current path to config
468  config->Write("/actualPath", dlg.GetDirectory());
469  // save the image extension
470  wxString tempFilename = wxFileName::CreateTempFileName(HuginQueue::GetConfigTempDir(wxConfig::Get()) + "htb");
471  pano.WritePTOFile(std::string(tempFilename.mb_str(HUGIN_CONV_FILENAME)));
472  const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
473  wxString nonaArgs;
474  switch (dlg.GetFilterIndex())
475  {
476  case 0:
477  config->Write("lastImageType", "jpg");
478  nonaArgs.Append("-m JPEG ");
479  break;
480  case 1:
481  default:
482  config->Write("lastImageType", "tiff");
483  nonaArgs.Append("-m TIFF ");
484  break;
485  case 2:
486  config->Write("lastImageType", "png");
487  nonaArgs.Append("-m PNG ");
488  break;
489  };
490  // use nona for remapping
491  nonaArgs.Append("-v -o " + HuginQueue::wxEscapeFilename(dlg.GetPath()) + " " + HuginQueue::wxEscapeFilename(tempFilename));
493  queue->push_back(new HuginQueue::NormalCommand(HuginQueue::GetInternalProgram(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), "nona"), nonaArgs, _("Remapping image")));
494  wxString exiftoolArgs("-overwrite_original -tagsfromfile ");
495  exiftoolArgs.Append(HuginQueue::wxEscapeFilename(wxString(m_srcImage.getFilename().c_str(), HUGIN_CONV_FILENAME)));
496  // tags to copy and to ignore (white space at begin and at end!)
497  exiftoolArgs.Append(" -all:all --thumbnail --thumbnailimage --xposition --yposition --orientation --imagefullwidth --imagefullheight ");
498  exiftoolArgs.Append(HuginQueue::wxEscapeFilename(dlg.GetPath()));
499  queue->push_back(new HuginQueue::OptionalCommand(HuginQueue::GetExternalProgram(wxConfig::Get(), exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), "exiftool"), exiftoolArgs, _("Updating EXIF")));
500  m_tempFiles.Add(tempFilename);
502  m_logWindow->ExecQueue(queue);
503  m_outputButton->Disable();
504  };
505  };
506 }
507 
508 void PerspectivePanel::OnProcessFinished(wxCommandEvent& e)
509 {
510  if (!m_tempFiles.IsEmpty())
511  {
512  // delete all temporary files at the end of command
513  for (auto& file : m_tempFiles)
514  {
515  if (wxFileExists(file))
516  {
517  wxRemoveFile(file);
518  };
519  };
520  m_tempFiles.clear();
521  };
522  m_outputButton->Enable();
523 }
524 
526 {
527  if (m_modeChoice->GetSelection()==0)
528  {
529  return _("Adjust the rectangle to an area which should be rectangular in the projected image.");
530  }
531  else
532  {
533  return _("Create a new line by dragging with left mouse button on a free space.\nExisting lines or line end points can be moved by dragging with left mouse button.\nA line can be deleted by clicking with the right mouse button.");
534  };
535 }
536 
538 {
539  if (m_srcImage.getFilename().empty())
540  {
541  hugin_utils::HuginMessageBox(_("You need to load an image first."), _("Hugin toolbox"), wxICON_ERROR | wxOK, this);
542  return false;
543  }
544  wxString focallengthText = m_focallengthTextCtrl->GetValue();
545  if (focallengthText.IsEmpty())
546  {
547  hugin_utils::HuginMessageBox(_("Focal length input box is empty."), _("Hugin toolbox"), wxICON_ERROR | wxOK, this);
548  return false;
549  };
550  double focallength, cropfactor;
551  if (!hugin_utils::str2double(focallengthText, focallength))
552  {
553  hugin_utils::HuginMessageBox(_("Focal length input box contains no valid number."), _("Hugin toolbox"), wxICON_ERROR | wxOK, this);
554  return false;
555  }
556  //no negative values, no zero input please
557  if (focallength < 0.1)
558  {
559  hugin_utils::HuginMessageBox(_("The focal length must be positive."), _("Hugin toolbox"), wxICON_ERROR | wxOK, this);
560  return false;
561  };
562  wxString cropfactorText = m_cropTextCtrl->GetValue();
563  if (cropfactorText.IsEmpty())
564  {
565  hugin_utils::HuginMessageBox(_("Crop factor input box is empty."), _("Hugin toolbox"), wxICON_ERROR | wxOK, this);
566  return false;
567  };
568  if (!hugin_utils::str2double(cropfactorText, cropfactor))
569  {
570  hugin_utils::HuginMessageBox(_("Crop factor input box contains no valid number."), _("Hugin toolbox"), wxICON_ERROR | wxOK, this);
571  return false;
572  }
573  //no negative values, no zero input please
574  if (cropfactor < 0.1)
575  {
576  hugin_utils::HuginMessageBox(_("The crop factor must be positive."), _("Hugin toolbox"), wxICON_ERROR | wxOK, this);
577  return false;
578  };
579  const double hfov = HuginBase::SrcPanoImage::calcHFOV(m_srcImage.getProjection(), focallength, cropfactor, m_srcImage.getSize());
580  if (hfov > 178)
581  {
582  hugin_utils::HuginMessageBox(_("The focal length and crop factor result in a invalid value of %d for the horizontal field of view.\nPlease input a valid combination of focal length and crop factor."),
583  _("Hugin toolbox"), wxICON_QUESTION | wxOK, this);
584  return false;
585  };
586  m_srcImage.setHFOV(hfov);
587  return true;
588 }
589 
590 bool PerspectivePanel::GetPanorama(HuginBase::Panorama& pano, const bool optimized)
591 {
592  if (ReadInputs())
593  {
595  panoImage.setRoll(GetRoll());
596  pano.addImage(panoImage);
598  if (optimized && pano.getCtrlPoints().size() < 2)
599  {
600  hugin_utils::HuginMessageBox(_("You need to create at least 2 lines."), _("Hugin toolbox"), wxICON_ERROR | wxOK, this);
601  return false;
602  };
604  // optimize yaw, pitch and roll
605  std::set<std::string> imgopt;
606  imgopt.insert("y");
607  imgopt.insert("p");
608  imgopt.insert("r");
609  optvec.push_back(imgopt);
610  pano.setOptimizeVector(optvec);
611  // set some sensible values for PanoramaOptions
614  opts.outputExposureValue = m_srcImage.getExposureValue();
615  pano.setOptions(opts);
616  // now optimize pano
617  if (optimized)
618  {
622  // calculate field of view
623  HuginBase::CalculateFitPanorama fitPano(pano);
624  fitPano.run();
625  opts.setHFOV(fitPano.getResultHorizontalFOV());
627  // calculate scale
629  opts.setWidth(scale * opts.getWidth());
630  pano.setOptions(opts);
631  // crop pano
633  const int cropMode = XRCCTRL(*this, "perspective_crop", wxChoice)->GetSelection();
634  if (cropMode == 1)
635  {
636  // crop inside
637  HuginBase::CalculateOptimalROI cropPano(pano, &progress);
638  cropPano.run();
639  if (cropPano.hasRunSuccessfully())
640  {
641  opts.setROI(cropPano.getResultOptimalROI());
642  };
643  pano.setOptions(opts);
644  }
645  else
646  {
647  // crop outside
648  HuginBase::CalculateOptimalROIOutside cropPano(pano, &progress);
649  cropPano.run();
650  if (cropPano.hasRunSuccessfully())
651  {
652  opts.setROI(cropPano.getResultOptimalROI());
653  };
654  pano.setOptions(opts);
655  };
656  };
657  return true;
658  }
659  else
660  {
661  return false;
662  };
663 }
664 
666 {
667  switch (m_rotationChoice->GetSelection())
668  {
669  case 0:
670  default:
671  // auto-rotate, return EXIF value
672  return m_exifRotation;
673  break;
674  case 1:
676  break;
677  case 2:
679  break;
680  case 3:
682  break;
683  case 4:
685  break;
686  }
688 }
689 
690 const double PerspectivePanel::GetRoll() const
691 {
692  switch (GetRotation())
693  {
695  default:
696  return 0.0;
697  break;
699  return 90.0;
700  break;
702  return 180.0;
703  break;
705  return 270.0;
706  break;
707  }
708  return 0.0;
709 }
710 
wxArrayString m_tempFiles
temp files, which should be deleted at end
normal command for queue, processing is stopped if an error occurred in program
Definition: Executor.h:37
wxTextCtrl * m_cropTextCtrl
bool Create(wxWindow *parent, MyExecPanel *logWindow)
create the panel and populate all controls
implementation of huginApp Class
Dummy progress display, without output.
bool AskUserOverwrite(const wxString &filename, const wxString &caption, wxWindow *parent)
ask user if the given file should be overwritten, return true if the user confirmed the overwritting ...
Definition: wxutils.cpp:233
static double calcOptimalPanoScale(const SrcPanoImage &src, const PanoramaOptions &dest)
function to calculate the scaling factor so that the distances in the input image and panorama image ...
wxString GetStatusString()
return help text for current mode
void OnFindLines(wxCommandEvent &e)
bool applyEXIFValues(bool applyEVValue=true)
apply values found in EXIF data to SrcPanoImage class, call readEXIF() before to initialize some valu...
const wxString GetConfigTempDir(const wxConfigBase *config)
return the temp dir from the preferences, ensure that it ends with path separator ...
Definition: Executor.cpp:302
void setHeight(unsigned int h)
set panorama height
int roundi(T x)
Definition: hugin_math.h:73
bool str2double(const wxString &s, double &d)
Definition: wxPlatform.cpp:37
HuginBase::CPVector GetVerticalLines(const HuginBase::Panorama &pano, const unsigned int imgNr, vigra::UInt8RGBImage &image, vigra::BImage &mask, const unsigned int nrLines)
searches for vertical control points in given image
Definition: FindLines.cpp:601
optional command for queue, processing of queue is always continued, also if an error occurred ...
Definition: Executor.h:53
#define HUGIN_CONV_FILENAME
Definition: platform.h:40
declaration of panel for perspective correction GUI
wxButton * m_outputButton
declaration of functions for finding lines
wxStaticText * m_helpTextCtrl
void registerPTWXDlgFcn()
Definition: PTWXDlg.cpp:178
int ExecQueue(HuginQueue::CommandQueue *queue)
bool checkImageSizeKnown()
check if the image size is known, if try to load the information from the file
void ChangeRotation(ImageRotation newRot)
void OnModeChanged(wxCommandEvent &e)
void ClearOutput()
clear the output
void deregisterPTWXDlgFcn()
Definition: PTWXDlg.cpp:185
wxString doubleTowxString(double d, int digits)
Definition: wxPlatform.cpp:31
wxString GetInternalProgram(const wxString &bindir, const wxString &name)
return path and name of external program, which comes bundled with Hugin
Definition: Executor.cpp:129
const double GetRoll() const
return the roll angle in degree
void setScale(double factor)
set the scaling factor for mask editing display.
void SetRectMode(bool newMode)
set line or rect mode
virtual void run()
runs the algorithm.
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition: Panorama.h:319
void setOptimizeVector(const OptimizeVector &optvec)
set optimize setting
Definition: Panorama.cpp:297
PerspectivePanel * m_perspectivePanel
basic classes and function for queuing commands in wxWidgets
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name="panel")
creates the control
void setImage(const std::string &filename, ImageRotation rot)
set the current image and mask list, this loads also the image from cache
bool ReadInputs()
read the values from the input boxes
void SetRemappedMode(const HuginBase::Panorama &pano)
set the panorama object for remapping, the mouse handler are deactivated
PerspectiveImageCtrl::ImageRotation m_exifRotation
save rotation as written in EXIF
Model for a panorama.
Definition: Panorama.h:152
void AddLines(const HuginBase::CPVector &lines)
add the lines to the list
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
Definition: utils.cpp:184
wxChoice * m_modeChoice
void OnProcessFinished(wxCommandEvent &e)
clean up temporary files at end
const PerspectiveImageCtrl::ImageRotation GetRotation() const
return the image rotation
void OnSaveOutput(wxCommandEvent &e)
void OnZoom(wxCommandEvent &e)
HuginBase::CPVector GetControlPoints(const unsigned int index)
return list of control points
void setCtrlPoints(const CPVector &points)
set all control points (Ippei: Is this supposed to be &#39;add&#39; method?)
Definition: Panorama.cpp:449
void OnLoadImage(wxCommandEvent &e)
virtual vigra::Rect2D getResultOptimalROI()
return the ROI structure?, for now area
virtual double getResultHeight()
Definition: FitPanorama.h:75
void SetLineColour(wxColour newColour)
sets the colour for the lines
PerspectiveImageCtrl * m_preview
controls
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
wxString GetMainImageFilters()
return a filter for the main image files (JPG/TIFF/PNG) only
Definition: platform.cpp:80
bool GetPanorama(HuginBase::Panorama &pano, const bool optimized=true)
return Pano object, it is optimized and the crop set when optimized=true
wxChoice * m_zoomChoice
HuginBase::CPVector GetLines(const HuginBase::Panorama &pano, const unsigned int imgNr, vigra::UInt8RGBImage &image, vigra::BImage &mask)
searches for all lines, the same as GetVerticalLines execpt that no filtering according to roll angle...
Definition: FindLines.cpp:611
image previewer for perspective correction
static double calcFocalLength(SrcPanoImage::Projection proj, double hfov, double crop, vigra::Size2D imageSize)
calcualte focal length, given crop factor and hfov
ImageCache::EntryPtr getCachedImage()
return pointer to ImageCache
MyExecPanel * m_logWindow
#define DEBUG_ERROR(msg)
Definition: utils.h:76
void setROI(const vigra::Rect2D &val)
!! from PTOptimise.h 1951
unsigned int addImage(const SrcPanoImage &img)
the the number for a specific image
Definition: Panorama.cpp:319
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
void setOriginalMode()
show the original images with selected zoom ration, the mouse handlers are activated ...
void OnCropChanged(wxCommandEvent &e)
void OnRotationChanged(wxCommandEvent &e)
void setHFOV(double h, bool keepView=true)
set the horizontal field of view.
wxButton * m_findLineButton
unsigned int getWidth() const
ImageRotation
image rotation.
void OnColourChanged(wxColourPickerEvent &e)
virtual double getResultHorizontalFOV()
Definition: FitPanorama.h:68
virtual vigra::Rect2D getResultOptimalROI()
returns the found crop rect
str wxEscapeFilename(const str &arg)
special escaping routine for CommandQueues
Definition: Executor.h:79
#define HUGIN_MASK_COLOUR_POINT_SELECTED
bool readEXIF()
try to fill out information about the image, by examining the exif data
file drag and drop handler method
unsigned int optimize(PanoramaData &pano, const char *userScript)
optimize the images imgs, for variables optvec, using vars as start.
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
static double calcHFOV(SrcPanoImage::Projection proj, double fl, double crop, vigra::Size2D imageSize)
calculate hfov of an image given focal length, image size and crop factor
platform/compiler specific stuff.
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
Definition: Panorama.cpp:2059
std::vector< std::set< std::string > > OptimizeVector
void OnSavePTO(wxCommandEvent &e)
HuginBase::SrcPanoImage m_srcImage
SrcPanoImage, contains information about the image.
void setOptions(const PanoramaOptions &opt)
set new output settings This is not used directly for optimizing/stiching, but it can be feed into ru...
Definition: Panorama.cpp:1531
void OnPreview(wxCommandEvent &e)
wxTextCtrl * m_focallengthTextCtrl
void SetImage(const wxString &filename)
load the given image
All variables of a source image.
Definition: SrcPanoImage.h:194
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
wxString GetFileDialogImageFilters()
return filter for image files, needed by file open dialog it contains all image format vigra can read...
Definition: platform.cpp:69
Panorama image options.
bool readCropfactorFromDB()
tries to read cropfactor from lens database you need to call SrcPanoImage::readEXIF before to fill so...
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition: wxutils.cpp:176
wxString GetExternalProgram(wxConfigBase *config, const wxString &bindir, const wxString &name)
return path and name of external program, which can be overwritten by the user
Definition: Executor.cpp:148
std::vector< NormalCommand * > CommandQueue
Definition: Executor.h:61
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
panel for enfuse GUI
wxChoice * m_previewChoice
PerspectiveDropTarget(PerspectivePanel *parent)
wxChoice * m_rotationChoice