34 #include "wx/mstream.h"
39 #include <exiv2/exiv2.hpp>
53 EVT_BUTTON(XRCID("find_pano_close"),
FindPanoDialog::OnButtonClose)
54 EVT_BUTTON(XRCID("find_pano_select_dir"),
FindPanoDialog::OnButtonChoose)
55 EVT_BUTTON(XRCID("find_pano_start_stop"),
FindPanoDialog::OnButtonStart)
56 EVT_BUTTON(XRCID("find_pano_add_queue"),
FindPanoDialog::OnButtonSend)
57 EVT_LISTBOX(XRCID("find_pano_list"),
FindPanoDialog::OnSelectPossiblePano)
58 EVT_LIST_ITEM_RIGHT_CLICK(XRCID("find_pano_selected_thumbslist"),
FindPanoDialog::OnListItemRightClick)
64 bool SortFilename::operator()(const HuginBase::SrcPanoImage* img1, const HuginBase::SrcPanoImage* img2)
const
76 wxXmlResource::Get()->LoadDialog(
this,batchframe,wxT(
"find_pano_dialog"));
79 wxIconBundle myIcons(xrcPrefix+ wxT(
"data/ptbatcher.ico"),wxBITMAP_TYPE_ICO);
82 wxIcon myIcon(xrcPrefix + wxT(
"data/ptbatcher.png"),wxBITMAP_TYPE_PNG);
95 m_cb_subdir=XRCCTRL(*
this,
"find_pano_subdir",wxCheckBox);
96 m_statustext=XRCCTRL(*
this,
"find_pano_label",wxStaticText);
97 m_list_pano=XRCCTRL(*
this,
"find_pano_list",wxCheckListBox);
98 m_ch_naming=XRCCTRL(*
this,
"find_pano_naming",wxChoice);
104 m_ch_blender = XRCCTRL(*
this,
"find_pano_default_blender", wxChoice);
108 wxConfigBase* config = wxConfigBase::Get();
111 wxDisplaySize(&dx,&dy);
112 bool maximized = config->Read(wxT(
"/FindPanoDialog/maximized"), 0l) != 0;
120 int w = config->Read(wxT(
"/FindPanoDialog/width"),-1l);
121 int h = config->Read(wxT(
"/FindPanoDialog/height"),-1l);
122 if (w > 0 && w <= dx)
124 this->SetClientSize(w,h);
131 int x = config->Read(wxT(
"/FindPanoDialog/positionX"),-1l);
132 int y = config->Read(wxT(
"/FindPanoDialog/positionY"),-1l);
133 if ( y >= 0 && x >= 0 && x < dx && y < dy)
142 long splitterPos = config->Read(wxT(
"/FindPanoDialog/splitterPos"), -1l);
143 if (splitterPos != -1)
145 XRCCTRL(*
this,
"find_pano_splitter", wxSplitterWindow)->SetSashPosition(splitterPos);
147 wxString path=config->Read(wxT(
"/FindPanoDialog/actualPath"),wxEmptyString);
153 config->Read(wxT(
"/FindPanoDialog/includeSubDirs"),&val,
false);
155 long i=config->Read(wxT(
"/FindPanoDialog/Naming"),0l);
157 config->Read(wxT(
"/FindPanoDialog/linkStacks"),&val,
true);
159 config->Read(wxT(
"/FindPanoDialog/loadDistortion"),&val,
false);
161 config->Read(wxT(
"/FindPanoDialog/loadVignetting"),&val,
false);
163 i=config->Read(wxT(
"/FindPanoDialog/MinNumberImages"), 2l);
165 i=config->Read(wxT(
"/FindPanoDialog/MaxTimeDiff"), 30l);
171 m_thumbsList = XRCCTRL(*
this,
"find_pano_selected_thumbslist", wxListCtrl);
183 wxConfigBase* config=wxConfigBase::Get();
184 if(!this->IsMaximized())
186 wxSize sz = this->GetClientSize();
187 config->Write(wxT(
"/FindPanoDialog/width"), sz.GetWidth());
188 config->Write(wxT(
"/FindPanoDialog/height"), sz.GetHeight());
189 wxPoint ps = this->GetPosition();
190 config->Write(wxT(
"/FindPanoDialog/positionX"), ps.x);
191 config->Write(wxT(
"/FindPanoDialog/positionY"), ps.y);
192 config->Write(wxT(
"/FindPanoDialog/maximized"), 0);
196 config->Write(wxT(
"/FindPanoDialog/maximized"), 1l);
198 config->Write(wxT(
"/FindPanoDialog/splitterPos"), XRCCTRL(*
this,
"find_pano_splitter", wxSplitterWindow)->GetSashPosition());
199 config->Write(wxT(
"/FindPanoDialog/actualPath"),
m_textctrl_dir->GetValue());
200 config->Write(wxT(
"/FindPanoDialog/includeSubDirs"),
m_cb_subdir->GetValue());
201 config->Write(wxT(
"/FindPanoDialog/Naming"),
m_ch_naming->GetSelection());
202 config->Write(wxT(
"/FindPanoDialog/linkStacks"),
m_cb_createLinks->GetValue());
206 config->Write(wxT(
"/FindPanoDialog/MaxTimeDiff"),
m_sc_maxTimeDiff->GetValue());
239 if(wxMessageBox(_(
"The list contains possibly unprocessed panoramas.\nIf you close the dialog, you will lose them.\nContinue anyway?"),
240 _(
"Question"),wxYES_NO|wxICON_WARNING,
this)==wxNO)
250 wxDirDialog dlg(
this, _(
"Specify a directory to search for projects in"),
251 m_textctrl_dir->GetValue(), wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
252 if (dlg.ShowModal()==wxID_OK)
274 if (wxMessageBox(_(
"The list contains still not yet processed panoramas.\nIf you continue, they will be disregarded.\nDo you still want to continue?"),
275 _(
"Question"),wxYES_NO|wxICON_WARNING,
this)==wxNO)
287 wxCommandEvent dummy;
295 wxMessageBox(wxString::Format(_(
"Directory %s does not exist.\nPlease give an existing directory."),
m_start_dir.c_str()),
296 _(
"Warning"),wxOK | wxICON_EXCLAMATION,
this);
308 for(
unsigned int i=0; i<
m_list_pano->GetCount(); i++)
317 wxMessageBox(_(
"You have selected no possible panorama.\nPlease select at least one panorama and try again."),_(
"Warning"),wxOK|wxICON_EXCLAMATION,
this);
322 for(
unsigned int i=0; i<
m_list_pano->GetCount(); i++)
328 if(!filename.IsEmpty())
340 wxMessageBox(_(
"Not all project files could be written successfully.\nMaybe you have no write permission for these directories or your disc is full."),_(
"Error"),wxOK,
this);
359 if (selected != wxNOT_FOUND)
361 XRCCTRL(*
this,
"find_pano_selected_cam", wxStaticText)->SetLabel(
m_panos[selected]->GetCameraName());
362 XRCCTRL(*
this,
"find_pano_selected_lens", wxStaticText)->SetLabel(
m_panos[selected]->GetLensName());
363 XRCCTRL(*
this,
"find_pano_selected_focallength", wxStaticText)->SetLabel(
m_panos[selected]->
GetFocalLength());
364 XRCCTRL(*
this,
"find_pano_selected_date_time", wxStaticText)->SetLabel(
m_panos[selected]->GetStartString() + wxT(
" (")+
m_panos[selected]->GetDuration() + wxT(
")"));
369 XRCCTRL(*
this,
"find_pano_selected_cam", wxStaticText)->SetLabel(wxEmptyString);
370 XRCCTRL(*
this,
"find_pano_selected_lens", wxStaticText)->SetLabel(wxEmptyString);
371 XRCCTRL(*
this,
"find_pano_selected_focallength", wxStaticText)->SetLabel(wxEmptyString);
372 XRCCTRL(*
this,
"find_pano_selected_date_time", wxStaticText)->SetLabel(wxEmptyString);
383 const int selectedPano =
m_list_pano->GetSelection();
384 if (
m_panos[selectedPano]->GetImageCount() > 2)
388 long imageIndex = -1;
389 imageIndex =
m_thumbsList->GetNextItem(imageIndex, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
390 if(imageIndex > 1 && imageIndex <= static_cast<long>(
m_panos[selectedPano]->GetImageCount()) - 2)
392 contextMenu.Append(
ID_SPLIT_PANOS, _(
"Split here into two panoramas"));
395 if (contextMenu.GetMenuItemCount() > 0)
397 PopupMenu(&contextMenu);
403 const int selectedPano =
m_list_pano->GetSelection();
404 if (selectedPano != wxNOT_FOUND)
406 if (
m_panos[selectedPano]->GetImageCount() > 2)
408 long imageIndex = -1;
409 imageIndex =
m_thumbsList->GetNextItem(imageIndex, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
410 if (imageIndex != wxNOT_FOUND)
413 m_panos[selectedPano]->RemoveImage(imageIndex);
419 wxCommandEvent dummy;
428 const int selectedPano =
m_list_pano->GetSelection();
429 if (selectedPano != wxNOT_FOUND)
431 long imageIndex = -1;
432 imageIndex =
m_thumbsList->GetNextItem(imageIndex, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
433 if (imageIndex != wxNOT_FOUND)
435 if (imageIndex > 1 && imageIndex <= static_cast<long>(
m_panos[selectedPano]->GetImageCount()) - 2)
448 wxCommandEvent dummy;
469 if (item != wxNOT_FOUND && (flags&wxLIST_HITTEST_ONITEM) && item <
m_tooltips.GetCount())
481 return doj::alphanum_comp(std::string(s1.mb_str(wxConvLocal)),std::string(s2.mb_str(wxConvLocal)));
484 void FindPanoDialog::SearchInDir(wxString dirstring,
const bool includeSubdir,
const bool loadDistortion,
const bool loadVignetting,
const size_t minNumberImages,
const size_t maxTimeDiff)
486 std::vector<PossiblePano*> newPanos;
487 wxTimeSpan max_diff(0, 0, maxTimeDiff, 0);
489 wxArrayString fileList;
490 wxDir::GetAllFiles(dirstring,&fileList,wxEmptyString,wxDIR_FILES|wxDIR_HIDDEN);
493 for(
size_t j=0; j<fileList.size() && !
m_stopped; j++)
495 m_statustext->SetLabel(wxString::Format(_(
"Reading file %s"),fileList[j].c_str()));
496 wxFileName file(fileList[j]);
498 wxString ext=file.GetExt();
499 if(ext.CmpNoCase(wxT(
"jpg"))==0 || ext.CmpNoCase(wxT(
"jpeg"))==0 ||
500 ext.CmpNoCase(wxT(
"tif"))==0 || ext.CmpNoCase(wxT(
"tiff"))==0)
504 img->setFilename(filenamestr);
508 HuginBase::FileMetaData::const_iterator it = metadata.find(
"pixeltype");
509 if (it != metadata.end())
511 if (it->second ==
"BILEVEL")
513 wxGetApp().Yield(
true);
517 img->applyEXIFValues();
518 if(!img->getExifMake().empty() && !img->getExifModel().empty() &&
519 img->getExifFocalLength()!=0 && img->getCropFactor()!=0)
521 img->readProjectionFromDB(
false);
524 img->readDistortionFromDB();
528 img->readVignettingFromDB();
531 for(
unsigned int i=0; i<newPanos.size() && !
m_stopped && !found; i++)
534 if(newPanos[i]->BelongsTo(img,max_diff))
536 newPanos[i]->AddSrcPanoImage(img);
541 wxGetApp().Yield(
true);
548 newPanos.push_back(newPano);
558 wxGetApp().Yield(
true);
562 for(
size_t i=0; i<newPanos.size(); i++)
564 if(newPanos[i]->GetImageCount()>=minNumberImages)
566 m_panos.push_back(newPanos[i]);
580 wxDir dir(dirstring);
581 bool cont=dir.GetFirst(&filename,wxEmptyString,wxDIR_DIRS);
584 SearchInDir(dir.GetName()+wxFileName::GetPathSeparator()+filename,includeSubdir, loadDistortion, loadVignetting, minNumberImages, maxTimeDiff);
585 cont=dir.GetNext(&filename);
598 m_statustext->SetLabel(wxString::Format(_(
"Found %d possible panoramas"), static_cast<int>(
m_panos.size())));
602 m_statustext->SetLabel(_(
"No possible panoramas found"));
612 for(ImageSet::reverse_iterator it=
m_images.rbegin(); it!=
m_images.rend(); ++it)
621 if(
m_make.compare(img->getExifMake())!=0)
625 if(
m_camera.compare(img->getExifModel())!=0)
629 if(
m_lens.compare(img->getExifLens())!=0)
641 if(
m_size!=img->getSize())
654 struct tm exifdatetime;
657 return wxDateTime(exifdatetime);
662 return file.GetModificationTime();
671 m_make=img->getExifMake();
673 m_lens=img->getExifLens();
697 ImageSet::const_iterator it=
m_images.begin();
699 f1.MakeRelativeTo(BasePath);
700 ImageSet::const_reverse_iterator rit=
m_images.rbegin();
704 return f1.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR)+f1.GetName()+wxT(
"-")+f2.GetName();
708 return f1.GetFullPath()+wxT(
" - ")+f2.GetFullName();
714 return wxString::Format(_(
"%d images: %s"), static_cast<int>(
m_images.size()),
GetFilestring(BasePath).c_str());
721 projectFile.SetPath(basePath);
722 projectFile.SetName(wxT(
"pano"));
723 projectFile.SetExt(wxT(
"pto"));
724 if(!projectFile.IsDirWritable())
731 mask=wxT(
"panorama%d");
735 projectFile.SetName(mask);
736 if(!projectFile.FileExists())
740 mask=mask+wxT(
"_%d");
744 wxArrayString folders=projectFile.GetDirs();
745 if(folders.GetCount()==0)
750 projectFile.SetName(mask);
751 if(!projectFile.FileExists())
755 mask=mask+wxT(
"_%d");
764 mask=newProject.GetName();
765 projectFile.SetName(mask);
766 if(!projectFile.FileExists())
770 mask=mask+wxT(
"_%d");
774 mask=wxT(
"panorama%d");
777 projectFile.SetName(wxString::Format(mask,i));
778 while(projectFile.FileExists())
781 projectFile.SetName(wxString::Format(mask,i));
795 return wxEmptyString;
797 ImageSet::const_iterator it=
m_images.begin();
799 firstFile.MakeAbsolute();
800 wxFileName projectFile;
803 return wxEmptyString;
806 double redBalanceAnchor = (*
m_images.begin())->getExifRedBalance();
807 double blueBalanceAnchor = (*
m_images.begin())->getExifBlueBalance();
808 if (fabs(redBalanceAnchor)<1e-2)
810 redBalanceAnchor = 1;
812 if (fabs(blueBalanceAnchor)<1e-2)
814 blueBalanceAnchor = 1;
819 (*it)->setWhiteBalanceRed((*it)->getExifRedBalance() / redBalanceAnchor);
820 (*it)->setWhiteBalanceBlue((*it)->getExifBlueBalance() / blueBalanceAnchor);
841 wxConfigBase* config = wxConfigBase::Get();
887 opts.
verdandiOptions = config->Read(wxT(
"/VerdandiDefaultArgs"), wxEmptyString).mb_str(wxConvLocal);
894 std::string(projectFile.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR).mb_str(
HUGIN_CONV_FILENAME))))
896 return projectFile.GetFullPath();
900 return wxEmptyString;
906 return wxString(
m_camera.c_str(), wxConvLocal);
911 return wxString(
m_lens.c_str(), wxConvLocal);
931 if (diff.GetSeconds() > 60)
933 return diff.Format(_(
"%M:%S min"));
937 return diff.Format(_(
"%S s"));
943 list->DeleteAllItems();
949 #if defined EXIV2_VERSION && EXIV2_TEST_VERSION(0,27,99)
950 Exiv2::Image::UniquePtr image;
952 Exiv2::Image::AutoPtr image;
957 image = Exiv2::ImageFactory::open((*it)->getFilename().c_str());
962 std::cerr << __FILE__ <<
" " << __LINE__ <<
" Error opening file" << std::endl;
970 image->readMetadata();
972 catch (
const Exiv2::Error& e)
974 std::cerr << __FILE__ <<
" " << __LINE__ <<
" Exiv2: Error reading metadata (" << e.what() <<
")" << std::endl;
978 Exiv2::PreviewManager previews(*image);
979 Exiv2::PreviewPropertiesList lists = previews.getPreviewProperties();
983 int previewIndex = 0;
984 while (previewIndex < lists.size() - 1 && lists[previewIndex].width_ <
THUMBSIZE && lists[previewIndex].height_ <
THUMBSIZE)
990 Exiv2::PreviewImage previewImage = previews.getPreviewImage(lists[previewIndex]);
991 wxMemoryInputStream stream(previewImage.pData(), previewImage.size());
992 rawImage.LoadFile(stream, wxString(previewImage.mimeType().c_str(), wxConvLocal), -1);
995 if (previewImage.width() > previewImage.height())
998 int newHeight =
THUMBSIZE*previewImage.height() / previewImage.width();
1006 int newWidth =
THUMBSIZE*previewImage.width() / previewImage.height();
1012 if ((*it)->getRoll() == 90)
1014 rawImage = rawImage.Rotate90();
1019 if ((*it)->getRoll() == 270)
1021 rawImage = rawImage.Rotate90(
false);
1026 if ((*it)->getRoll() == 180)
1028 rawImage = rawImage.Rotate180();
1034 wxMemoryDC dc(bitmap);
1035 dc.SetBackground(list->GetBackgroundColour());
1037 dc.DrawBitmap(rawImage, x, y);
1038 dc.SelectObject(wxNullBitmap);
1044 index = thumbs->Add(bitmap, wxBitmap(mask, 1));
1049 list->InsertItem(list->GetItemCount(), fn.GetFullName(), index);
1062 ImageSet::iterator item =
m_images.begin();
1063 std::advance(item, index);
1079 ImageSet::iterator img = allImages.begin();
1080 while (
m_images.size() < index && img != allImages.end())
1085 while (img != allImages.end())
1107 if (dt.IsLaterThan(m_dt_end))
wxString GetFocalLength()
returns the focal length as string
int alphanum_comp(const std::string &l, const std::string &r)
Compare l and r with the same semantics as strcmp(), but with the "Alphanum Algorithm" which produces...
static void swap(T &x, T &y)
#define HUGIN_NONA_CROPPEDIMAGES
unsigned int getPartNumber(unsigned int imageNr) const
Get a part number from an image number.
BlendingMechanism
blenders
wxSpinCtrl * m_sc_maxTimeDiff
void AddSrcPanoImage(HuginBase::SrcPanoImage *img)
adds the given SrcPanoImage to this pano-group
#define HUGIN_JPEG_QUALITY
~PossiblePano()
destructor, cleans up used variables
void setPhotometricOptimizerSwitch(const int newSwitch)
sets the photometric optimizer master switch
Somewhere to specify what variables belong to what.
void AddToList(wxString aFile, Project::Target target=Project::STITCHING, wxString userDefined=wxEmptyString)
void RemoveImage(const unsigned int index)
removes the image at given index
void EnableButtons(const bool state)
std::string enfuseOptions
wxButton * m_button_start
include file for the hugin project
wxCheckBox * m_cb_loadDistortion
std::string outputImageTypeCompression
wxString GetCameraName()
returns the camera name
void setOptimizerSwitch(const int newSwitch)
set optimizer master switch
wxCheckBox * m_cb_createLinks
Batch processor for Hugin with GUI.
int SortWxFilenames(const wxString &s1, const wxString &s2)
void OnButtonClose(wxCommandEvent &e)
closes window
wxCheckBox * m_cb_loadVignetting
void UpdateDateTimes()
updates the internal date/time representations
void linkPossibleStacks(bool linkPosition)
create automatically stacks as indicated by metadata
PossiblePano * SplitPano(const unsigned int index)
split pano into 2 subpanos, index is used as first image of second pano
BatchFrame * m_batchframe
some definitions to work with optimizer master switches
const wxString GetFilestring(const wxString BasePath, const bool stripExtension=false) const
returns a string with the filename of the first and last file
wxString GetDuration()
returns the duration as string
void PopulateListCtrl(wxListCtrl *list, wxImageList *thumbs, wxArrayString &tooltips)
add all images to wxListCtrl
std::size_t getNrOfImages() const
number of images.
void SearchInDir(wxString dirstring, const bool includeSubdir, const bool loadDistortion, const bool loadVignetting, const size_t minNumberImages, const size_t maxTimeDiff)
const int getExifDateTime(struct tm *datetime) const
try to convert Exif date time string to struct tm
void OnSplitPanos(wxCommandEvent &e)
event handler to split into 2 panos
vigra_ext::Interpolator interpolator
const unsigned int GetImageCount() const
returns number of images in this group
Definition of dialog to change user defined sequence.
wxString GetStartString()
return the start date/time as string
ImageVariableGroup & getLenses()
Get the ImageVariableGroup representing the group of lens variables.
#define HUGIN_NONA_INTERPOLATOR
#define HUGIN_TIFF_COMPRESSION
void OnListMouseMove(wxMouseEvent &e)
mouse move handler for tooltips
std::map< std::string, std::string > FileMetaData
typedef for general map for storing metadata in files
wxString GetLensName()
returns the lens name
std::set< HuginBase::SrcPanoImage *, SortFilename > ImageSet
std::string stripExtension(const std::string &basename2)
remove extension of a filename
TIFFErrorHandler m_oldtiffwarning
void OnSelectPossiblePano(wxCommandEvent &e)
event to populate information on the right
wxStaticText * m_statustext
void OnListItemRightClick(wxListEvent &e)
event handler for context menu
#define HUGIN_HDRMERGE_ARGS
#define HUGIN_LDR_OUTPUT_FORMAT
bool BelongsTo(HuginBase::SrcPanoImage *img, const wxTimeSpan max_time_diff)
return true, if the image could belong to the given PossiblePano, it checks camera maker and model...
unsigned int addImage(const SrcPanoImage &img)
the the number for a specific image
wxTextCtrl * m_textctrl_dir
std::string tiffCompression
std::string verdandiOptions
Same as above, but use a non const panorama.
wxButton * m_button_close
NamingConvention
enumeration for different naming conventions, must be match combobox in ressource ...
std::string enblendOptions
const PanoramaOptions & getOptions() const
returns the options for this panorama
wxString GeneratePanorama(NamingConvention nc, bool createLinks, HuginBase::PanoramaOptions::BlendingMechanism defaultBlender)
generates the panorama file from this set of images
HDRMergeType hdrMergeMode
wxListCtrl * m_thumbsList
bool GetNewProjectFilename(NamingConvention nc, const wxString basePath, wxFileName &projectFile)
returns a given filename, which does not already exists
#define HUGIN_ENFUSE_ARGS
bool readEXIF()
try to fill out information about the image, by examining the exif data
const wxDateTime GetDateTime(const HuginBase::SrcPanoImage *img)
does some reformating date/time format
PossiblePano()
constructor, init values
std::string outputImageType
void OnClose(wxCloseEvent &e)
prevents closing window when running detection
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
wxSpinCtrl * m_sc_minNumberImages
~FindPanoDialog()
destructor, saves size and position
std::string hdrmergeOptions
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
FindPanoDialog(BatchFrame *batchframe, wxString xrcPrefix)
Constructor, read from xrc ressource; restore last uses settings, size and position.
const wxString GetItemString(const wxString BasePath) const
returns a string which contains description of this pano
void OnRemoveImage(wxCommandEvent &e)
event handler to remove selected image from list
void setOptions(const PanoramaOptions &opt)
set new output settings This is not used directly for optimizing/stiching, but it can be feed into ru...
Dialog for finding panorama in given directory.
Interpolator
enum with all interpolation methods
All variables of a source image.
void switchParts(unsigned int ImageNr, unsigned int partNr)
switch a given image to a different part number.
const bool hasPossibleStacks() const
return true, if the metadata indicates that the projects is a bracketet project
wxButton * m_button_choose
#define HUGIN_ENBLEND_ARGS
void OnButtonSend(wxCommandEvent &e)
add selected projects to queue
wxString getDefaultProjectName(const HuginBase::Panorama &pano, const wxString filenameTemplate)
gets the default project name, as defined in the preferences
void OnButtonChoose(wxCommandEvent &e)
select directory with dialog
BlendingMechanism blendMode
wxCheckListBox * m_list_pano
void OnButtonStart(wxCommandEvent &e)
start/stops detections
std::vector< PossiblePano * > m_panos
double outputExposureValue