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"
34 #include "celeste/Celeste.h"
35 #ifdef _WIN32
36 // workaround for a conflict between exiv2 and wxWidgets/CMake built
37 #define HAVE_PID_T 1
38 #endif
39 #include <exiv2/exiv2.hpp>
40 #include "base_wx/LensTools.h"
41 #include "base_wx/wxLensDB.h"
42 #include "hugin/ResetDialog.h"
44 #include "hugin/MainFrame.h"
45 #include "hugin/RawImport.h"
46 #include <vigra_ext/openmp_vigra.h>
47 #include <vigra_ext/cms.h>
48 
49 namespace PanoOperation
50 {
51 
52 wxString PanoOperation::GetLabel()
53 {
54  return wxEmptyString;
55 };
56 
57 bool PanoOperation::IsEnabled(HuginBase::Panorama& pano, HuginBase::UIntSet images, GuiLevel guiLevel)
58 {
59  return true;
60 };
61 
62 PanoCommand::PanoCommand* PanoOperation::GetCommand(wxWindow* parent, HuginBase::Panorama& pano, HuginBase::UIntSet images, GuiLevel guiLevel)
63 {
64  //remember gui level, only used by some PanoOperation's
65  m_guiLevel=guiLevel;
66  if(IsEnabled(pano, images, m_guiLevel))
67  {
68  return GetInternalCommand(parent,pano,images);
69  }
70  else
71  {
72  return NULL;
73  };
74 };
75 
77 {
78  return images.size()==1;
79 };
80 
82 {
83  return !images.empty();
84 };
85 
91 bool AddImageDialog(wxWindow* parent, std::vector<std::string>& files, bool& withRaws)
92 {
93  // get stored path
94  wxConfigBase* config = wxConfigBase::Get();
95  wxString path = config->Read(wxT("/actualPath"), wxT(""));
96  wxFileDialog dlg(parent,_("Add images"),
97  path, wxT(""),
99  wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST | wxFD_PREVIEW, wxDefaultPosition);
100  dlg.SetDirectory(path);
101 
102  // remember the image extension
103  wxString img_ext;
104  if (config->HasEntry(wxT("lastImageType")))
105  {
106  img_ext = config->Read(wxT("lastImageType")).c_str();
107  }
108  if (img_ext == wxT("all images"))
109  {
110  dlg.SetFilterIndex(0);
111  }
112  else
113  {
114  if (!withRaws)
115  {
116  if (img_ext == wxT("jpg"))
117  dlg.SetFilterIndex(1);
118  else if (img_ext == wxT("tiff"))
119  dlg.SetFilterIndex(2);
120  else if (img_ext == wxT("png"))
121  dlg.SetFilterIndex(3);
122  else if (img_ext == wxT("hdr"))
123  dlg.SetFilterIndex(4);
124  else if (img_ext == wxT("exr"))
125  dlg.SetFilterIndex(5);
126  else if (img_ext == wxT("all files"))
127  dlg.SetFilterIndex(6);
128  }
129  else
130  {
131  if (img_ext == wxT("all raws"))
132  dlg.SetFilterIndex(1);
133  else if (img_ext == wxT("jpg"))
134  dlg.SetFilterIndex(2);
135  else if (img_ext == wxT("tiff"))
136  dlg.SetFilterIndex(3);
137  else if (img_ext == wxT("png"))
138  dlg.SetFilterIndex(4);
139  else if (img_ext == wxT("hdr"))
140  dlg.SetFilterIndex(5);
141  else if (img_ext == wxT("exr"))
142  dlg.SetFilterIndex(6);
143  };
144  };
145 
146  // call the file dialog
147  if (dlg.ShowModal() == wxID_OK)
148  {
149  // get the selections
150  wxArrayString Pathnames;
151  dlg.GetPaths(Pathnames);
152 
153  // remember path for later
154 #ifdef __WXGTK__
155  //workaround a bug in GTK, see https://bugzilla.redhat.com/show_bug.cgi?id=849692 and http://trac.wxwidgets.org/ticket/14525
156  config->Write(wxT("/actualPath"), wxPathOnly(Pathnames[0]));
157 #else
158  config->Write(wxT("/actualPath"), dlg.GetDirectory());
159 #endif
160  // save the image extension
161  if (!withRaws)
162  {
163  switch (dlg.GetFilterIndex())
164  {
165  case 0: config->Write(wxT("lastImageType"), wxT("all images")); break;
166  case 1: config->Write(wxT("lastImageType"), wxT("jpg")); break;
167  case 2: config->Write(wxT("lastImageType"), wxT("tiff")); break;
168  case 3: config->Write(wxT("lastImageType"), wxT("png")); break;
169  case 4: config->Write(wxT("lastImageType"), wxT("hdr")); break;
170  case 5: config->Write(wxT("lastImageType"), wxT("exr")); break;
171  case 6: config->Write(wxT("lastImageType"), wxT("all files")); break;
172  };
173  }
174  else
175  {
176  switch (dlg.GetFilterIndex())
177  {
178  case 0: config->Write(wxT("lastImageType"), wxT("all images")); break;
179  case 1: config->Write(wxT("lastImageType"), wxT("all raws")); break;
180  case 2: config->Write(wxT("lastImageType"), wxT("jpg")); break;
181  case 3: config->Write(wxT("lastImageType"), wxT("tiff")); break;
182  case 4: config->Write(wxT("lastImageType"), wxT("png")); break;
183  case 5: config->Write(wxT("lastImageType"), wxT("hdr")); break;
184  case 6: config->Write(wxT("lastImageType"), wxT("exr")); break;
185  }
186  withRaws = dlg.GetFilterIndex() == 1;
187  };
188 
189  //check for forbidden/non working chars
190  wxArrayString invalidFiles;
191  for(unsigned int i=0;i<Pathnames.GetCount(); i++)
192  {
193  if(containsInvalidCharacters(Pathnames[i]))
194  {
195  invalidFiles.Add(Pathnames[i]);
196  };
197  };
198  if(!invalidFiles.empty())
199  {
200  ShowFilenameWarning(parent, invalidFiles);
201  return false;
202  }
203  for (unsigned int i=0; i<Pathnames.GetCount(); i++)
204  {
205  files.push_back((const char *)Pathnames[i].mb_str(HUGIN_CONV_FILENAME));
206  };
207  return true;
208  };
209  return false;
210 };
211 
213 {
214  return _("Add individual images...");
215 };
216 
218 {
219  std::vector<std::string> files;
220  bool withRaws = true;
221  if(AddImageDialog(parent, files, withRaws))
222  {
223  if(!files.empty())
224  {
225  if (withRaws)
226  {
227  if (files.size() == 1)
228  {
229  wxMessageDialog message(parent, _("You selected only one raw file. This is not recommended.\nAll raw files should be converted at once."),
230 #ifdef _WIN32
231  _("Hugin"),
232 #else
233  wxT(""),
234 #endif
235  wxICON_EXCLAMATION | wxYES_NO );
236  message.SetYesNoLabels(_("Convert anyway"), _("Let me select several raw files"));
237  if (message.ShowModal() == wxID_NO)
238  {
239  // post new add image event to open dialog again
240  wxCommandEvent newAddEvent(wxEVT_COMMAND_BUTTON_CLICKED, XRCID("action_add_images"));
241  MainFrame::Get()->GetEventHandler()->AddPendingEvent(newAddEvent);
242  return NULL;
243  };
244  };
245  RawImportDialog dlg(parent, &pano, files);
246  // check that raw files are from same camera and that all can be read
247  if (dlg.CheckRawFiles())
248  {
249  // now show dialog
250  if (dlg.ShowModal() == wxID_OK)
251  {
252  return dlg.GetPanoCommand();
253  };
254  };
255  }
256  else
257  {
258  return new PanoCommand::wxAddImagesCmd(pano, files, m_preferredLensType);
259  };
260  };
261  };
262  return NULL;
263 };
264 
265 WX_DECLARE_STRING_HASH_MAP(time_t, StringToPointerHash);
266 WX_DECLARE_STRING_HASH_MAP(int, StringToFlagHash);
267 
268 time_t ReadExifTime(const char* filename)
269 {
270 #if defined EXIV2_VERSION && EXIV2_TEST_VERSION(0,27,99)
271  Exiv2::Image::UniquePtr image;
272 #else
273  Exiv2::Image::AutoPtr image;
274 #endif
275  try
276  {
277  image = Exiv2::ImageFactory::open(filename);
278  }
279  catch(...)
280  {
281  return 0;
282  }
283  if (image.get() == 0)
284  {
285  return 0;
286  }
287 
288  try
289  {
290  image->readMetadata();
291  }
292  catch (const Exiv2::Error& e)
293  {
294  std::cerr << "Exiv2: Error reading metadata (" << e.what() << ")" << std::endl;
295  return 0;
296  }
297  Exiv2::ExifData &exifData = image->exifData();
298  if (exifData.empty())
299  {
300  return 0;
301  }
302 
303  Exiv2::Exifdatum& tag = exifData["Exif.Image.DateTime"];
304  const std::string date_time = tag.toString();
305 
306  // Remember the file and a shutter timestamp.
307  struct tm when;
308  memset(&when, 0, sizeof(when));
309  when.tm_wday = -1;
310 
311  // parse into the tm_structure
312  const int a = sscanf(date_time.c_str(), "%d:%d:%d %d:%d:%d",
313  &when.tm_year, &when.tm_mon, &when.tm_mday,
314  &when.tm_hour, &when.tm_min, &when.tm_sec);
315 
316  if (a == 6)
317  {
318  when.tm_isdst = -1;
319  when.tm_mon -= 1; // Adjust for unix zero-based months
320  when.tm_year -= 1900; // Adjust for year starting at 1900
321  }
322  else
323  {
324  // Not in EXIF format
325  return 0;
326  }
327 
328  time_t stamp;
329  stamp = mktime(&when);
330  if (stamp == (time_t)(-1))
331  return 0;
332 
333  return stamp;
334 }
335 
337 {
338  explicit sortbytime(std::map<std::string, time_t> & h) : m_time(h) {};
339  bool operator()(const std::string & s1, const std::string & s2)
340  {
341  time_t t1 = m_time[s1];
342  time_t t2 = m_time[s2];
343  return t1 < t2;
344  };
345  std::map<std::string, time_t> & m_time;
346 };
347 
349 {
350  return _("Add time-series of images...");
351 };
352 
354 {
355  //load image if pano contains no images
356  std::vector<std::string> files;
357  if(pano.getNrOfImages()==0)
358  {
359  bool withRaws = false;
360  if(!AddImageDialog(parent,files, withRaws))
361  {
362  return NULL;
363  };
364  //just in case
365  if(files.empty())
366  {
367  return NULL;
368  };
369  }
370  else
371  {
372  for(size_t i=0;i<pano.getNrOfImages();i++)
373  {
374  files.push_back(pano.getImage(i).getFilename());
375  };
376  };
377 
378  DEBUG_TRACE("seeking similarly timed images");
379 
380  // Collect potential image-mates.
381  StringToPointerHash filenames;
382  StringToFlagHash preloaded;
383  for(size_t i=0;i<files.size();i++)
384  {
385  wxString file(files[i].c_str(), HUGIN_CONV_FILENAME);
386  preloaded[file] = 1;
387 
388  // Glob for all files of same type in same directory.
389  wxString path = ::wxPathOnly(file) + wxT("/*");
390  file = ::wxFindFirstFile(path);
391  while (!file.IsEmpty())
392  {
393  // Associated with a NULL dummy timestamp for now.
394  if(vigra::isImage(files[i].c_str()))
395  {
396  filenames[file] = 0;
397  };
398  file = ::wxFindNextFile();
399  }
400  }
401 
402  DEBUG_INFO("found " << filenames.size() << " candidate files to search.");
403 
404  // For each globbed or loaded file,
405  StringToPointerHash::iterator found;
406  std::map<std::string, time_t> timeMap;
407  for (found = filenames.begin(); found != filenames.end(); ++found)
408  {
409  wxString file = found->first;
410  // Check the time if it's got a camera EXIF timestamp.
411  time_t stamp = ReadExifTime(file.mb_str(HUGIN_CONV_FILENAME));
412  if (stamp)
413  {
414  filenames[file] = stamp;
415  timeMap[(const char *)file.mb_str(HUGIN_CONV_FILENAME)] = stamp;
416  }
417  }
418 
419  //TODO: sorting the filenames keys by timestamp would be useful
420  int maxtimediff = wxConfigBase::Get()->Read(wxT("CaptureTimeSpan"), HUGIN_CAPTURE_TIMESPAN);
421  // For each timestamped file,
422  for (found = filenames.begin(); found != filenames.end(); ++found)
423  {
424  wxString recruit = found->first;
425  if (preloaded[recruit] == 1)
426  continue;
427  time_t pledge = filenames[recruit];
428  if (!pledge)
429  continue;
430 
431  // For each other image already loaded,
432  for(size_t i=0;i<files.size();i++)
433  {
434  wxString file(files[i].c_str(), HUGIN_CONV_FILENAME);
435  if (file == recruit)
436  continue;
437 
438  // If it is within threshold time,
439  time_t stamp = filenames[file];
440  if (abs((int)(pledge - stamp)) < maxtimediff)
441  {
442  // Load this file, and remember it.
443  DEBUG_TRACE("Recruited " << recruit.mb_str(wxConvLocal));
444  std::string file = (const char *)recruit.mb_str(HUGIN_CONV_FILENAME);
445  files.push_back(file);
446  // Don't recruit it again.
447  filenames[recruit] = 0;
448  break;
449  }
450  }
451  }
452 
453  if(!files.empty())
454  {
455  // sort files by date
456  sortbytime spred(timeMap);
457  sort(files.begin(), files.end(), spred);
458  // Load all of the named files.
459  return new PanoCommand::wxAddImagesCmd(pano,files);
460  }
461  else
462  {
463  wxMessageBox(
464  _("No matching images found."),
465 #ifdef _WIN32
466  _("Hugin"),
467 #else
468  wxT(""),
469 #endif
470  wxOK | wxICON_INFORMATION, parent);
471  return NULL;
472  };
473 };
474 
476 {
477  return _("Manipulate image variables...");
478 }
479 
481 {
482  ImageVariablesExpressionDialog dlg(parent, &pano);
483  if (dlg.ShowModal() == wxID_OK)
484  {
485  const std::string expression = dlg.GetExpression();
486  if (!expression.empty())
487  {
488  return new PanoCommand::UpdateVariablesByParseExpression(pano, expression);
489  };
490  };
491  return NULL;
492 }
493 
495 {
496  return pano.getNrOfImages() > 0 && guiLevel >= GuiLevel::GUI_ADVANCED;
497 }
498 
500 {
501  return _("Remove selected image(s)");
502 };
503 
505 {
506  //remove images from cache
507  for (HuginBase::UIntSet::iterator it = images.begin(); it != images.end(); ++it)
508  {
509  HuginBase::ImageCache::getInstance().removeImage(pano.getImage(*it).getFilename());
510  }
511  return new PanoCommand::RemoveImagesCmd(pano, images);
512 };
513 
515 {
516  return _("Anchor this image for position");
517 };
518 
520 {
522  opt.optimizeReferenceImage = *(images.begin());
523  return new PanoCommand::SetPanoOptionsCmd(pano,opt);
524 };
525 
527 {
528  return _("Anchor this image for exposure");
529 };
530 
532 {
534  opt.colorReferenceImage = *(images.begin());
535  return new PanoCommand::SetPanoOptionsCmd(pano, opt);
536 };
537 
539 {
540  if(pano.getNrOfImages()==0 || images.empty())
541  {
542  return false;
543  }
544  else
545  {
546  HuginBase::StandardImageVariableGroups variable_groups(pano);
547  return variable_groups.getLenses().getNumberOfParts()<pano.getNrOfImages();
548  };
549 };
550 
552 {
553  return _("New lens");
554 };
555 
557 {
559 };
560 
562 {
563  if(pano.getNrOfImages()==0 || images.empty())
564  {
565  return false;
566  }
567  else
568  {
569  //project must have more than 1 lens before you can assign another lens number
570  HuginBase::StandardImageVariableGroups variableGroups(pano);
571  return variableGroups.getLenses().getNumberOfParts() > 1;
572  };
573 };
574 
576 {
577  return _("Change lens...");
578 };
579 
581 {
582  HuginBase::StandardImageVariableGroups variable_groups(pano);
583  long nr = wxGetNumberFromUser(
584  _("Enter new lens number"),
585  _("Lens number"),
586  _("Change lens number"), 0, 0,
587  variable_groups.getLenses().getNumberOfParts()-1
588  );
589  if (nr >= 0)
590  {
591  // user accepted
592  // check that image size are the same
593  const vigra::Size2D lensImgSize = variable_groups.getLens(nr).getImageSize();
594  for (const auto& img : images)
595  {
596  if (pano.getImage(img).getSize() != lensImgSize)
597  {
598  wxMessageBox(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."),
599  img, pano.getImage(img).getWidth(), pano.getImage(img).getHeight(), nr, lensImgSize.width(), lensImgSize.height()),
600 #ifdef __WXMSW__
601  wxT("Hugin"),
602 #else
603  wxT(""),
604 #endif
605  wxICON_EXCLAMATION | wxOK);
606  return NULL;
607  };
608  };
610  }
611  else
612  {
613  return NULL;
614  };
615 };
616 
618 {
619  m_fromDatabase = fromDatabase;
620 };
621 
623 {
624  if (m_fromDatabase)
625  {
626  return _("Load lens from lens database");
627  }
628  else
629  {
630  return _("Load lens from ini file");
631  };
632 };
633 
635 {
636  HuginBase::StandardImageVariableGroups variable_groups(pano);
637  HuginBase::UIntSet lensImages = variable_groups.getLenses().getPartsSet()[variable_groups.getLenses().getPartNumber(*images.begin())];
638  if (!m_fromDatabase && images.size() == 1 && lensImages.size() > 1)
639  {
640  // database is always linking the parameters, so no need to ask user
641  if(wxMessageBox(_("You selected only one image.\nShould the loaded parameters be applied to all images with the same lens?"),_("Question"), wxICON_QUESTION | wxYES_NO)==wxYES)
642  {
643  // get all images with the current lens.
644  std::copy(lensImages.begin(), lensImages.end(), std::inserter(images, images.end()));
645  };
646  };
647  vigra::Size2D sizeImg0=pano.getImage(*(images.begin())).getSize();
648  //check if all images have the same size
649  bool differentImageSize=false;
650  for(HuginBase::UIntSet::const_iterator it=images.begin();it!=images.end() && !differentImageSize;++it)
651  {
652  differentImageSize=(pano.getImage(*it).getSize()!=sizeImg0);
653  };
654  if(differentImageSize)
655  {
656  if(wxMessageBox(_("You selected images with different sizes.\nApply lens parameter file can result in unwanted results.\nApply settings anyway?"), _("Error"), wxICON_QUESTION |wxYES_NO)==wxID_NO)
657  {
658  return NULL;
659  };
660  };
661  PanoCommand::PanoCommand* cmd=NULL;
662  bool isLoaded=false;
663  if (m_fromDatabase)
664  {
665  isLoaded=ApplyLensDBParameters(parent,&pano,images,cmd);
666  }
667  else
668  {
669  isLoaded=ApplyLensParameters(parent,&pano,images,cmd);
670  };
671  if(isLoaded)
672  {
673  return cmd;
674  }
675  else
676  {
677  return NULL;
678  }
679 };
680 
682 {
683  m_database = toDatabase;
684 };
685 
687 {
688  if (m_database)
689  {
690  return _("Save lens parameters to lens database");
691  }
692  else
693  {
694  return _("Save lens to ini file");
695  };
696 };
697 
699 {
700  unsigned int imgNr = *(images.begin());
701  if (m_database)
702  {
703  SaveLensParameters(parent, pano.getImage(imgNr));
704  }
705  else
706  {
707  SaveLensParametersToIni(parent, &pano, images);
708  };
709  return NULL;
710 };
711 
713 {
714  return _("Remove control points");
715 };
716 
718 {
719  return pano.getNrOfImages()>0 && pano.getNrOfCtrlPoints()>0;
720 };
721 
723 {
724  HuginBase::UIntSet selImages;
725  if(images.empty())
726  {
727  fill_set(selImages,0,pano.getNrOfCtrlPoints()-1);
728  }
729  else
730  {
731  selImages=images;
732  };
733  HuginBase::UIntSet cpsToDelete;
734  const HuginBase::CPVector & cps = pano.getCtrlPoints();
735  for (HuginBase::CPVector::const_iterator it = cps.begin(); it != cps.end(); ++it)
736  {
737  if (set_contains(selImages, (*it).image1Nr) && set_contains(selImages, (*it).image2Nr) )
738  {
739  cpsToDelete.insert(it - cps.begin());
740  }
741  }
742  if(cpsToDelete.empty())
743  {
744  wxMessageBox(_("Selected images have no control points."),
745 #ifdef __WXMSW__
746  wxT("Hugin"),
747 #else
748  wxT(""),
749 #endif
750  wxICON_EXCLAMATION | wxOK);
751  return NULL;
752  };
753  int r =wxMessageBox(wxString::Format(_("Really delete %lu control points?"),
754  (unsigned long int) cpsToDelete.size()),
755  _("Delete Control Points"),
756  wxICON_QUESTION | wxYES_NO);
757  if (r == wxYES)
758  {
759  return new PanoCommand::RemoveCtrlPointsCmd(pano, cpsToDelete );
760  }
761  else
762  {
763  return NULL;
764  };
765 };
766 
768 {
769  return _("Clean control points");
770 };
771 
773 {
774  return pano.getNrOfCtrlPoints()>2;
775 };
776 
778 {
780  ProgressReporterDialog progress(0, _("Cleaning Control points"), _("Checking pairwise"), parent);
781 
782  HuginBase::UIntSet removedCPs=getCPoutsideLimit_pair(pano, progress, 2.0);
783 
784  //create a copy to work with
785  //we copy remaining control points to new pano object for running second step
786  HuginBase::Panorama newPano=pano.duplicate();
787  std::map<size_t,size_t> cpMap;
788  HuginBase::CPVector allCPs=newPano.getCtrlPoints();
789  HuginBase::CPVector firstCleanedCP;
790  size_t j=0;
791  for(size_t i=0;i<allCPs.size();i++)
792  {
793  HuginBase::ControlPoint cp = allCPs[i];
794  if (cp.mode == HuginBase::ControlPoint::X_Y && !set_contains(removedCPs, i))
795  {
796  firstCleanedCP.push_back(cp);
797  cpMap[j++]=i;
798  };
799  };
800  newPano.setCtrlPoints(firstCleanedCP);
801 
802  //check for unconnected images
803  HuginGraph::ImageGraph graph(newPano);
804  if (!progress.updateDisplayValue(_("Checking whole project")))
805  {
806  return NULL;
807  }
808  if (graph.IsConnected())
809  {
810  //now run the second step
811  HuginBase::UIntSet removedCP2=getCPoutsideLimit(newPano, 2.0);
812  if(!removedCP2.empty())
813  {
814  for(HuginBase::UIntSet::const_iterator it=removedCP2.begin();it!=removedCP2.end();++it)
815  {
816  removedCPs.insert(cpMap[*it]);
817  };
818  };
819  }
821  if (!progress.updateDisplay(_("Finished cleaning")))
822  {
823  return NULL;
824  }
825  if (!removedCPs.empty())
826  {
827  wxMessageBox(wxString::Format(_("Removed %lu control points"), (unsigned long int)removedCPs.size()), _("Cleaning"), wxOK | wxICON_INFORMATION, parent);
828  return new PanoCommand::RemoveCtrlPointsCmd(pano,removedCPs);
829  };
830  return NULL;
831 };
832 
834 {
835  return _("Remove control points on clouds");
836 };
837 
839 {
840  ProgressReporterDialog progress(images.size() + 2, _("Running Celeste"), _("Running Celeste"), parent);
841  progress.updateDisplay(_("Loading model file"));
842 
843  struct celeste::svm_model* model=MainFrame::Get()->GetSVMModel();
844  if (model == NULL || !progress.updateDisplay(_("Loading images")))
845  {
846  return NULL;
847  };
848 
849  // Get Celeste parameters
850  wxConfigBase *cfg = wxConfigBase::Get();
851  // SVM threshold
853  cfg->Read(wxT("/Celeste/Threshold"), &threshold, HUGIN_CELESTE_THRESHOLD);
854 
855  // Mask resolution - 1 sets it to fine
856  bool t = (cfg->Read(wxT("/Celeste/Filter"), HUGIN_CELESTE_FILTER) == 0);
857  int radius=(t)?10:20;
858  DEBUG_TRACE("Running Celeste");
859 
860  HuginBase::UIntSet cpsToRemove;
861  for (HuginBase::UIntSet::const_iterator it=images.begin(); it!=images.end(); ++it)
862  {
863  // Image to analyse
865  if(cps.empty())
866  {
867  if (!progress.updateDisplayValue())
868  {
869  return NULL;
870  };
871  continue;
872  };
874  vigra::UInt16RGBImage in;
875  if(img->image16->width()>0)
876  {
877  in.resize(img->image16->size());
878  vigra::omp::copyImage(srcImageRange(*(img->image16)),destImage(in));
879  }
880  else
881  {
882  HuginBase::ImageCache::ImageCacheRGB8Ptr im8 = img->get8BitImage();
883  in.resize(im8->size());
884  vigra::omp::transformImage(srcImageRange(*im8),destImage(in),vigra::functor::Arg1()*vigra::functor::Param(65535/255));
885  };
886  if (!img->iccProfile->empty())
887  {
888  HuginBase::Color::ApplyICCProfile(in, *(img->iccProfile), TYPE_RGB_16);
889  };
890  if (!progress.updateDisplay(_("Running Celeste")))
891  {
892  return NULL;
893  };
894  HuginBase::UIntSet cloudCP=celeste::getCelesteControlPoints(model,in,cps,radius,threshold,800);
895  in.resize(0,0);
896  if (!progress.updateDisplay())
897  {
898  return NULL;
899  };
900  if(!cloudCP.empty())
901  {
902  for(HuginBase::UIntSet::const_iterator it2=cloudCP.begin();it2!=cloudCP.end(); ++it2)
903  {
904  cpsToRemove.insert(*it2);
905  };
906  };
907  if (!progress.updateDisplayValue(_("Loading images")))
908  {
909  return NULL;
910  };
911  };
912 
913  if (!progress.updateDisplayValue())
914  {
915  return NULL;
916  }
917  if (!cpsToRemove.empty())
918  {
919  wxMessageBox(wxString::Format(_("Removed %lu control points"), (unsigned long int) cpsToRemove.size()), _("Celeste result"),wxOK|wxICON_INFORMATION);
920  return new PanoCommand::RemoveCtrlPointsCmd(pano,cpsToRemove);
921  }
922  else
923  {
924  return NULL;
925  };
926 };
927 
929 {
930  m_resetMode=newResetMode;
935  m_resetExposure=0;
937  {
938  m_resetExposure=3;
939  };
941  m_resetColor = 0;
943  {
944  m_resetColor=1;
945  };
947 };
948 
950 {
951  switch(m_resetMode)
952  {
953  case RESET_DIALOG:
954  case RESET_DIALOG_LENS:
956  return _("Reset user defined...");
957  break;
958  case RESET_POSITION:
959  return _("Reset positions");
960  break;
961  case RESET_TRANSLATION:
962  return _("Reset translation parameters");
963  break;
964  case RESET_LENS:
965  return _("Reset lens parameters");
966  break;
967  case RESET_PHOTOMETRICS:
968  return _("Reset photometric parameters");
969  };
970  return wxEmptyString;
971 };
972 
974 {
975  switch(m_resetMode)
976  {
977  case RESET_TRANSLATION:
978  return guiLevel>=GUI_EXPERT && pano.getNrOfImages()>0;
979  break;
980  default:
981  return pano.getNrOfImages()>0;
982  };
983 };
984 
986 {
988  {
989  if(!ShowDialog(parent))
990  {
991  return NULL;
992  };
993  };
994  if(images.empty())
995  {
996  fill_set(images,0,pano.getNrOfImages()-1);
997  };
998  double redBalanceAnchor = pano.getImage(pano.getOptions().colorReferenceImage).getExifRedBalance();
999  double blueBalanceAnchor = pano.getImage(pano.getOptions().colorReferenceImage).getExifBlueBalance();
1000  if(fabs(redBalanceAnchor)<1e-2)
1001  {
1002  redBalanceAnchor=1;
1003  };
1004  if(fabs(blueBalanceAnchor)<1e-2)
1005  {
1006  blueBalanceAnchor=1;
1007  };
1008 
1010  for(HuginBase::UIntSet::const_iterator it = images.begin(); it != images.end(); ++it)
1011  {
1012  unsigned int imgNr = *it;
1013  HuginBase::VariableMap ImgVars = pano.getImageVariables(imgNr);
1014  if(m_resetPos)
1015  {
1016  map_get(ImgVars,"y").setValue(0);
1017  map_get(ImgVars,"p").setValue(0);
1018  map_get(ImgVars,"r").setValue(pano.getSrcImage(imgNr).getExifOrientation());
1019  map_get(ImgVars,"TrX").setValue(0);
1020  map_get(ImgVars,"TrY").setValue(0);
1021  map_get(ImgVars,"TrZ").setValue(0);
1022  map_get(ImgVars,"Tpy").setValue(0);
1023  map_get(ImgVars,"Tpp").setValue(0);
1024  };
1025  if(m_resetTranslation)
1026  {
1027  map_get(ImgVars,"TrX").setValue(0);
1028  map_get(ImgVars,"TrY").setValue(0);
1029  map_get(ImgVars,"TrZ").setValue(0);
1030  map_get(ImgVars,"Tpy").setValue(0);
1031  map_get(ImgVars,"Tpp").setValue(0);
1032  };
1033  HuginBase::SrcPanoImage srcImg = pano.getSrcImage(imgNr);
1034  if(m_resetHFOV)
1035  {
1036  double focalLength=srcImg.getExifFocalLength();
1037  double cropFactor=srcImg.getExifCropFactor();
1038  if(focalLength!=0 && cropFactor!=0)
1039  {
1040  double newHFOV=HuginBase::SrcPanoImage::calcHFOV(srcImg.getProjection(), focalLength, cropFactor, srcImg.getSize());
1041  if(newHFOV!=0)
1042  {
1043  map_get(ImgVars,"v").setValue(newHFOV);
1044  };
1045  };
1046  };
1047  if(m_resetLens)
1048  {
1049  map_get(ImgVars,"a").setValue(0);
1050  map_get(ImgVars,"b").setValue(0);
1051  map_get(ImgVars,"c").setValue(0);
1052  map_get(ImgVars,"d").setValue(0);
1053  map_get(ImgVars,"e").setValue(0);
1054  map_get(ImgVars,"g").setValue(0);
1055  map_get(ImgVars,"t").setValue(0);
1056  };
1057  if(m_resetExposure>0)
1058  {
1059  if(m_resetExposure==1 || m_resetExposure==3)
1060  {
1061  //reset to exif value
1062  double eV=srcImg.calcExifExposureValue();
1063  if ((m_resetExposure == 1 && eV != 0) || m_resetExposure == 3)
1064  {
1065  map_get(ImgVars,"Eev").setValue(eV);
1066  }
1067  }
1068  else
1069  {
1070  //reset to zero
1071  map_get(ImgVars,"Eev").setValue(0);
1072  };
1073  };
1074  if(m_resetColor>0)
1075  {
1076  if(m_resetColor==1)
1077  {
1078  double redBal=1;
1079  double blueBal=1;
1080  const HuginBase::SrcPanoImage& img=pano.getImage(imgNr);
1082  // use EXIF Red/BlueBalance data only if image and anchor image are from the same camera
1083  if(img.getExifMake() == anchor.getExifMake() &&
1084  img.getExifModel() == anchor.getExifModel())
1085  {
1086  redBal=fabs(img.getExifRedBalance()/redBalanceAnchor);
1087  if(redBal<1e-2)
1088  {
1089  redBal=1;
1090  };
1091  blueBal=fabs(img.getExifBlueBalance()/blueBalanceAnchor);
1092  if(blueBal<1e-2)
1093  {
1094  blueBal=1;
1095  };
1096  };
1097  map_get(ImgVars,"Er").setValue(redBal);
1098  map_get(ImgVars,"Eb").setValue(blueBal);
1099  }
1100  else
1101  {
1102  map_get(ImgVars,"Er").setValue(1);
1103  map_get(ImgVars,"Eb").setValue(1);
1104  };
1105  };
1106  if(m_resetVignetting)
1107  {
1108  map_get(ImgVars,"Vb").setValue(0);
1109  map_get(ImgVars,"Vc").setValue(0);
1110  map_get(ImgVars,"Vd").setValue(0);
1111  map_get(ImgVars,"Vx").setValue(0);
1112  map_get(ImgVars,"Vy").setValue(0);
1113 
1114  };
1116  {
1117  map_get(ImgVars,"Ra").setValue(0);
1118  map_get(ImgVars,"Rb").setValue(0);
1119  map_get(ImgVars,"Rc").setValue(0);
1120  map_get(ImgVars,"Rd").setValue(0);
1121  map_get(ImgVars,"Re").setValue(0);
1122  };
1123  vars.push_back(ImgVars);
1124  };
1125  std::vector<PanoCommand::PanoCommand *> reset_commands;
1126  reset_commands.push_back(
1127  new PanoCommand::UpdateImagesVariablesCmd(pano, images, vars)
1128  );
1129  if(m_resetExposure>0)
1130  {
1131  //reset panorama output exposure value
1132  reset_commands.push_back(new PanoCommand::ResetToMeanExposure(pano));
1133  };
1134  return new PanoCommand::CombinedPanoCommand(pano, reset_commands);
1135 };
1136 
1137 bool ResetOperation::ShowDialog(wxWindow* parent)
1138 {
1139  ResetDialog reset_dlg(parent, m_guiLevel);
1140  bool checkGeometric;
1141  bool checkPhotometric;
1142  switch(m_resetMode)
1143  {
1144  case RESET_DIALOG_LENS:
1145  reset_dlg.LimitToGeometric();
1146  checkGeometric=true;
1147  checkPhotometric=false;
1148  break;
1150  reset_dlg.LimitToPhotometric();
1151  checkGeometric=false;
1152  checkPhotometric=true;
1153  break;
1154  case RESET_DIALOG:
1155  default:
1156  checkGeometric=true;
1157  checkPhotometric=true;
1158  break;
1159  };
1160  if(reset_dlg.ShowModal()==wxID_OK)
1161  {
1162  if(checkGeometric)
1163  {
1164  m_resetPos=reset_dlg.GetResetPos();
1166  m_resetHFOV=reset_dlg.GetResetFOV();
1167  m_resetLens=reset_dlg.GetResetLens();
1168  };
1169  if(checkPhotometric)
1170  {
1171  if(reset_dlg.GetResetExposure())
1172  {
1173  if(reset_dlg.GetResetExposureToExif())
1174  {
1175  m_resetExposure=1;
1176  }
1177  else
1178  {
1179  m_resetExposure=2;
1180  };
1181  }
1182  else
1183  {
1184  m_resetExposure=0;
1185  };
1187  if(reset_dlg.GetResetColor())
1188  {
1189  if(reset_dlg.GetResetColorToExif())
1190  {
1191  m_resetColor=1;
1192  }
1193  else
1194  {
1195  m_resetColor=2;
1196  };
1197  }
1198  else
1199  {
1200  m_resetColor=0;
1201  };
1203  };
1204  return true;
1205  }
1206  else
1207  {
1208  return false;
1209  };
1210 };
1211 
1213 {
1214  if(pano.getNrOfImages()==0 || images.empty())
1215  {
1216  return false;
1217  }
1218  else
1219  {
1220  HuginBase::StandardImageVariableGroups variable_groups(pano);
1221  return variable_groups.getStacks().getNumberOfParts()<pano.getNrOfImages();
1222  };
1223 };
1224 
1226 {
1227  return _("New stack");
1228 };
1229 
1231 {
1233 };
1234 
1236 {
1237  if(pano.getNrOfImages()==0 || images.empty())
1238  {
1239  return false;
1240  }
1241  else
1242  {
1243  //project must have more than 1 stack before you can assign another stack number
1244  HuginBase::StandardImageVariableGroups variableGroups(pano);
1245  return variableGroups.getStacks().getNumberOfParts() > 1;
1246  };
1247 };
1248 
1250 {
1251  return _("Change stack...");
1252 };
1253 
1255 {
1256  HuginBase::StandardImageVariableGroups variable_groups(pano);
1257  long nr = wxGetNumberFromUser(
1258  _("Enter new stack number"),
1259  _("Stack number"),
1260  _("Change stack number"), 0, 0,
1261  variable_groups.getStacks().getNumberOfParts()-1
1262  );
1263  if (nr >= 0)
1264  {
1265  // user accepted
1266  // check that image size are the same
1267  const vigra::Size2D stackImgSize = pano.getImage(*variable_groups.getStacks().getPartsSet()[nr].begin()).getSize();
1268  for (const auto& img : images)
1269  {
1270  if (pano.getImage(img).getSize() != stackImgSize)
1271  {
1272  wxMessageBox(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."),
1273  img, pano.getImage(img).getWidth(), pano.getImage(img).getHeight(), nr, stackImgSize.width(), stackImgSize.height()),
1274 #ifdef __WXMSW__
1275  wxT("Hugin"),
1276 #else
1277  wxT(""),
1278 #endif
1279  wxICON_EXCLAMATION | wxOK);
1280  return NULL;
1281  };
1282  };
1283 
1285  }
1286  else
1287  {
1288  return NULL;
1289  };
1290 };
1291 
1293 {
1294  return pano.getNrOfImages()>1;
1295 };
1296 
1298 {
1299  return _("Set stack size...");
1300 };
1301 
1303 {
1304  wxConfigBase* cfg = wxConfigBase::Get();
1305  wxDialog dlg;
1306  wxXmlResource::Get()->LoadDialog(&dlg, parent, wxT("stack_size_dialog"));
1307  wxSpinCtrl* stackSpin = XRCCTRL(dlg, "stack_size_spinctrl", wxSpinCtrl);
1308  stackSpin->SetRange(1, pano.getNrOfImages());
1309  size_t oldStackSize = cfg->Read(wxT("/StackDialog/StackSize"), 3);
1310  oldStackSize = std::min(oldStackSize, pano.getNrOfImages());
1311  stackSpin->SetValue(oldStackSize);
1312  wxCheckBox* linkCheckBox = XRCCTRL(dlg, "stack_size_link_checkbox", wxCheckBox);
1313  linkCheckBox->SetValue(cfg->Read(wxT("/StackDialog/LinkPosition"), true) != 0l);
1314  if (dlg.ShowModal() != wxID_OK)
1315  {
1316  // user has canceled dialog
1317  return NULL;
1318  };
1319  long stackSize = stackSpin->GetValue();
1320  bool linkPosition = linkCheckBox->IsChecked();
1321  cfg->Write(wxT("/StackDialog/StackSize"), stackSize);
1322  cfg->Write(wxT("/StackDialog/LinkPosition"), linkPosition);
1323  if(stackSize<0)
1324  {
1325  return NULL;
1326  };
1327  std::vector<PanoCommand::PanoCommand *> commands;
1328  HuginBase::StandardImageVariableGroups variable_groups(pano);
1329  if(variable_groups.getStacks().getNumberOfParts()<pano.getNrOfImages())
1330  {
1331  // first remove all existing stacks
1332  for(size_t i=1; i<pano.getNrOfImages(); i++)
1333  {
1334  HuginBase::UIntSet imgs;
1335  imgs.insert(i);
1337  };
1338  };
1339 
1340  if (stackSize > 1)
1341  {
1342  size_t stackNr=0;
1343  size_t imgNr=0;
1344  while(imgNr<pano.getNrOfImages())
1345  {
1346  HuginBase::UIntSet imgs;
1347  for(size_t i=0; i<stackSize && imgNr<pano.getNrOfImages(); i++)
1348  {
1349  imgs.insert(imgNr);
1350  imgNr++;
1351  };
1353  stackNr++;
1354  };
1355  };
1356 
1357  if (!linkPosition && stackSize > 1)
1358  {
1359  // unlink image position
1360  HuginBase::UIntSet imgs;
1361  fill_set(imgs, 0, pano.getNrOfImages() - 1);
1362  std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> variables;
1363  variables.insert(HuginBase::ImageVariableGroup::IVE_Yaw);
1364  variables.insert(HuginBase::ImageVariableGroup::IVE_Pitch);
1365  variables.insert(HuginBase::ImageVariableGroup::IVE_Roll);
1366  variables.insert(HuginBase::ImageVariableGroup::IVE_X);
1367  variables.insert(HuginBase::ImageVariableGroup::IVE_Y);
1368  variables.insert(HuginBase::ImageVariableGroup::IVE_Z);
1369  variables.insert(HuginBase::ImageVariableGroup::IVE_TranslationPlaneYaw);
1370  variables.insert(HuginBase::ImageVariableGroup::IVE_TranslationPlanePitch);
1371  commands.push_back(new PanoCommand::ChangePartImagesLinkingCmd(pano, imgs, variables, false, HuginBase::StandardImageVariableGroups::getStackVariables()));
1372  };
1373  return new PanoCommand::CombinedPanoCommand(pano, commands);
1374 };
1375 
1381 
1383 {
1384  return &PanoOpImages;
1385 };
1386 
1388 {
1389  return &PanoOpLens;
1390 };
1391 
1393 {
1394  return &PanoOpStacks;
1395 };
1396 
1398 {
1399  return &PanoOpControlPoints;
1400 };
1401 
1403 {
1404  return &PanoOpReset;
1405 };
1406 
1408 {
1409  PanoOpImages.push_back(new AddImageOperation());
1410  PanoOpImages.push_back(new AddImagesSeriesOperation());
1411  PanoOpImages.push_back(new RemoveImageOperation());
1412  PanoOpImages.push_back(new ChangeAnchorImageOperation());
1415 
1416  PanoOpLens.push_back(new NewLensOperation());
1417  PanoOpLens.push_back(new ChangeLensOperation());
1418  PanoOpLens.push_back(new LoadLensOperation(false));
1419  PanoOpLens.push_back(new LoadLensOperation(true));
1420  PanoOpLens.push_back(new SaveLensOperation(false));
1421  PanoOpLens.push_back(new SaveLensOperation(true));
1422 
1423  PanoOpStacks.push_back(new NewStackOperation());
1424  PanoOpStacks.push_back(new ChangeStackOperation());
1425  PanoOpStacks.push_back(new AssignStacksOperation());
1426 
1428  PanoOpControlPoints.push_back(new CelesteOperation());
1430 
1436 
1437 };
1438 
1439 
1441 {
1442  for(size_t i=0; i<vec.size(); i++)
1443  {
1444  delete vec[i];
1445  }
1446  vec.clear();
1447 };
1448 
1450 {
1456 };
1457 
1458 } //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:271
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.
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:173
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:180
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:294
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:81
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
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:515
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:410
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:656
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:143
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
static MainFrame * Get()
hack.. kind of a pseudo singleton...
Definition: MainFrame.cpp:2169
void LimitToGeometric()
limits the displayed parameters to geometric parameters
Definition: ResetDialog.cpp:98
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:2226
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:419
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:502
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:125
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
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:661
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