Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PanoOperation.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
9 /* This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This software is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public
20  * License along with this software. If not, see
21  * <http://www.gnu.org/licenses/>.
22  *
23  */
24 
25 #include "hugin/PanoOperation.h"
26 #include "hugin/config_defaults.h"
27 #include "base_wx/PanoCommand.h"
28 #include "base_wx/wxPanoCommand.h"
29 #include "huginapp/ImageCache.h"
31 #include "base_wx/PTWXDlg.h"
32 #include "base_wx/wxutils.h"
35 #include "celeste/Celeste.h"
36 #ifdef _WIN32
37 // workaround for a conflict between exiv2 and wxWidgets/CMake built
38 #define HAVE_PID_T 1
39 #endif
40 #include <exiv2/exiv2.hpp>
41 #include "base_wx/LensTools.h"
42 #include "base_wx/wxLensDB.h"
43 #include "hugin/ResetDialog.h"
45 #include "hugin/MainFrame.h"
46 #include "hugin/RawImport.h"
47 #include <vigra_ext/openmp_vigra.h>
48 #include <vigra_ext/cms.h>
49 
50 namespace PanoOperation
51 {
52 
53 wxString PanoOperation::GetLabel()
54 {
55  return wxEmptyString;
56 };
57 
58 bool PanoOperation::IsEnabled(HuginBase::Panorama& pano, HuginBase::UIntSet images, GuiLevel guiLevel)
59 {
60  return true;
61 };
62 
63 PanoCommand::PanoCommand* PanoOperation::GetCommand(wxWindow* parent, HuginBase::Panorama& pano, HuginBase::UIntSet images, GuiLevel guiLevel)
64 {
65  //remember gui level, only used by some PanoOperation's
66  m_guiLevel=guiLevel;
67  if(IsEnabled(pano, images, m_guiLevel))
68  {
69  return GetInternalCommand(parent,pano,images);
70  }
71  else
72  {
73  return NULL;
74  };
75 };
76 
78 {
79  return images.size()==1;
80 };
81 
83 {
84  return !images.empty();
85 };
86 
92 bool AddImageDialog(wxWindow* parent, std::vector<std::string>& files, bool& withRaws)
93 {
94  // get stored path
95  wxConfigBase* config = wxConfigBase::Get();
96  wxString path = config->Read("/actualPath", wxEmptyString);
97  wxFileDialog dlg(parent,_("Add images"),
98  path, wxEmptyString,
100  wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST | wxFD_PREVIEW, wxDefaultPosition);
101  dlg.SetDirectory(path);
102 
103  // remember the image extension
104  wxString img_ext;
105  if (config->HasEntry("lastImageType"))
106  {
107  img_ext = config->Read("lastImageType").c_str();
108  }
109  if (img_ext == "all images")
110  {
111  dlg.SetFilterIndex(0);
112  }
113  else
114  {
115  if (!withRaws)
116  {
117  if (img_ext == "jpg")
118  dlg.SetFilterIndex(1);
119  else if (img_ext == "tiff")
120  dlg.SetFilterIndex(2);
121  else if (img_ext == "png")
122  dlg.SetFilterIndex(3);
123  else if (img_ext == "hdr")
124  dlg.SetFilterIndex(4);
125  else if (img_ext == "exr")
126  dlg.SetFilterIndex(5);
127  else if (img_ext == "all files")
128  dlg.SetFilterIndex(6);
129  }
130  else
131  {
132  if (img_ext == "all raws")
133  dlg.SetFilterIndex(1);
134  else if (img_ext == "jpg")
135  dlg.SetFilterIndex(2);
136  else if (img_ext == "tiff")
137  dlg.SetFilterIndex(3);
138  else if (img_ext == "png")
139  dlg.SetFilterIndex(4);
140  else if (img_ext == "hdr")
141  dlg.SetFilterIndex(5);
142  else if (img_ext == "exr")
143  dlg.SetFilterIndex(6);
144  };
145  };
146 
147  // call the file dialog
148  if (dlg.ShowModal() == wxID_OK)
149  {
150  // get the selections
151  wxArrayString Pathnames;
152  dlg.GetPaths(Pathnames);
153 
154  // remember path for later
155 #ifdef __WXGTK__
156  //workaround a bug in GTK, see https://bugzilla.redhat.com/show_bug.cgi?id=849692 and http://trac.wxwidgets.org/ticket/14525
157  config->Write("/actualPath", wxPathOnly(Pathnames[0]));
158 #else
159  config->Write("/actualPath", dlg.GetDirectory());
160 #endif
161  // save the image extension
162  if (!withRaws)
163  {
164  switch (dlg.GetFilterIndex())
165  {
166  case 0: config->Write("lastImageType", "all images"); break;
167  case 1: config->Write("lastImageType", "jpg"); break;
168  case 2: config->Write("lastImageType", "tiff"); break;
169  case 3: config->Write("lastImageType", "png"); break;
170  case 4: config->Write("lastImageType", "hdr"); break;
171  case 5: config->Write("lastImageType", "exr"); break;
172  case 6: config->Write("lastImageType", "all files"); break;
173  };
174  }
175  else
176  {
177  switch (dlg.GetFilterIndex())
178  {
179  case 0: config->Write("lastImageType", "all images"); break;
180  case 1: config->Write("lastImageType", "all raws"); break;
181  case 2: config->Write("lastImageType", "jpg"); break;
182  case 3: config->Write("lastImageType", "tiff"); break;
183  case 4: config->Write("lastImageType", "png"); break;
184  case 5: config->Write("lastImageType", "hdr"); break;
185  case 6: config->Write("lastImageType", "exr"); break;
186  }
187  withRaws = dlg.GetFilterIndex() == 1;
188  };
189 
190  //check for forbidden/non working chars
191  wxArrayString invalidFiles;
192  for(unsigned int i=0;i<Pathnames.GetCount(); i++)
193  {
194  if(containsInvalidCharacters(Pathnames[i]))
195  {
196  invalidFiles.Add(Pathnames[i]);
197  };
198  };
199  if(!invalidFiles.empty())
200  {
201  ShowFilenameWarning(parent, invalidFiles);
202  return false;
203  }
204  for (unsigned int i=0; i<Pathnames.GetCount(); i++)
205  {
206  files.push_back((const char *)Pathnames[i].mb_str(HUGIN_CONV_FILENAME));
207  };
208  return true;
209  };
210  return false;
211 };
212 
214 {
215  return _("Add individual images...");
216 };
217 
219 {
220  std::vector<std::string> files;
221  bool withRaws = true;
222  if(AddImageDialog(parent, files, withRaws))
223  {
224  if(!files.empty())
225  {
226  if (withRaws)
227  {
228  if (files.size() == 1)
229  {
230  hugin_utils::MessageDialog message = hugin_utils::GetMessageDialog(_("You selected only one raw file. This is not recommended.\nAll raw files should be converted at once."),
231  _("Hugin"), wxICON_EXCLAMATION | wxYES_NO, parent);
232  message->SetYesNoLabels(_("Convert anyway"), _("Let me select several raw files"));
233  if (message->ShowModal() == wxID_NO)
234  {
235  // post new add image event to open dialog again
236  wxCommandEvent newAddEvent(wxEVT_COMMAND_BUTTON_CLICKED, XRCID("action_add_images"));
237  MainFrame::Get()->GetEventHandler()->AddPendingEvent(newAddEvent);
238  return NULL;
239  };
240  };
241  RawImportDialog dlg(parent, &pano, files);
242  // check that raw files are from same camera and that all can be read
243  if (dlg.CheckRawFiles())
244  {
245  // now show dialog
246  if (dlg.ShowModal() == wxID_OK)
247  {
248  return dlg.GetPanoCommand();
249  };
250  };
251  }
252  else
253  {
254  return new PanoCommand::wxAddImagesCmd(pano, files, m_preferredLensType);
255  };
256  };
257  };
258  return NULL;
259 };
260 
261 WX_DECLARE_STRING_HASH_MAP(time_t, StringToPointerHash);
262 WX_DECLARE_STRING_HASH_MAP(int, StringToFlagHash);
263 
264 time_t ReadExifTime(const char* filename)
265 {
266 #if defined EXIV2_VERSION && EXIV2_TEST_VERSION(0,27,99)
267  Exiv2::Image::UniquePtr image;
268 #else
269  Exiv2::Image::AutoPtr image;
270 #endif
271  try
272  {
273  image = Exiv2::ImageFactory::open(filename);
274  }
275  catch(...)
276  {
277  return 0;
278  }
279  if (image.get() == 0)
280  {
281  return 0;
282  }
283 
284  try
285  {
286  image->readMetadata();
287  }
288  catch (const Exiv2::Error& e)
289  {
290  std::cerr << "Exiv2: Error reading metadata (" << e.what() << ")" << std::endl;
291  return 0;
292  }
293  Exiv2::ExifData &exifData = image->exifData();
294  if (exifData.empty())
295  {
296  return 0;
297  }
298 
299  Exiv2::Exifdatum& tag = exifData["Exif.Image.DateTime"];
300  const std::string date_time = tag.toString();
301 
302  // Remember the file and a shutter timestamp.
303  struct tm when;
304  memset(&when, 0, sizeof(when));
305  when.tm_wday = -1;
306 
307  // parse into the tm_structure
308  const int a = sscanf(date_time.c_str(), "%d:%d:%d %d:%d:%d",
309  &when.tm_year, &when.tm_mon, &when.tm_mday,
310  &when.tm_hour, &when.tm_min, &when.tm_sec);
311 
312  if (a == 6)
313  {
314  when.tm_isdst = -1;
315  when.tm_mon -= 1; // Adjust for unix zero-based months
316  when.tm_year -= 1900; // Adjust for year starting at 1900
317  }
318  else
319  {
320  // Not in EXIF format
321  return 0;
322  }
323 
324  time_t stamp;
325  stamp = mktime(&when);
326  if (stamp == (time_t)(-1))
327  return 0;
328 
329  return stamp;
330 }
331 
333 {
334  explicit sortbytime(std::map<std::string, time_t> & h) : m_time(h) {};
335  bool operator()(const std::string & s1, const std::string & s2)
336  {
337  time_t t1 = m_time[s1];
338  time_t t2 = m_time[s2];
339  return t1 < t2;
340  };
341  std::map<std::string, time_t> & m_time;
342 };
343 
345 {
346  return _("Add time-series of images...");
347 };
348 
350 {
351  //load image if pano contains no images
352  std::vector<std::string> files;
353  if(pano.getNrOfImages()==0)
354  {
355  bool withRaws = false;
356  if(!AddImageDialog(parent,files, withRaws))
357  {
358  return NULL;
359  };
360  //just in case
361  if(files.empty())
362  {
363  return NULL;
364  };
365  }
366  else
367  {
368  for(size_t i=0;i<pano.getNrOfImages();i++)
369  {
370  files.push_back(pano.getImage(i).getFilename());
371  };
372  };
373 
374  DEBUG_TRACE("seeking similarly timed images");
375 
376  // Collect potential image-mates.
377  StringToPointerHash filenames;
378  StringToFlagHash preloaded;
379  for(size_t i=0;i<files.size();i++)
380  {
381  wxString file(files[i].c_str(), HUGIN_CONV_FILENAME);
382  preloaded[file] = 1;
383 
384  // Glob for all files of same type in same directory.
385  wxString path = ::wxPathOnly(file) + "/*";
386  file = ::wxFindFirstFile(path);
387  while (!file.IsEmpty())
388  {
389  // Associated with a NULL dummy timestamp for now.
390  if(vigra::isImage(files[i].c_str()))
391  {
392  filenames[file] = 0;
393  };
394  file = ::wxFindNextFile();
395  }
396  }
397 
398  DEBUG_INFO("found " << filenames.size() << " candidate files to search.");
399 
400  // For each globbed or loaded file,
401  StringToPointerHash::iterator found;
402  std::map<std::string, time_t> timeMap;
403  for (found = filenames.begin(); found != filenames.end(); ++found)
404  {
405  wxString file = found->first;
406  // Check the time if it's got a camera EXIF timestamp.
407  time_t stamp = ReadExifTime(file.mb_str(HUGIN_CONV_FILENAME));
408  if (stamp)
409  {
410  filenames[file] = stamp;
411  timeMap[(const char *)file.mb_str(HUGIN_CONV_FILENAME)] = stamp;
412  }
413  }
414 
415  //TODO: sorting the filenames keys by timestamp would be useful
416  int maxtimediff = wxConfigBase::Get()->Read("CaptureTimeSpan", HUGIN_CAPTURE_TIMESPAN);
417  // For each timestamped file,
418  for (found = filenames.begin(); found != filenames.end(); ++found)
419  {
420  wxString recruit = found->first;
421  if (preloaded[recruit] == 1)
422  continue;
423  time_t pledge = filenames[recruit];
424  if (!pledge)
425  continue;
426 
427  // For each other image already loaded,
428  for(size_t i=0;i<files.size();i++)
429  {
430  wxString file(files[i].c_str(), HUGIN_CONV_FILENAME);
431  if (file == recruit)
432  continue;
433 
434  // If it is within threshold time,
435  time_t stamp = filenames[file];
436  if (abs((int)(pledge - stamp)) < maxtimediff)
437  {
438  // Load this file, and remember it.
439  DEBUG_TRACE("Recruited " << recruit.mb_str(wxConvLocal));
440  std::string file = (const char *)recruit.mb_str(HUGIN_CONV_FILENAME);
441  files.push_back(file);
442  // Don't recruit it again.
443  filenames[recruit] = 0;
444  break;
445  }
446  }
447  }
448 
449  if(!files.empty())
450  {
451  // sort files by date
452  sortbytime spred(timeMap);
453  sort(files.begin(), files.end(), spred);
454  // Load all of the named files.
455  return new PanoCommand::wxAddImagesCmd(pano,files);
456  }
457  else
458  {
459  hugin_utils::HuginMessageBox(_("No matching images found."), _("Hugin"), wxOK | wxICON_INFORMATION, parent);
460  return NULL;
461  };
462 };
463 
465 {
466  return _("Manipulate image variables...");
467 }
468 
470 {
471  ImageVariablesExpressionDialog dlg(parent, &pano);
472  if (dlg.ShowModal() == wxID_OK)
473  {
474  const std::string expression = dlg.GetExpression();
475  if (!expression.empty())
476  {
477  return new PanoCommand::UpdateVariablesByParseExpression(pano, expression);
478  };
479  };
480  return NULL;
481 }
482 
484 {
485  return pano.getNrOfImages() > 0 && guiLevel >= GuiLevel::GUI_ADVANCED;
486 }
487 
489 {
490  return _("Remove selected image(s)");
491 };
492 
494 {
495  //remove images from cache
496  for (HuginBase::UIntSet::iterator it = images.begin(); it != images.end(); ++it)
497  {
498  HuginBase::ImageCache::getInstance().removeImage(pano.getImage(*it).getFilename());
499  }
500  return new PanoCommand::RemoveImagesCmd(pano, images);
501 };
502 
504 {
505  return _("Anchor this image for position");
506 };
507 
509 {
511  opt.optimizeReferenceImage = *(images.begin());
512  return new PanoCommand::SetPanoOptionsCmd(pano,opt);
513 };
514 
516 {
517  return _("Anchor this image for exposure");
518 };
519 
521 {
523  opt.colorReferenceImage = *(images.begin());
524  return new PanoCommand::SetPanoOptionsCmd(pano, opt);
525 };
526 
528 {
529  if(pano.getNrOfImages()==0 || images.empty())
530  {
531  return false;
532  }
533  else
534  {
535  HuginBase::StandardImageVariableGroups variable_groups(pano);
536  return variable_groups.getLenses().getNumberOfParts()<pano.getNrOfImages();
537  };
538 };
539 
541 {
542  return _("New lens");
543 };
544 
546 {
548 };
549 
551 {
552  if(pano.getNrOfImages()==0 || images.empty())
553  {
554  return false;
555  }
556  else
557  {
558  //project must have more than 1 lens before you can assign another lens number
559  HuginBase::StandardImageVariableGroups variableGroups(pano);
560  return variableGroups.getLenses().getNumberOfParts() > 1;
561  };
562 };
563 
565 {
566  return _("Change lens...");
567 };
568 
570 {
571  HuginBase::StandardImageVariableGroups variable_groups(pano);
572  long nr = wxGetNumberFromUser(
573  _("Enter new lens number"),
574  _("Lens number"),
575  _("Change lens number"), 0, 0,
576  variable_groups.getLenses().getNumberOfParts()-1
577  );
578  if (nr >= 0)
579  {
580  // user accepted
581  // check that image size are the same
582  const vigra::Size2D lensImgSize = variable_groups.getLens(nr).getImageSize();
583  for (const auto& img : images)
584  {
585  if (pano.getImage(img).getSize() != lensImgSize)
586  {
587  hugin_utils::HuginMessageBox(wxString::Format(_("Selected images and selected lens have different sizes. All images of the same lens should have the same size.\n\nImage %d has size %dx%d, while lens %d has images with size of %dx%d pixel."),
588  img, pano.getImage(img).getWidth(), pano.getImage(img).getHeight(), nr, lensImgSize.width(), lensImgSize.height()),
589  _("Hugin"), wxICON_EXCLAMATION | wxOK, wxGetActiveWindow());
590  return NULL;
591  };
592  };
594  }
595  else
596  {
597  return NULL;
598  };
599 };
600 
602 {
603  m_fromDatabase = fromDatabase;
604 };
605 
607 {
608  if (m_fromDatabase)
609  {
610  return _("Load lens from lens database");
611  }
612  else
613  {
614  return _("Load lens from ini file");
615  };
616 };
617 
619 {
620  HuginBase::StandardImageVariableGroups variable_groups(pano);
621  HuginBase::UIntSet lensImages = variable_groups.getLenses().getPartsSet()[variable_groups.getLenses().getPartNumber(*images.begin())];
622  if (!m_fromDatabase && images.size() == 1 && lensImages.size() > 1)
623  {
624  // database is always linking the parameters, so no need to ask user
625  if (hugin_utils::HuginMessageBox(_("You selected only one image.\nShould the loaded parameters be applied to all images with the same lens?"), _("Hugin"), wxICON_QUESTION | wxYES_NO, wxGetActiveWindow()) == wxYES)
626  {
627  // get all images with the current lens.
628  std::copy(lensImages.begin(), lensImages.end(), std::inserter(images, images.end()));
629  };
630  };
631  vigra::Size2D sizeImg0=pano.getImage(*(images.begin())).getSize();
632  //check if all images have the same size
633  bool differentImageSize=false;
634  for(HuginBase::UIntSet::const_iterator it=images.begin();it!=images.end() && !differentImageSize;++it)
635  {
636  differentImageSize=(pano.getImage(*it).getSize()!=sizeImg0);
637  };
638  if(differentImageSize)
639  {
640  if (hugin_utils::HuginMessageBox(_("You selected images with different sizes.\nApply lens parameter file can result in unwanted results.\nApply settings anyway?"), _("Hugin"), wxICON_QUESTION | wxYES_NO, wxGetActiveWindow()) == wxNO)
641  {
642  return NULL;
643  };
644  };
645  PanoCommand::PanoCommand* cmd=NULL;
646  bool isLoaded=false;
647  if (m_fromDatabase)
648  {
649  isLoaded=ApplyLensDBParameters(parent,&pano,images,cmd);
650  }
651  else
652  {
653  isLoaded=ApplyLensParameters(parent,&pano,images,cmd);
654  };
655  if(isLoaded)
656  {
657  return cmd;
658  }
659  else
660  {
661  return NULL;
662  }
663 };
664 
666 {
667  m_database = toDatabase;
668 };
669 
671 {
672  if (m_database)
673  {
674  return _("Save lens parameters to lens database");
675  }
676  else
677  {
678  return _("Save lens to ini file");
679  };
680 };
681 
683 {
684  unsigned int imgNr = *(images.begin());
685  if (m_database)
686  {
687  SaveLensParameters(parent, pano.getImage(imgNr));
688  }
689  else
690  {
691  SaveLensParametersToIni(parent, &pano, images);
692  };
693  return NULL;
694 };
695 
697 {
698  return _("Remove control points");
699 };
700 
702 {
703  return pano.getNrOfImages()>0 && pano.getNrOfCtrlPoints()>0;
704 };
705 
707 {
708  HuginBase::UIntSet selImages;
709  if(images.empty())
710  {
711  fill_set(selImages,0,pano.getNrOfCtrlPoints()-1);
712  }
713  else
714  {
715  selImages=images;
716  };
717  HuginBase::UIntSet cpsToDelete;
718  const HuginBase::CPVector & cps = pano.getCtrlPoints();
719  for (HuginBase::CPVector::const_iterator it = cps.begin(); it != cps.end(); ++it)
720  {
721  if (set_contains(selImages, (*it).image1Nr) && set_contains(selImages, (*it).image2Nr) )
722  {
723  cpsToDelete.insert(it - cps.begin());
724  }
725  }
726  if(cpsToDelete.empty())
727  {
728  hugin_utils::HuginMessageBox(_("Selected images have no control points."), _("Hugin"), wxICON_EXCLAMATION | wxOK, wxGetActiveWindow());
729  return NULL;
730  };
731  if (hugin_utils::HuginMessageBox(wxString::Format(_("Really delete %lu control points?"), (unsigned long int) cpsToDelete.size()),
732  _("Hugin"), wxICON_QUESTION | wxYES_NO, wxGetActiveWindow()) == wxYES)
733  {
734  return new PanoCommand::RemoveCtrlPointsCmd(pano, cpsToDelete );
735  }
736  else
737  {
738  return NULL;
739  };
740 };
741 
743 {
744  return _("Clean control points");
745 };
746 
748 {
749  return pano.getNrOfCtrlPoints()>2;
750 };
751 
753 {
755  ProgressReporterDialog progress(0, _("Cleaning Control points"), _("Checking pairwise"), parent);
756 
757  HuginBase::UIntSet removedCPs=getCPoutsideLimit_pair(pano, progress, 2.0);
758 
759  //create a copy to work with
760  //we copy remaining control points to new pano object for running second step
761  HuginBase::Panorama newPano=pano.duplicate();
762  std::map<size_t,size_t> cpMap;
763  HuginBase::CPVector allCPs=newPano.getCtrlPoints();
764  HuginBase::CPVector firstCleanedCP;
765  size_t j=0;
766  for(size_t i=0;i<allCPs.size();i++)
767  {
768  HuginBase::ControlPoint cp = allCPs[i];
769  if (cp.mode == HuginBase::ControlPoint::X_Y && !set_contains(removedCPs, i))
770  {
771  firstCleanedCP.push_back(cp);
772  cpMap[j++]=i;
773  };
774  };
775  newPano.setCtrlPoints(firstCleanedCP);
776 
777  //check for unconnected images
778  HuginGraph::ImageGraph graph(newPano);
779  if (!progress.updateDisplayValue(_("Checking whole project")))
780  {
781  return NULL;
782  }
783  if (graph.IsConnected())
784  {
785  //now run the second step
786  HuginBase::UIntSet removedCP2=getCPoutsideLimit(newPano, 2.0);
787  if(!removedCP2.empty())
788  {
789  for(HuginBase::UIntSet::const_iterator it=removedCP2.begin();it!=removedCP2.end();++it)
790  {
791  removedCPs.insert(cpMap[*it]);
792  };
793  };
794  }
796  if (!progress.updateDisplay(_("Finished cleaning")))
797  {
798  return NULL;
799  }
800  if (!removedCPs.empty())
801  {
802  hugin_utils::HuginMessageBox(wxString::Format(_("Removed %lu control points"), (unsigned long int)removedCPs.size()), _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
803  return new PanoCommand::RemoveCtrlPointsCmd(pano,removedCPs);
804  };
805  return NULL;
806 };
807 
809 {
810  return _("Remove control points on clouds");
811 };
812 
814 {
815  ProgressReporterDialog progress(images.size() + 2, _("Running Celeste"), _("Running Celeste"), parent);
816  progress.updateDisplay(_("Loading model file"));
817 
818  struct celeste::svm_model* model=MainFrame::Get()->GetSVMModel();
819  if (model == NULL || !progress.updateDisplay(_("Loading images")))
820  {
821  return NULL;
822  };
823 
824  // Get Celeste parameters
825  wxConfigBase *cfg = wxConfigBase::Get();
826  // SVM threshold
828  cfg->Read("/Celeste/Threshold", &threshold, HUGIN_CELESTE_THRESHOLD);
829 
830  // Mask resolution - 1 sets it to fine
831  bool t = (cfg->Read("/Celeste/Filter", HUGIN_CELESTE_FILTER) == 0);
832  int radius=(t)?10:20;
833  DEBUG_TRACE("Running Celeste");
834 
835  HuginBase::UIntSet cpsToRemove;
836  for (HuginBase::UIntSet::const_iterator it=images.begin(); it!=images.end(); ++it)
837  {
838  // Image to analyse
840  if(cps.empty())
841  {
842  if (!progress.updateDisplayValue())
843  {
844  return NULL;
845  };
846  continue;
847  };
849  vigra::UInt16RGBImage in;
850  if(img->image16->width()>0)
851  {
852  in.resize(img->image16->size());
853  vigra::omp::copyImage(srcImageRange(*(img->image16)),destImage(in));
854  }
855  else
856  {
857  HuginBase::ImageCache::ImageCacheRGB8Ptr im8 = img->get8BitImage();
858  in.resize(im8->size());
859  vigra::omp::transformImage(srcImageRange(*im8),destImage(in),vigra::functor::Arg1()*vigra::functor::Param(65535/255));
860  };
861  if (!img->iccProfile->empty())
862  {
863  HuginBase::Color::ApplyICCProfile(in, *(img->iccProfile), TYPE_RGB_16);
864  };
865  if (!progress.updateDisplay(_("Running Celeste")))
866  {
867  return NULL;
868  };
869  HuginBase::UIntSet cloudCP=celeste::getCelesteControlPoints(model,in,cps,radius,threshold,800);
870  in.resize(0,0);
871  if (!progress.updateDisplay())
872  {
873  return NULL;
874  };
875  if(!cloudCP.empty())
876  {
877  for(HuginBase::UIntSet::const_iterator it2=cloudCP.begin();it2!=cloudCP.end(); ++it2)
878  {
879  cpsToRemove.insert(*it2);
880  };
881  };
882  if (!progress.updateDisplayValue(_("Loading images")))
883  {
884  return NULL;
885  };
886  };
887 
888  if (!progress.updateDisplayValue())
889  {
890  return NULL;
891  }
892  if (!cpsToRemove.empty())
893  {
894  hugin_utils::HuginMessageBox(wxString::Format(_("Removed %lu control points"), (unsigned long int) cpsToRemove.size()), _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
895  return new PanoCommand::RemoveCtrlPointsCmd(pano,cpsToRemove);
896  }
897  else
898  {
899  return NULL;
900  };
901 };
902 
904 {
905  m_resetMode=newResetMode;
910  m_resetExposure=0;
912  {
913  m_resetExposure=3;
914  };
916  m_resetColor = 0;
918  {
919  m_resetColor=1;
920  };
922 };
923 
925 {
926  switch(m_resetMode)
927  {
928  case RESET_DIALOG:
929  case RESET_DIALOG_LENS:
931  return _("Reset user defined...");
932  break;
933  case RESET_POSITION:
934  return _("Reset positions");
935  break;
936  case RESET_TRANSLATION:
937  return _("Reset translation parameters");
938  break;
939  case RESET_LENS:
940  return _("Reset lens parameters");
941  break;
942  case RESET_PHOTOMETRICS:
943  return _("Reset photometric parameters");
944  };
945  return wxEmptyString;
946 };
947 
949 {
950  switch(m_resetMode)
951  {
952  case RESET_TRANSLATION:
953  return guiLevel>=GUI_EXPERT && pano.getNrOfImages()>0;
954  break;
955  default:
956  return pano.getNrOfImages()>0;
957  };
958 };
959 
961 {
963  {
964  if(!ShowDialog(parent))
965  {
966  return NULL;
967  };
968  };
969  if(images.empty())
970  {
971  fill_set(images,0,pano.getNrOfImages()-1);
972  };
973  double redBalanceAnchor = pano.getImage(pano.getOptions().colorReferenceImage).getExifRedBalance();
974  double blueBalanceAnchor = pano.getImage(pano.getOptions().colorReferenceImage).getExifBlueBalance();
975  if(fabs(redBalanceAnchor)<1e-2)
976  {
977  redBalanceAnchor=1;
978  };
979  if(fabs(blueBalanceAnchor)<1e-2)
980  {
981  blueBalanceAnchor=1;
982  };
983 
985  for(HuginBase::UIntSet::const_iterator it = images.begin(); it != images.end(); ++it)
986  {
987  unsigned int imgNr = *it;
988  HuginBase::VariableMap ImgVars = pano.getImageVariables(imgNr);
989  if(m_resetPos)
990  {
991  map_get(ImgVars,"y").setValue(0);
992  map_get(ImgVars,"p").setValue(0);
993  map_get(ImgVars,"r").setValue(pano.getSrcImage(imgNr).getExifOrientation());
994  map_get(ImgVars,"TrX").setValue(0);
995  map_get(ImgVars,"TrY").setValue(0);
996  map_get(ImgVars,"TrZ").setValue(0);
997  map_get(ImgVars,"Tpy").setValue(0);
998  map_get(ImgVars,"Tpp").setValue(0);
999  };
1000  if(m_resetTranslation)
1001  {
1002  map_get(ImgVars,"TrX").setValue(0);
1003  map_get(ImgVars,"TrY").setValue(0);
1004  map_get(ImgVars,"TrZ").setValue(0);
1005  map_get(ImgVars,"Tpy").setValue(0);
1006  map_get(ImgVars,"Tpp").setValue(0);
1007  };
1008  HuginBase::SrcPanoImage srcImg = pano.getSrcImage(imgNr);
1009  if(m_resetHFOV)
1010  {
1011  double focalLength=srcImg.getExifFocalLength();
1012  double cropFactor=srcImg.getExifCropFactor();
1013  if(focalLength!=0 && cropFactor!=0)
1014  {
1015  double newHFOV=HuginBase::SrcPanoImage::calcHFOV(srcImg.getProjection(), focalLength, cropFactor, srcImg.getSize());
1016  if(newHFOV!=0)
1017  {
1018  map_get(ImgVars,"v").setValue(newHFOV);
1019  };
1020  };
1021  };
1022  if(m_resetLens)
1023  {
1024  map_get(ImgVars,"a").setValue(0);
1025  map_get(ImgVars,"b").setValue(0);
1026  map_get(ImgVars,"c").setValue(0);
1027  map_get(ImgVars,"d").setValue(0);
1028  map_get(ImgVars,"e").setValue(0);
1029  map_get(ImgVars,"g").setValue(0);
1030  map_get(ImgVars,"t").setValue(0);
1031  };
1032  if(m_resetExposure>0)
1033  {
1034  if(m_resetExposure==1 || m_resetExposure==3)
1035  {
1036  //reset to exif value
1037  double eV=srcImg.calcExifExposureValue();
1038  if ((m_resetExposure == 1 && eV != 0) || m_resetExposure == 3)
1039  {
1040  map_get(ImgVars,"Eev").setValue(eV);
1041  }
1042  }
1043  else
1044  {
1045  //reset to zero
1046  map_get(ImgVars,"Eev").setValue(0);
1047  };
1048  };
1049  if(m_resetColor>0)
1050  {
1051  if(m_resetColor==1)
1052  {
1053  double redBal=1;
1054  double blueBal=1;
1055  const HuginBase::SrcPanoImage& img=pano.getImage(imgNr);
1057  // use EXIF Red/BlueBalance data only if image and anchor image are from the same camera
1058  if(img.getExifMake() == anchor.getExifMake() &&
1059  img.getExifModel() == anchor.getExifModel())
1060  {
1061  redBal=fabs(img.getExifRedBalance()/redBalanceAnchor);
1062  if(redBal<1e-2)
1063  {
1064  redBal=1;
1065  };
1066  blueBal=fabs(img.getExifBlueBalance()/blueBalanceAnchor);
1067  if(blueBal<1e-2)
1068  {
1069  blueBal=1;
1070  };
1071  };
1072  map_get(ImgVars,"Er").setValue(redBal);
1073  map_get(ImgVars,"Eb").setValue(blueBal);
1074  }
1075  else
1076  {
1077  map_get(ImgVars,"Er").setValue(1);
1078  map_get(ImgVars,"Eb").setValue(1);
1079  };
1080  };
1081  if(m_resetVignetting)
1082  {
1083  map_get(ImgVars,"Vb").setValue(0);
1084  map_get(ImgVars,"Vc").setValue(0);
1085  map_get(ImgVars,"Vd").setValue(0);
1086  map_get(ImgVars,"Vx").setValue(0);
1087  map_get(ImgVars,"Vy").setValue(0);
1088 
1089  };
1091  {
1092  map_get(ImgVars,"Ra").setValue(0);
1093  map_get(ImgVars,"Rb").setValue(0);
1094  map_get(ImgVars,"Rc").setValue(0);
1095  map_get(ImgVars,"Rd").setValue(0);
1096  map_get(ImgVars,"Re").setValue(0);
1097  };
1098  vars.push_back(ImgVars);
1099  };
1100  std::vector<PanoCommand::PanoCommand *> reset_commands;
1101  reset_commands.push_back(
1102  new PanoCommand::UpdateImagesVariablesCmd(pano, images, vars)
1103  );
1104  if(m_resetExposure>0)
1105  {
1106  //reset panorama output exposure value
1107  reset_commands.push_back(new PanoCommand::ResetToMeanExposure(pano));
1108  };
1109  return new PanoCommand::CombinedPanoCommand(pano, reset_commands);
1110 };
1111 
1112 bool ResetOperation::ShowDialog(wxWindow* parent)
1113 {
1114  ResetDialog reset_dlg(parent, m_guiLevel);
1115  bool checkGeometric;
1116  bool checkPhotometric;
1117  switch(m_resetMode)
1118  {
1119  case RESET_DIALOG_LENS:
1120  reset_dlg.LimitToGeometric();
1121  checkGeometric=true;
1122  checkPhotometric=false;
1123  break;
1125  reset_dlg.LimitToPhotometric();
1126  checkGeometric=false;
1127  checkPhotometric=true;
1128  break;
1129  case RESET_DIALOG:
1130  default:
1131  checkGeometric=true;
1132  checkPhotometric=true;
1133  break;
1134  };
1135  if(reset_dlg.ShowModal()==wxID_OK)
1136  {
1137  if(checkGeometric)
1138  {
1139  m_resetPos=reset_dlg.GetResetPos();
1141  m_resetHFOV=reset_dlg.GetResetFOV();
1142  m_resetLens=reset_dlg.GetResetLens();
1143  };
1144  if(checkPhotometric)
1145  {
1146  if(reset_dlg.GetResetExposure())
1147  {
1148  if(reset_dlg.GetResetExposureToExif())
1149  {
1150  m_resetExposure=1;
1151  }
1152  else
1153  {
1154  m_resetExposure=2;
1155  };
1156  }
1157  else
1158  {
1159  m_resetExposure=0;
1160  };
1162  if(reset_dlg.GetResetColor())
1163  {
1164  if(reset_dlg.GetResetColorToExif())
1165  {
1166  m_resetColor=1;
1167  }
1168  else
1169  {
1170  m_resetColor=2;
1171  };
1172  }
1173  else
1174  {
1175  m_resetColor=0;
1176  };
1178  };
1179  return true;
1180  }
1181  else
1182  {
1183  return false;
1184  };
1185 };
1186 
1188 {
1189  if(pano.getNrOfImages()==0 || images.empty())
1190  {
1191  return false;
1192  }
1193  else
1194  {
1195  HuginBase::StandardImageVariableGroups variable_groups(pano);
1196  return variable_groups.getStacks().getNumberOfParts()<pano.getNrOfImages();
1197  };
1198 };
1199 
1201 {
1202  return _("New stack");
1203 };
1204 
1206 {
1208 };
1209 
1211 {
1212  if(pano.getNrOfImages()==0 || images.empty())
1213  {
1214  return false;
1215  }
1216  else
1217  {
1218  //project must have more than 1 stack before you can assign another stack number
1219  HuginBase::StandardImageVariableGroups variableGroups(pano);
1220  return variableGroups.getStacks().getNumberOfParts() > 1;
1221  };
1222 };
1223 
1225 {
1226  return _("Change stack...");
1227 };
1228 
1230 {
1231  HuginBase::StandardImageVariableGroups variable_groups(pano);
1232  long nr = wxGetNumberFromUser(
1233  _("Enter new stack number"),
1234  _("Stack number"),
1235  _("Change stack number"), 0, 0,
1236  variable_groups.getStacks().getNumberOfParts()-1
1237  );
1238  if (nr >= 0)
1239  {
1240  // user accepted
1241  // check that image size are the same
1242  const vigra::Size2D stackImgSize = pano.getImage(*variable_groups.getStacks().getPartsSet()[nr].begin()).getSize();
1243  for (const auto& img : images)
1244  {
1245  if (pano.getImage(img).getSize() != stackImgSize)
1246  {
1247  hugin_utils::HuginMessageBox(wxString::Format(_("Selected images and selected stack have different sizes. All images of the same stack should have the same size.\n\nImage %d has size %dx%d, while stack %d has images with size of %dx%d pixel."),
1248  img, pano.getImage(img).getWidth(), pano.getImage(img).getHeight(), nr, stackImgSize.width(), stackImgSize.height()),
1249  _("Hugin"), wxICON_EXCLAMATION | wxOK, wxGetActiveWindow());
1250  return NULL;
1251  };
1252  };
1253 
1255  }
1256  else
1257  {
1258  return NULL;
1259  };
1260 };
1261 
1263 {
1264  return pano.getNrOfImages()>1;
1265 };
1266 
1268 {
1269  return _("Set stack size...");
1270 };
1271 
1273 {
1274  wxConfigBase* cfg = wxConfigBase::Get();
1275  wxDialog dlg;
1276  wxXmlResource::Get()->LoadDialog(&dlg, parent, "stack_size_dialog");
1277  wxSpinCtrl* stackSpin = XRCCTRL(dlg, "stack_size_spinctrl", wxSpinCtrl);
1278  stackSpin->SetRange(1, pano.getNrOfImages());
1279  size_t oldStackSize = cfg->Read("/StackDialog/StackSize", 3);
1280  oldStackSize = std::min(oldStackSize, pano.getNrOfImages());
1281  stackSpin->SetValue(oldStackSize);
1282  wxCheckBox* linkCheckBox = XRCCTRL(dlg, "stack_size_link_checkbox", wxCheckBox);
1283  linkCheckBox->SetValue(cfg->Read("/StackDialog/LinkPosition", true) != 0l);
1284  if (dlg.ShowModal() != wxID_OK)
1285  {
1286  // user has canceled dialog
1287  return NULL;
1288  };
1289  long stackSize = stackSpin->GetValue();
1290  bool linkPosition = linkCheckBox->IsChecked();
1291  cfg->Write("/StackDialog/StackSize", stackSize);
1292  cfg->Write("/StackDialog/LinkPosition", linkPosition);
1293  if(stackSize<0)
1294  {
1295  return NULL;
1296  };
1297  std::vector<PanoCommand::PanoCommand *> commands;
1298  HuginBase::StandardImageVariableGroups variable_groups(pano);
1299  if(variable_groups.getStacks().getNumberOfParts()<pano.getNrOfImages())
1300  {
1301  // first remove all existing stacks
1302  for(size_t i=1; i<pano.getNrOfImages(); i++)
1303  {
1304  HuginBase::UIntSet imgs;
1305  imgs.insert(i);
1307  };
1308  };
1309 
1310  if (stackSize > 1)
1311  {
1312  size_t stackNr=0;
1313  size_t imgNr=0;
1314  while(imgNr<pano.getNrOfImages())
1315  {
1316  HuginBase::UIntSet imgs;
1317  for(size_t i=0; i<stackSize && imgNr<pano.getNrOfImages(); i++)
1318  {
1319  imgs.insert(imgNr);
1320  imgNr++;
1321  };
1323  stackNr++;
1324  };
1325  };
1326 
1327  if (!linkPosition && stackSize > 1)
1328  {
1329  // unlink image position
1330  HuginBase::UIntSet imgs;
1331  fill_set(imgs, 0, pano.getNrOfImages() - 1);
1332  std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> variables;
1333  variables.insert(HuginBase::ImageVariableGroup::IVE_Yaw);
1334  variables.insert(HuginBase::ImageVariableGroup::IVE_Pitch);
1335  variables.insert(HuginBase::ImageVariableGroup::IVE_Roll);
1336  variables.insert(HuginBase::ImageVariableGroup::IVE_X);
1337  variables.insert(HuginBase::ImageVariableGroup::IVE_Y);
1338  variables.insert(HuginBase::ImageVariableGroup::IVE_Z);
1339  variables.insert(HuginBase::ImageVariableGroup::IVE_TranslationPlaneYaw);
1340  variables.insert(HuginBase::ImageVariableGroup::IVE_TranslationPlanePitch);
1341  commands.push_back(new PanoCommand::ChangePartImagesLinkingCmd(pano, imgs, variables, false, HuginBase::StandardImageVariableGroups::getStackVariables()));
1342  };
1343  return new PanoCommand::CombinedPanoCommand(pano, commands);
1344 };
1345 
1351 
1353 {
1354  return &PanoOpImages;
1355 };
1356 
1358 {
1359  return &PanoOpLens;
1360 };
1361 
1363 {
1364  return &PanoOpStacks;
1365 };
1366 
1368 {
1369  return &PanoOpControlPoints;
1370 };
1371 
1373 {
1374  return &PanoOpReset;
1375 };
1376 
1378 {
1379  PanoOpImages.push_back(new AddImageOperation());
1380  PanoOpImages.push_back(new AddImagesSeriesOperation());
1381  PanoOpImages.push_back(new RemoveImageOperation());
1382  PanoOpImages.push_back(new ChangeAnchorImageOperation());
1385 
1386  PanoOpLens.push_back(new NewLensOperation());
1387  PanoOpLens.push_back(new ChangeLensOperation());
1388  PanoOpLens.push_back(new LoadLensOperation(false));
1389  PanoOpLens.push_back(new LoadLensOperation(true));
1390  PanoOpLens.push_back(new SaveLensOperation(false));
1391  PanoOpLens.push_back(new SaveLensOperation(true));
1392 
1393  PanoOpStacks.push_back(new NewStackOperation());
1394  PanoOpStacks.push_back(new ChangeStackOperation());
1395  PanoOpStacks.push_back(new AssignStacksOperation());
1396 
1398  PanoOpControlPoints.push_back(new CelesteOperation());
1400 
1406 
1407 };
1408 
1409 
1411 {
1412  for(size_t i=0; i<vec.size(); i++)
1413  {
1414  delete vec[i];
1415  }
1416  vec.clear();
1417 };
1418 
1420 {
1426 };
1427 
1428 } //namespace
#define DEBUG_INFO(msg)
Definition: utils.h:69
Base class for all panorama commands.
Definition: Command.h:38
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
bool GetResetLens()
Return TRUE, when user selected &quot;Reset lens&quot;.
static const std::set< ConstImageVariableGroup::ImageVariableEnum > & getLensVariables()
Get the set of lens image variables.
vigra::Size2D getImageSize() const
get the image size, in pixels
Definition: Lens.h:89
update variables of a group of images
Definition: PanoCommand.h:174
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
PanoOperation to change anchor image.
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
PanoOperation to clean control points with Celeste.
bool updateDisplayValue(const wxString &message, const wxString &filename=wxEmptyString)
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
unsigned int getPartNumber(unsigned int imageNr) const
Get a part number from an image number.
Change the linking of some variables across parts of an ImageVariableGroup containing some specified ...
Definition: PanoCommand.h:524
bool AddImageDialog(wxWindow *parent, std::vector< std::string > &files, bool &withRaws)
small function to show add image dialog
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
Definition: Panorama.cpp:1620
Dialog for reset panorama settings.
Definition: ResetDialog.h:44
PanoOperation to change exposure anchor image.
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
PanoOperation to save lens to ini file or database.
PanoOperation to assign new stack.
bool ApplyLensDBParameters(wxWindow *parent, HuginBase::Panorama *pano, HuginBase::UIntSet images, PanoCommand::PanoCommand *&cmd)
loads the lens parameters from lens database and create approbiate PanoCommand::PanoCommand to apply ...
Definition: wxLensDB.cpp:272
static PanoOperationVector PanoOpImages
WXIMPEX bool ApplyLensParameters(wxWindow *parent, HuginBase::Panorama *pano, HuginBase::UIntSet images, PanoCommand::PanoCommand *&command)
applies lens parameter from user selected file to pano using GlobalCmdHist
#define HUGIN_CONV_FILENAME
Definition: platform.h:40
ImageVariableGroup & getStacks()
Get the ImageVariableGroup representing the group of stack variables.
std::unique_ptr< wxMessageDialogBase > MessageDialog
Definition: wxutils.h:87
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
#define DEBUG_TRACE(msg)
Definition: utils.h:67
void registerPTWXDlgFcn()
Definition: PTWXDlg.cpp:178
some helper classes for graphes
bool IsConnected()
check if all images are connected
Definition: ImageGraph.cpp:128
PanoOperation to assigns stacks.
bool GetResetExposure()
Return TRUE, when user selected &quot;Reset exposure&quot;.
static PanoOperationVector PanoOpReset
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
PanoOperation to assign new lens.
ResetOperation(ResetMode newResetMode)
void deregisterPTWXDlgFcn()
Definition: PTWXDlg.cpp:185
std::size_t getNrOfCtrlPoints() const
number of control points
Definition: Panorama.h:306
void LimitToPhotometric()
limits the displayed parameters to photometric parameters
bool set_contains(const _Container &c, const typename _Container::key_type &key)
Definition: stl_utils.h:74
double calcExifExposureValue()
calculate exposure value
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition: Panorama.h:319
int getHeight() const
Get the height of the image in pixels.
Definition: SrcPanoImage.h:276
void GeneratePanoOperationVector()
generates the PanoOperationVector for context menu
static ImageCache & getInstance()
get the global ImageCache object
Definition: ImageCache.cpp:258
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
remove several control points
Definition: PanoCommand.h:307
wxString GetFileDialogImageAndRawFilters()
return filter for image and raw files, needed by file open dialog
Definition: platform.cpp:89
represents a control point
Definition: ControlPoint.h:38
Definition of PanoOperation class.
bool GetResetFOV()
Return TRUE, when user selected &quot;Reset FOV&quot;.
static PanoOperationVector PanoOpStacks
MessageDialog GetMessageDialog(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition: wxutils.cpp:212
Definition of ResetDialog class.
void ShowFilenameWarning(wxWindow *parent, const wxArrayString filelist)
shows a dialog about filename with invalid characters, all names in filelist will be show in list ...
Definition: platform.cpp:523
bool GetResetExposureToExif()
Return TRUE, when user selected &quot;Reset exposure to EXIF&quot;, Return FALSE, when user selected &quot;Reset exp...
Dialog for raw import.
Definition: RawImport.h:34
void SaveLensParametersToIni(wxWindow *parent, HuginBase::Panorama *pano, const HuginBase::UIntSet images)
saves the lens parameters to ini files, provides all necessary dialogs
Definition: LensTools.cpp:412
PanoCommand to combine other PanoCommands.
Definition: PanoCommand.h:39
PanoOperation to remove selected images.
Panorama duplicate() const
duplicate the panorama
Definition: Panorama.cpp:1653
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
set the panorama options
Definition: PanoCommand.h:418
bool GetResetColor()
Return TRUE, when user selected &quot;Reset color&quot;.
std::vector< VariableMap > VariableMapVector
options getSize().area()) int wxCALLBACK SortFieldOfViewAscending(wxIntPtr item1
algorithms for remove control points by statistic method
Model for a panorama.
Definition: Panorama.h:152
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
bool GetResetVignetting()
Return TRUE, when user selected &quot;Reset vignetting&quot;.
#define HUGIN_CAPTURE_TIMESPAN
UIntSetVector getPartsSet() const
return a vector which contains a HuginBase::UIntSet for each group with the corresponding images numb...
Definition of dialog and functions to import RAW images to project file.
std::shared_ptr< Entry > EntryPtr
a shared pointer to the entry
Definition: ImageCache.h:112
Make a new part in a ImageVariableGroup for a set of images, given the variables that make up the gro...
Definition: PanoCommand.h:591
std::map< std::string, time_t > & m_time
const VariableMap getImageVariables(unsigned int imgNr) const
Get the variables of an image.
Definition: Panorama.cpp:128
PanoCommand::PanoCommand * GetPanoCommand()
return PanoCommand for adding converted raw files to Panorama
Definition: RawImport.cpp:625
void SaveLensParameters(const wxString filename, HuginBase::Panorama *pano, unsigned int imgNr)
save the lens parameters of the image to a lens file named filename
Definition: LensTools.cpp:144
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
static MainFrame * Get()
hack.. kind of a pseudo singleton...
Definition: MainFrame.cpp:2129
void LimitToGeometric()
limits the displayed parameters to geometric parameters
Definition: ResetDialog.cpp:90
UIntSet getCPoutsideLimit_pair(Panorama pano, AppBase::ProgressDisplay &progress, double n)
optimises images pairwise and removes for every image pair control points with error &gt; mean+n*sigma ...
Definition: CleanCP.cpp:37
void setCtrlPoints(const CPVector &points)
set all control points (Ippei: Is this supposed to be &#39;add&#39; method?)
Definition: Panorama.cpp:449
Map::mapped_type & map_get(Map &m, const typename Map::key_type &key)
get a map element.
Definition: stl_utils.h:98
std::shared_ptr< vigra::BRGBImage > ImageCacheRGB8Ptr
use reference counted pointers
Definition: ImageCache.h:57
#define HUGIN_CELESTE_FILTER
int getWidth() const
Get the width of the image in pixels.
Definition: SrcPanoImage.h:266
PanoOperationVector * GetLensesOperationVector()
returns list of PanoOperation for work with lenses
#define HUGIN_CELESTE_THRESHOLD
Switch the part number of an image.
Definition: PanoCommand.h:506
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
PanoOperationVector * GetControlPointsOperationVector()
returns list of PanoOperation for work with control points
PanoOperation to load lens from ini file or lens database.
base class for different PanoOperations derived classes should overwrite protected PanoOperation::Get...
Definition: PanoOperation.h:39
Definition of dialog to edit image variables by parsing an expression.
PanoOperation to add several user selected images to the panorama.
Definition: PanoOperation.h:73
time_t ReadExifTime(const char *filename)
reset output exposure to mean exposure of all images
Definition: PanoCommand.h:640
ImageVariableGroup & getLenses()
Get the ImageVariableGroup representing the group of lens variables.
static PanoOperationVector PanoOpControlPoints
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
wxwindows specific panorama commands
IMPEX double h[25][1024]
Definition: emor.cpp:169
PanoOperation to remove control points.
update variables by parsing a expression
Definition: PanoCommand.h:188
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
vigra::pair< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImage(ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:324
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
CPointVector getCtrlPointsVectorForImage(unsigned int imgNr) const
return a vector of std::pairs with global ctrl point nr and ControlPoint In the class ControlPoint th...
Definition: Panorama.cpp:96
vigra::triple< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImageRange(const ROIImage< Image, Mask > &img)
helper function for ROIImages
Definition: ROIImage.h:287
Dialog for editing expression to change image variables.
dialogs for loading and saving information from/to lens database
std::vector< CPoint > CPointVector
Definition: ControlPoint.h:102
PanoOperation to change lens number.
WX_DECLARE_STRING_HASH_MAP(time_t, StringToPointerHash)
bool GetResetColorToExif()
Return TRUE, when user selected &quot;Reset color to EXIF&quot;, Return FALSE, when user selected &quot;Reset color ...
std::map< std::string, Variable > VariableMap
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
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
struct celeste::svm_model * GetSVMModel()
Definition: MainFrame.cpp:2186
PanoOperation to add all image in a defined timeinterval to the panorama.
Definition: PanoOperation.h:85
EntryPtr getImage(const std::string &filename)
get a image.
Definition: ImageCache.cpp:307
static PanoOperationVector PanoOpLens
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition: Panorama.h:481
HuginBase::UIntSet getCelesteControlPoints(struct svm_model *model, vigra::UInt16RGBImage &input, HuginBase::CPointVector cps, int radius, float threshold, int resize_dimension, bool verbose)
Definition: Celeste.cpp:363
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)=0
main working function, overwrite it in derived classes
UIntSet getCPoutsideLimit(Panorama pano, double n, bool skipOptimisation, bool includeLineCp)
optimises the whole panorama and removes all control points with error &gt; mean+n*sigma ...
Definition: CleanCP.cpp:123
sortbytime(std::map< std::string, time_t > &h)
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
bool operator()(const std::string &s1, const std::string &s2)
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
PanoOperation to reset image variables.
bool containsInvalidCharacters(const wxString stringToTest)
returns true, if the given strings contains invalid characters
Definition: platform.cpp:510
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
add image(s) to a panorama
Definition: wxPanoCommand.h:50
bool ShowDialog(wxWindow *parent)
PanoOperationVector * GetResetOperationVector()
returns list of PanoOperation for resetting
PanoOperationVector * GetImagesOperationVector()
returns list of PanoOperation for work with images
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
void transformImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor &func)
Definition: openmp_vigra.h:330
PanoOperation to clean control points with statistically method.
void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)
Definition: openmp_vigra.h:305
LoadLensOperation(bool fromDatabase)
virtual bool IsEnabled(HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
return true, if operation is enabled with the given image set
std::vector< PanoOperation * > PanoOperationVector
bool updateDisplay(const wxString &message)
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
remove multiple images from a panorama
Definition: PanoCommand.h:94
GuiLevel
Definition: GuiLevel.h:31
void CleanPanoOperationVector()
clears the PanoOperationVector
void fill_set(_Container &c, typename _Container::key_type begin, typename _Container::key_type end)
Definition: stl_utils.h:81
bool GetResetTranslation()
Return TRUE, when user selected &quot;Reset translation&quot;.
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
std::size_t getNumberOfParts() const
get the number of parts.
All variables of a source image.
Definition: SrcPanoImage.h:194
void removeImage(const std::string &filename)
remove a specific image (and dependant images) from the cache
Definition: ImageCache.cpp:91
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.
PanoOperationVector * GetStacksOperationVector()
returns list of PanoOperation for stacks
bool GetResetResponse()
Return TRUE, when user selected &quot;Reset Camera Response&quot;.
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
bool GetResetPos()
Return TRUE, when user selected &quot;Reset position&quot;.
void _CleanPanoOperationVector(PanoOperationVector &vec)
functions to handle icc profiles in images
static T min(T x, T y)
Definition: svm.cpp:62
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition: wxutils.cpp:176
static const std::set< ConstImageVariableGroup::ImageVariableEnum > & getStackVariables()
Get the set of stack image variables.
virtual PanoCommand::PanoCommand * GetInternalCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images)
main working function, overwrite it in derived classes
PanoOperation to modify image variables by parsing an expression.
Definition: PanoOperation.h:94
void ApplyICCProfile(ImageType &image, const vigra::ImageImportInfo::ICCProfile &iccProfile, const cmsUInt32Number imageFormat)
converts given image with iccProfile to sRGB/gray space, need to give pixel type in lcms2 format work...
Definition: cms.h:37
PanoOperation to change lens number.
bool CheckRawFiles()
return true, if all raw files are from the same camera
Definition: RawImport.cpp:630
Lens getLens(std::size_t lens_number)
A panorama.getLens equivalent, not for new code.
class to work with images graphs created from a HuginBase::Panorama class it creates a graph based on...
Definition: ImageGraph.h:44