48 #define DEFAULT_LENSCAL_SCALE 2.0
49 #define DEFAULT_LENSCAL_THRESHOLD 4.0
50 #define DEFAULT_RESIZE_DIMENSION 1600
51 #define DEFAULT_MINLINELENGTH 0.3
63 wxArrayString invalidFiles;
64 for (
unsigned int i=0; i< filenames.GetCount(); i++)
66 wxFileName file(filenames[i]);
67 if (file.GetExt().CmpNoCase(
"jpg") == 0 ||
68 file.GetExt().CmpNoCase(
"jpeg") == 0 ||
69 file.GetExt().CmpNoCase(
"tif") == 0 ||
70 file.GetExt().CmpNoCase(
"tiff") == 0 ||
71 file.GetExt().CmpNoCase(
"png") == 0 ||
72 file.GetExt().CmpNoCase(
"bmp") == 0 ||
73 file.GetExt().CmpNoCase(
"gif") == 0 ||
74 file.GetExt().CmpNoCase(
"pnm") == 0 ||
75 file.GetExt().CmpNoCase(
"sun") == 0 ||
76 file.GetExt().CmpNoCase(
"hdr") == 0 ||
77 file.GetExt().CmpNoCase(
"viff") == 0 )
81 invalidFiles.push_back(file.GetFullPath());
85 files.push_back(file.GetFullPath());
89 if(!invalidFiles.empty())
107 wxXmlResource::Get()->LoadFrame(
this, parent,
"lenscal_frame");
112 wxApp::s_macExitMenuItemId = XRCID(
"menu_quit");
114 SetMenuBar(wxXmlResource::Get()->LoadMenuBar(
this,
"lenscal_menubar"));
118 m_images_list=XRCCTRL(*
this,
"lenscal_images_list",wxListBox);
122 wxConfigBase* config = wxConfigBase::Get();
130 config->Read(
"/LensCalFrame/Optimize_a",&selected,
false);
131 XRCCTRL(*
this,
"lenscal_opt_a",wxCheckBox)->SetValue(selected);
132 config->Read(
"/LensCalFrame/Optimize_b",&selected,
true);
133 XRCCTRL(*
this,
"lenscal_opt_b",wxCheckBox)->SetValue(selected);
134 config->Read(
"/LensCalFrame/Optimize_c",&selected,
false);
135 XRCCTRL(*
this,
"lenscal_opt_c",wxCheckBox)->SetValue(selected);
136 config->Read(
"/LensCalFrame/Optimize_de",&selected,
false);
137 XRCCTRL(*
this,
"lenscal_opt_de",wxCheckBox)->SetValue(selected);
141 wxIconBundle myIcons(
GetXRCPath() +
"data/hugin.ico", wxBITMAP_TYPE_ICO);
144 wxIcon myIcon(
GetXRCPath() +
"data/hugin.png",wxBITMAP_TYPE_PNG);
147 SetTitle(_(
"Hugin Lens calibration GUI"));
153 const int fields (2);
154 CreateStatusBar(fields);
155 int widths[fields] = {-1, 85};
156 SetStatusWidths( fields, &widths[0]);
160 #if defined __WXMAC__ || defined __WXMSW__
162 SetSizeHints(900, 675);
165 SetSizeHints(780, 455);
169 ImageCache::getInstance().setProgressDisplay(
this);
170 #if defined __WXMSW__
173 unsigned long mem_high = config->Read(
"/ImageCache/UpperBoundHigh", (
long) 0);
175 mem = ((
unsigned long long) mem_high << 32) + mem_low;
180 ImageCache::getInstance().SetUpperLimit(mem);
199 XRCCTRL(*
this,
"lenscal_remove_image", wxButton)->Enable(
false);
206 ImageCache::getInstance().setProgressDisplay(0);
207 delete & ImageCache::getInstance();
209 wxConfigBase* config = wxConfigBase::Get();
217 config->Write(
"/LensCalFrame/Optimize_a",XRCCTRL(*
this,
"lenscal_opt_a",wxCheckBox)->GetValue());
218 config->Write(
"/LensCalFrame/Optimize_b",XRCCTRL(*
this,
"lenscal_opt_b",wxCheckBox)->GetValue());
219 config->Write(
"/LensCalFrame/Optimize_c",XRCCTRL(*
this,
"lenscal_opt_c",wxCheckBox)->GetValue());
220 config->Write(
"/LensCalFrame/Optimize_de",XRCCTRL(*
this,
"lenscal_opt_de",wxCheckBox)->GetValue());
224 for(
unsigned int i=0;i<
m_images.size();i++)
237 XRCCTRL(*
this,
"lenscal_resizedim", wxTextCtrl)->SetValue(wxString::Format(
"%d",
m_resize_dimension));
243 return wxGetApp().GetXRCPath();
252 msg = wxGetTranslation(wxString(
m_message.c_str(), wxConvLocal));
259 GetStatusBar()->SetStatusText(msg, 0);
273 wxArrayString wrongSize;
274 wxArrayString wrongExif;
275 for (
unsigned int i=0; i<files.GetCount(); i++)
282 HuginBase::FileMetaData::const_iterator it = metadata.find(
"pixeltype");
283 if (it != metadata.end())
285 if (it->second ==
"BILEVEL")
287 hugin_utils::HuginMessageBox(wxString::Format(_(
"File \"%s\" is a black/white image.\nHugin does not support this image type. Skipping this image.\nConvert image to grayscale image and try loading again."), files[i].c_str()),
288 _(
"Calibrate_lens_GUI"), wxOK | wxICON_EXCLAMATION,
this);
298 if(image0->getSize()!=image1->getSize())
300 wrongSize.push_back(files[i]);
304 if(!image0->getExifMake().empty() && !image1->getExifMake().empty() &&
305 !image0->getExifModel().empty() && !image1->getExifModel().empty() &&
306 image0->getExifFocalLength()>0 && image1->getExifFocalLength()>0 &&
307 image0->getCropFactor()>0 && image1->getCropFactor()>0
310 if(image0->getExifMake()!=image1->getExifMake() ||
311 image0->getExifModel()!=image1->getExifModel() ||
312 image0->getExifFocalLength()!=image1->getExifFocalLength() ||
313 image0->getCropFactor()!=image1->getCropFactor())
316 wrongExif.push_back(files[i]);
321 SetStatusText(wxString::Format(_(
"Added %s"),image->
GetFilename().c_str()));
324 XRCCTRL(*
this,
"lenscal_focallength", wxTextCtrl)->SetValue(
330 XRCCTRL(*
this,
"lenscal_cropfactor", wxTextCtrl)->SetValue(
341 if(!wrongSize.empty())
344 for(
unsigned int i=0;i<wrongSize.size();i++)
346 wxFileName filename(wrongSize[i]);
347 fileText.Append(filename.GetFullName());
348 if(i<wrongSize.size()-1)
349 fileText.Append(
", ");
351 hugin_utils::HuginMessageBox(wxString::Format(_(
"The size of the images (%s) does not match the already added image(s)."), fileText.c_str()),
352 _(
"Calibrate_lens_GUI"), wxOK | wxICON_EXCLAMATION,
this);
354 if(!wrongExif.empty())
357 for(
unsigned int i=0;i<wrongExif.size();i++)
359 wxFileName filename(wrongExif[i]);
360 fileText.Append(filename.GetFullName());
361 if(i<wrongExif.size()-1)
362 fileText.Append(
", ");
364 hugin_utils::HuginMessageBox(wxString::Format(_(
"The EXIF information of the added images (%s) is not consistent with the already added image(s).\nPlease check the image again, if you selected the correct images."), fileText.c_str()),
365 _(
"Calibrate_lens_GUI"), wxOK | wxICON_EXCLAMATION,
this);
371 wxConfigBase* config = wxConfigBase::Get();
372 wxString path = config->Read(
"/actualPath", wxEmptyString);
373 wxFileDialog dlg(
this,_(
"Add images"),
376 wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST | wxFD_PREVIEW, wxDefaultPosition);
377 dlg.SetDirectory(path);
381 if (config->HasEntry(
"lastImageType")){
382 img_ext = config->Read(
"lastImageType").c_str();
384 if (img_ext ==
"all images")
385 dlg.SetFilterIndex(0);
386 else if (img_ext ==
"jpg")
387 dlg.SetFilterIndex(1);
388 else if (img_ext ==
"tiff")
389 dlg.SetFilterIndex(2);
390 else if (img_ext ==
"png")
391 dlg.SetFilterIndex(3);
392 else if (img_ext ==
"hdr")
393 dlg.SetFilterIndex(4);
394 else if (img_ext ==
"exr")
395 dlg.SetFilterIndex(5);
396 else if (img_ext ==
"all files")
397 dlg.SetFilterIndex(6);
398 DEBUG_INFO (
"Image extention: " << img_ext.mb_str(wxConvLocal) )
401 if (dlg.ShowModal() == wxID_OK)
404 wxArrayString Pathnames;
405 dlg.GetPaths(Pathnames);
410 config->Write(
"/actualPath", wxPathOnly(Pathnames[0]));
412 config->Write(
"/actualPath", dlg.GetDirectory());
415 wxArrayString invalidFiles;
416 for(
unsigned int i=0;i<Pathnames.GetCount(); i++)
420 invalidFiles.push_back(Pathnames[i]);
423 if(!invalidFiles.empty())
431 DEBUG_INFO ( wxString::Format(
"img_ext: %d", dlg.GetFilterIndex()).mb_str(wxConvLocal) )
433 switch ( dlg.GetFilterIndex() )
435 case 0: config->Write(
"lastImageType",
"all images");
break;
436 case 1: config->Write(
"lastImageType",
"jpg");
break;
437 case 2: config->Write(
"lastImageType",
"tiff");
break;
438 case 3: config->Write(
"lastImageType",
"png");
break;
439 case 4: config->Write(
"lastImageType",
"hdr");
break;
440 case 5: config->Write(
"lastImageType",
"exr");
break;
441 case 6: config->Write(
"lastImageType",
"all files");
break;
447 SetStatusText( _(
"Add Image: cancel"));
454 wxFileName file(
m_images[index]->GetFilename());
455 m_images_list->SetString(index,wxString::Format(_(
"%s (%d lines)"),file.GetFullName().c_str(),
m_images[index]->GetNrOfValidLines()));
462 for(
unsigned int i=0;i<
m_images.size();i++)
464 wxFileName file(
m_images[i]->GetFilename());
465 wxString text=wxString::Format(_(
"%s (%d lines)"),file.GetFullName().c_str(),
m_images[i]->GetNrOfValidLines());
468 if(oldSelection!=wxNOT_FOUND && restoreSelection)
479 if(selection!=wxNOT_FOUND)
483 ImageCache::getInstance().removeImage(filename);
497 const bool enabling = !
m_images.empty();
498 XRCCTRL(*
this,
"lenscal_find_lines",wxButton)->Enable(enabling);
499 XRCCTRL(*
this,
"lenscal_opt",wxButton)->Enable(enabling);
500 XRCCTRL(*
this,
"lenscal_show_distortion_graph", wxButton)->Enable(enabling);
501 XRCCTRL(*
this,
"lenscal_save_lens",wxButton)->Enable(enabling);
502 GetMenuBar()->Enable(XRCID(
"menu_save"),enabling);
533 if(m_minlinelength<=0 || m_minlinelength>1)
536 if(readLensParameter)
556 hugin_utils::HuginMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."), _(
"Calibrate_lens_GUI"), wxOK | wxICON_INFORMATION,
this);
560 for(
unsigned int i=0;i<
m_images.size();i++)
563 ImageCache::EntryPtr img=ImageCache::getInstance().getImage(filename);
565 SetStatusText(_(
"Detecting edges..."));
567 SetStatusText(_(
"Finding lines..."));
571 SetStatusText(_(
"Finished"));
579 hugin_utils::HuginMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."), _(
"Calibrate_lens_GUI"), wxOK | wxICON_INFORMATION,
this);
582 unsigned int count=0;
583 for(
unsigned int i=0;i<
m_images.size();i++)
584 count+=
m_images[i]->GetNrOfValidLines();
587 hugin_utils::HuginMessageBox(_(
"There are no detected lines.\nPlease run \"Find lines\" first. If there are no lines found, change the parameters."), _(
"Calibrate_lens_GUI"), wxOK | wxICON_INFORMATION,
this);
601 hugin_utils::HuginMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."), _(
"Calibrate_lens_GUI"), wxOK | wxICON_INFORMATION,
this);
617 wxWindow *button = (wxWindow*)e.GetEventObject();
618 wxPoint pos = button->ClientToScreen(wxPoint(0, 0));
619 m_popup->Position(pos, button->GetSize());
627 unsigned int line_number=3;
628 for(
unsigned int i=0;i<
m_images.size();i++)
642 std::set<std::string> imgopt;
645 if(XRCCTRL(*
this,
"lenscal_opt_a",wxCheckBox)->GetValue())
647 if(XRCCTRL(*
this,
"lenscal_opt_b",wxCheckBox)->GetValue())
649 if(XRCCTRL(*
this,
"lenscal_opt_c",wxCheckBox)->GetValue())
651 if(XRCCTRL(*
this,
"lenscal_opt_de",wxCheckBox)->GetValue())
657 optvec.push_back(imgopt);
660 for(
unsigned j=0;j<lines.size();j++)
665 for(
unsigned int k=0;k<cpv.size();k++)
680 img.setExposureValue(0);
681 img.setWhiteBalanceRed(1);
682 img.setWhiteBalanceBlue(1);
698 SetStatusText(_(
"Optimizing lens distortion parameters..."));
714 SetStatusText(_(
"Finished"));
719 wxFileDialog dlg(
this,
720 _(
"Save lens parameters file"),
721 wxConfigBase::Get()->Read(
"/lensPath",wxEmptyString), wxEmptyString,
722 _(
"Lens Project Files (*.ini)|*.ini|All files (*)|*"),
723 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
724 dlg.SetDirectory(wxConfigBase::Get()->Read(
"/lensPath",wxEmptyString));
725 if (dlg.ShowModal() == wxID_OK)
727 wxFileName filename(dlg.GetPath());
728 if(!filename.HasExt())
729 filename.SetExt(
"ini");
730 wxConfig::Get()->Write(
"/lensPath", dlg.GetDirectory());
731 if (filename.FileExists())
747 hugin_utils::HuginMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."), _(
"Calibrate_lens_GUI"), wxOK | wxICON_INFORMATION,
this);
750 unsigned int count=0;
751 for(
unsigned int i=0;i<
m_images.size();i++)
752 count+=
m_images[i]->GetNrOfValidLines();
755 hugin_utils::HuginMessageBox(_(
"There are no detected lines.\nPlease run \"Find lines\" and \"Optimize\" before saving the lens data. If there are no lines found, change the parameters."), _(
"Calibrate_lens_GUI"), wxOK | wxICON_INFORMATION,
this);
759 wxArrayString choices;
760 choices.push_back(_(
"Save lens parameters to ini file"));
761 choices.push_back(_(
"Save lens parameters to lens database"));
762 wxSingleChoiceDialog save_dlg(
this,_(
"Saving lens data"),_(
"Save lens"),choices);
763 if(save_dlg.ShowModal()==wxID_OK)
765 if(save_dlg.GetSelection()==0)
781 hugin_utils::HuginMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."), _(
"Calibrate_lens_GUI"), wxOK | wxICON_INFORMATION,
this);
785 wxFileDialog dlg(
this,_(
"Save project file"),wxEmptyString,wxEmptyString,
786 _(
"Project files (*.pto)|*.pto|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
787 dlg.SetDirectory(wxConfigBase::Get()->Read(
"/actualPath",wxEmptyString));
788 if (dlg.ShowModal() == wxID_OK)
790 wxConfig::Get()->Write(
"/actualPath", dlg.GetDirectory());
791 wxFileName filename(dlg.GetPath());
792 if(!filename.HasExt())
793 filename.SetExt(
"pto");
794 if (filename.FileExists())
810 XRCCTRL(*
this,
"lenscal_remove_image",wxButton)->Enable(selected);
846 hugin_utils::HuginMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."), _(
"Calibrate_lens_GUI"), wxOK | wxICON_INFORMATION,
this);
bool AskUserOverwrite(const wxString &filename, const wxString &caption, wxWindow *parent)
ask user if the given file should be overwritten, return true if the user confirmed the overwritting ...
void SetEmptyImage()
set preview to empty image
LensCalImageCtrl * m_preview
unsigned int getPartNumber(unsigned int imageNr) const
Get a part number from an image number.
const unsigned int cps_per_line
bool str2double(const wxString &s, double &d)
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
image previewer for lens calibration GUI
HuginBase::SrcPanoImage * GetPanoImage()
return the SrcPanoImage from the given filename
Somewhere to specify what variables belong to what.
wxChoice * m_choice_projection
void OnSelectPreviewContent(wxCommandEvent &e)
wxString doubleTowxString(double d, int digits)
include file for the hugin project
void OnSaveLens(wxCommandEvent &e)
declaration of LensCal main frame class
Lines findLines(vigra::BImage &edge, double length_threshold, double focal_length, double crop_factor)
find straightish non-crossing lines find straightish non-crossing lines in an edge map using 8-neighb...
void setOptimizeVector(const OptimizeVector &optvec)
set optimize setting
static void Clean()
cleanup the static LensDB instance, must be called at the end of the program
simple class that forward the drop to the mainframe
virtual ~LensCalFrame()
destructor
class to access Hugins camera and lens database
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
file drag and drop handler method
void OnRefresh(wxCommandEvent &e)
unsigned int addCtrlPoint(const ControlPoint &point)
add a new control point.
#define HUGIN_IMGCACHE_UPPERBOUND
void Optimize()
do the optimization
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
LensCalFrame(wxWindow *parent)
constructor
void OnShowLines(wxCommandEvent &e)
void OnShowDistortionGraph(wxCommandEvent &e)
show distortion graph
unsigned int m_resize_dimension
void setVar(const std::string &name, double val)
HuginBase::CPVector GetControlPoints(const SingleLine &line, const unsigned int imgNr, const unsigned int lineNr, const unsigned int numberOfCtrlPoints)
returns a HuginBase::CPVector with cps_per_lines
std::size_t getNrOfImages() const
number of images.
void updateProgressDisplay()
called when a progress message should be displayed
void OnAddImage(wxCommandEvent &e)
void OnImageSelected(wxCommandEvent &e)
#define DEFAULT_RESIZE_DIMENSION
ImageVariableGroup & getLenses()
Get the ImageVariableGroup representing the group of lens variables.
std::map< std::string, std::string > FileMetaData
typedef for general map for storing metadata in files
void EnableButtons()
enable all buttons and menu items depending on number of active images
void UpdateListString(unsigned int index)
double getVar(const std::string &name) const
HuginBase::SrcPanoImage::Projection m_projection
wxGraphTools::GraphPopupWindow * m_popup
void OnReset(wxCommandEvent &e)
vigra::BImage * detectEdges(const vigra::UInt8RGBImage &input, const double scale, const double threshold, const unsigned int resize_dimension, double &size_factor)
detect and mark edges in an edge image using Canny's algorithm
!! from PTOptimise.h 1951
dialogs for loading and saving information from/to lens database
unsigned int addImage(const SrcPanoImage &img)
the the number for a specific image
void OnOptimize(wxCommandEvent &e)
Same as above, but use a non const panorama.
void StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
bool ReadInputs(bool readFocalLength, bool readOptions, bool readLensParameter)
reads all input values into internal values
void OnFindLines(wxCommandEvent &e)
include file for the hugin project
const PanoramaOptions & getOptions() const
returns the options for this panorama
const wxString & GetXRCPath()
get the path to the xrc directory
#define DEFAULT_LENSCAL_THRESHOLD
const LensCalPreviewMode GetMode()
return actual preview mode
std::vector< SingleLine > Lines
vector of extracted lines from image
void OnExit(wxCommandEvent &e)
wxListBox * m_images_list
void SetImage(ImageLineList *newList, unsigned int newIndex)
set preview setting to given ImageLineList
std::vector< ControlPoint > CPVector
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
declaration of application class for lens calibrate application
#define DEFAULT_LENSCAL_SCALE
std::vector< ImageLineList * > m_images
list of all detected lines
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
std::vector< std::set< std::string > > OptimizeVector
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
const wxString GetFilename()
returns the filename
void setOptions(const PanoramaOptions &opt)
set new output settings This is not used directly for optimizing/stiching, but it can be feed into ru...
#define DEFAULT_MINLINELENGTH
HuginBase::Panorama GetPanorama()
return panorama object with all images
void setSrcImage(unsigned int nr, const SrcPanoImage &img)
set input image parameters
void SetLens(const HuginBase::SrcPanoImage::Projection newProjection, const double newFocallength, const double newCropfactor)
updates the internal values of the lens (needed only for remapped image)
All variables of a source image.
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
void switchParts(unsigned int ImageNr, unsigned int partNr)
switch a given image to a different part number.
void SetMode(const LensCalPreviewMode newMode)
set which image (original, edge, remapped/corrected) should be drawn
void ParametersToDisplay()
set all parameter input wxTextField to internal values
void SetLensDistortions(const double newA, const double newB, const double newC, const double newD, const double newE)
updates the internal values of the lens distortions parameters (needed only for remapped image) ...
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
void OnRemoveImage(wxCommandEvent &e)
void UpdateList(bool restoreSelection)
updates the list box with current values
void SetShowLines(bool showLines)
void OnSaveProject(wxCommandEvent &e)
void AddImages(wxArrayString files)
double outputExposureValue