47 #define DEFAULT_LENSCAL_SCALE 2.0
48 #define DEFAULT_LENSCAL_THRESHOLD 4.0
49 #define DEFAULT_RESIZE_DIMENSION 1600
50 #define DEFAULT_MINLINELENGTH 0.3
62 wxArrayString invalidFiles;
63 for (
unsigned int i=0; i< filenames.GetCount(); i++)
65 wxFileName file(filenames[i]);
66 if (file.GetExt().CmpNoCase(wxT(
"jpg")) == 0 ||
67 file.GetExt().CmpNoCase(wxT(
"jpeg")) == 0 ||
68 file.GetExt().CmpNoCase(wxT(
"tif")) == 0 ||
69 file.GetExt().CmpNoCase(wxT(
"tiff")) == 0 ||
70 file.GetExt().CmpNoCase(wxT(
"png")) == 0 ||
71 file.GetExt().CmpNoCase(wxT(
"bmp")) == 0 ||
72 file.GetExt().CmpNoCase(wxT(
"gif")) == 0 ||
73 file.GetExt().CmpNoCase(wxT(
"pnm")) == 0 ||
74 file.GetExt().CmpNoCase(wxT(
"sun")) == 0 ||
75 file.GetExt().CmpNoCase(wxT(
"hdr")) == 0 ||
76 file.GetExt().CmpNoCase(wxT(
"viff")) == 0 )
80 invalidFiles.push_back(file.GetFullPath());
84 files.push_back(file.GetFullPath());
88 if(!invalidFiles.empty())
106 wxXmlResource::Get()->LoadFrame(
this, parent, wxT(
"lenscal_frame"));
111 wxApp::s_macExitMenuItemId = XRCID(
"menu_quit");
113 SetMenuBar(wxXmlResource::Get()->LoadMenuBar(
this, wxT(
"lenscal_menubar")));
117 m_images_list=XRCCTRL(*
this,
"lenscal_images_list",wxListBox);
121 wxConfigBase* config = wxConfigBase::Get();
129 config->Read(wxT(
"/LensCalFrame/Optimize_a"),&selected,
false);
130 XRCCTRL(*
this,
"lenscal_opt_a",wxCheckBox)->SetValue(selected);
131 config->Read(wxT(
"/LensCalFrame/Optimize_b"),&selected,
true);
132 XRCCTRL(*
this,
"lenscal_opt_b",wxCheckBox)->SetValue(selected);
133 config->Read(wxT(
"/LensCalFrame/Optimize_c"),&selected,
false);
134 XRCCTRL(*
this,
"lenscal_opt_c",wxCheckBox)->SetValue(selected);
135 config->Read(wxT(
"/LensCalFrame/Optimize_de"),&selected,
false);
136 XRCCTRL(*
this,
"lenscal_opt_de",wxCheckBox)->SetValue(selected);
140 wxIconBundle myIcons(
GetXRCPath() + wxT(
"data/hugin.ico"), wxBITMAP_TYPE_ICO);
143 wxIcon myIcon(
GetXRCPath() + wxT(
"data/hugin.png"),wxBITMAP_TYPE_PNG);
146 SetTitle(_(
"Hugin Lens calibration GUI"));
152 const int fields (2);
153 CreateStatusBar(fields);
154 int widths[fields] = {-1, 85};
155 SetStatusWidths( fields, &widths[0]);
159 #if defined __WXMAC__ || defined __WXMSW__
161 SetSizeHints(900, 675);
164 SetSizeHints(780, 455);
168 ImageCache::getInstance().setProgressDisplay(
this);
169 #if defined __WXMSW__
172 unsigned long mem_high = config->Read(wxT(
"/ImageCache/UpperBoundHigh"), (
long) 0);
174 mem = ((
unsigned long long) mem_high << 32) + mem_low;
179 ImageCache::getInstance().SetUpperLimit(mem);
198 XRCCTRL(*
this,
"lenscal_remove_image", wxButton)->Enable(
false);
205 ImageCache::getInstance().setProgressDisplay(0);
206 delete & ImageCache::getInstance();
208 wxConfigBase* config = wxConfigBase::Get();
211 config->Write(wxT(
"/LensCalFrame/EdgeScale"),
m_edge_scale);
216 config->Write(wxT(
"/LensCalFrame/Optimize_a"),XRCCTRL(*
this,
"lenscal_opt_a",wxCheckBox)->GetValue());
217 config->Write(wxT(
"/LensCalFrame/Optimize_b"),XRCCTRL(*
this,
"lenscal_opt_b",wxCheckBox)->GetValue());
218 config->Write(wxT(
"/LensCalFrame/Optimize_c"),XRCCTRL(*
this,
"lenscal_opt_c",wxCheckBox)->GetValue());
219 config->Write(wxT(
"/LensCalFrame/Optimize_de"),XRCCTRL(*
this,
"lenscal_opt_de",wxCheckBox)->GetValue());
223 for(
unsigned int i=0;i<
m_images.size();i++)
236 XRCCTRL(*
this,
"lenscal_resizedim", wxTextCtrl)->SetValue(wxString::Format(wxT(
"%d"),
m_resize_dimension));
242 return wxGetApp().GetXRCPath();
251 msg = wxGetTranslation(wxString(
m_message.c_str(), wxConvLocal));
254 msg.Append(wxT(
" "));
258 GetStatusBar()->SetStatusText(msg, 0);
272 wxArrayString wrongSize;
273 wxArrayString wrongExif;
274 for (
unsigned int i=0; i<files.GetCount(); i++)
281 HuginBase::FileMetaData::const_iterator it = metadata.find(
"pixeltype");
282 if (it != metadata.end())
284 if (it->second ==
"BILEVEL")
286 wxMessageBox(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()),
287 _(
"Warning"), wxOK | wxICON_EXCLAMATION,
this);
297 if(image0->getSize()!=image1->getSize())
299 wrongSize.push_back(files[i]);
303 if(!image0->getExifMake().empty() && !image1->getExifMake().empty() &&
304 !image0->getExifModel().empty() && !image1->getExifModel().empty() &&
305 image0->getExifFocalLength()>0 && image1->getExifFocalLength()>0 &&
306 image0->getCropFactor()>0 && image1->getCropFactor()>0
309 if(image0->getExifMake()!=image1->getExifMake() ||
310 image0->getExifModel()!=image1->getExifModel() ||
311 image0->getExifFocalLength()!=image1->getExifFocalLength() ||
312 image0->getCropFactor()!=image1->getCropFactor())
315 wrongExif.push_back(files[i]);
320 SetStatusText(wxString::Format(_(
"Added %s"),image->
GetFilename().c_str()));
323 XRCCTRL(*
this,
"lenscal_focallength", wxTextCtrl)->SetValue(
329 XRCCTRL(*
this,
"lenscal_cropfactor", wxTextCtrl)->SetValue(
340 if(!wrongSize.empty())
343 for(
unsigned int i=0;i<wrongSize.size();i++)
345 wxFileName filename(wrongSize[i]);
346 fileText.Append(filename.GetFullName());
347 if(i<wrongSize.size()-1)
348 fileText.Append(wxT(
", "));
350 wxMessageBox(wxString::Format(_(
"The size of the images (%s) does not match the already added image(s)."),fileText.c_str()),
351 _(
"Error"),wxOK|wxICON_EXCLAMATION,
this);
353 if(!wrongExif.empty())
356 for(
unsigned int i=0;i<wrongExif.size();i++)
358 wxFileName filename(wrongExif[i]);
359 fileText.Append(filename.GetFullName());
360 if(i<wrongExif.size()-1)
361 fileText.Append(wxT(
", "));
363 wxMessageBox(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()),
364 _(
"Warning"),wxOK|wxICON_EXCLAMATION,
this);
370 wxConfigBase* config = wxConfigBase::Get();
371 wxString path = config->Read(wxT(
"/actualPath"), wxT(
""));
372 wxFileDialog dlg(
this,_(
"Add images"),
375 wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST | wxFD_PREVIEW, wxDefaultPosition);
376 dlg.SetDirectory(path);
380 if (config->HasEntry(wxT(
"lastImageType"))){
381 img_ext = config->Read(wxT(
"lastImageType")).c_str();
383 if (img_ext == wxT(
"all images"))
384 dlg.SetFilterIndex(0);
385 else if (img_ext == wxT(
"jpg"))
386 dlg.SetFilterIndex(1);
387 else if (img_ext == wxT(
"tiff"))
388 dlg.SetFilterIndex(2);
389 else if (img_ext == wxT(
"png"))
390 dlg.SetFilterIndex(3);
391 else if (img_ext == wxT(
"hdr"))
392 dlg.SetFilterIndex(4);
393 else if (img_ext == wxT(
"exr"))
394 dlg.SetFilterIndex(5);
395 else if (img_ext == wxT(
"all files"))
396 dlg.SetFilterIndex(6);
397 DEBUG_INFO (
"Image extention: " << img_ext.mb_str(wxConvLocal) )
400 if (dlg.ShowModal() == wxID_OK)
403 wxArrayString Pathnames;
404 dlg.GetPaths(Pathnames);
409 config->Write(wxT(
"/actualPath"), wxPathOnly(Pathnames[0]));
411 config->Write(wxT(
"/actualPath"), dlg.GetDirectory());
414 wxArrayString invalidFiles;
415 for(
unsigned int i=0;i<Pathnames.GetCount(); i++)
419 invalidFiles.push_back(Pathnames[i]);
422 if(!invalidFiles.empty())
430 DEBUG_INFO ( wxString::Format(wxT(
"img_ext: %d"), dlg.GetFilterIndex()).mb_str(wxConvLocal) )
432 switch ( dlg.GetFilterIndex() )
434 case 0: config->Write(wxT(
"lastImageType"), wxT(
"all images"));
break;
435 case 1: config->Write(wxT(
"lastImageType"), wxT(
"jpg"));
break;
436 case 2: config->Write(wxT(
"lastImageType"), wxT(
"tiff"));
break;
437 case 3: config->Write(wxT(
"lastImageType"), wxT(
"png"));
break;
438 case 4: config->Write(wxT(
"lastImageType"), wxT(
"hdr"));
break;
439 case 5: config->Write(wxT(
"lastImageType"), wxT(
"exr"));
break;
440 case 6: config->Write(wxT(
"lastImageType"), wxT(
"all files"));
break;
446 SetStatusText( _(
"Add Image: cancel"));
453 wxFileName file(
m_images[index]->GetFilename());
454 m_images_list->SetString(index,wxString::Format(_(
"%s (%d lines)"),file.GetFullName().c_str(),
m_images[index]->GetNrOfValidLines()));
461 for(
unsigned int i=0;i<
m_images.size();i++)
463 wxFileName file(
m_images[i]->GetFilename());
464 wxString text=wxString::Format(_(
"%s (%d lines)"),file.GetFullName().c_str(),
m_images[i]->GetNrOfValidLines());
467 if(oldSelection!=wxNOT_FOUND && restoreSelection)
478 if(selection!=wxNOT_FOUND)
482 ImageCache::getInstance().removeImage(filename);
496 const bool enabling = !
m_images.empty();
497 XRCCTRL(*
this,
"lenscal_find_lines",wxButton)->Enable(enabling);
498 XRCCTRL(*
this,
"lenscal_opt",wxButton)->Enable(enabling);
499 XRCCTRL(*
this,
"lenscal_show_distortion_graph", wxButton)->Enable(enabling);
500 XRCCTRL(*
this,
"lenscal_save_lens",wxButton)->Enable(enabling);
501 GetMenuBar()->Enable(XRCID(
"menu_save"),enabling);
532 if(m_minlinelength<=0 || m_minlinelength>1)
535 if(readLensParameter)
555 wxMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."),_(
"Warning"),wxOK | wxICON_INFORMATION,
this);
559 for(
unsigned int i=0;i<
m_images.size();i++)
562 ImageCache::EntryPtr img=ImageCache::getInstance().getImage(filename);
564 SetStatusText(_(
"Detecting edges..."));
566 SetStatusText(_(
"Finding lines..."));
570 SetStatusText(_(
"Finished"));
578 wxMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."),_(
"Warning"),wxOK | wxICON_INFORMATION,
this);
581 unsigned int count=0;
582 for(
unsigned int i=0;i<
m_images.size();i++)
583 count+=
m_images[i]->GetNrOfValidLines();
586 wxMessageBox(_(
"There are no detected lines.\nPlease run \"Find lines\" first. If there are no lines found, change the parameters."),_(
"Warning"),wxOK | wxICON_INFORMATION,
this);
600 wxMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."), _(
"Warning"), wxOK | wxICON_INFORMATION,
this);
616 wxWindow *button = (wxWindow*)e.GetEventObject();
617 wxPoint pos = button->ClientToScreen(wxPoint(0, 0));
618 m_popup->Position(pos, button->GetSize());
626 unsigned int line_number=3;
627 for(
unsigned int i=0;i<
m_images.size();i++)
641 std::set<std::string> imgopt;
644 if(XRCCTRL(*
this,
"lenscal_opt_a",wxCheckBox)->GetValue())
646 if(XRCCTRL(*
this,
"lenscal_opt_b",wxCheckBox)->GetValue())
648 if(XRCCTRL(*
this,
"lenscal_opt_c",wxCheckBox)->GetValue())
650 if(XRCCTRL(*
this,
"lenscal_opt_de",wxCheckBox)->GetValue())
656 optvec.push_back(imgopt);
659 for(
unsigned j=0;j<lines.size();j++)
664 for(
unsigned int k=0;k<cpv.size();k++)
679 img.setExposureValue(0);
680 img.setWhiteBalanceRed(1);
681 img.setWhiteBalanceBlue(1);
697 SetStatusText(_(
"Optimizing lens distortion parameters..."));
713 SetStatusText(_(
"Finished"));
718 wxFileDialog dlg(
this,
719 _(
"Save lens parameters file"),
720 wxConfigBase::Get()->Read(wxT(
"/lensPath"),wxT(
"")), wxT(
""),
721 _(
"Lens Project Files (*.ini)|*.ini|All files (*)|*"),
722 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
723 dlg.SetDirectory(wxConfigBase::Get()->Read(wxT(
"/lensPath"),wxT(
"")));
724 if (dlg.ShowModal() == wxID_OK)
726 wxFileName filename(dlg.GetPath());
727 if(!filename.HasExt())
728 filename.SetExt(wxT(
"ini"));
729 wxConfig::Get()->Write(wxT(
"/lensPath"), dlg.GetDirectory());
730 if (filename.FileExists())
732 int d = wxMessageBox(wxString::Format(_(
"File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
733 _(
"Save project"), wxYES_NO | wxICON_QUESTION);
748 wxMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."),_(
"Warning"),wxOK | wxICON_INFORMATION,
this);
751 unsigned int count=0;
752 for(
unsigned int i=0;i<
m_images.size();i++)
753 count+=
m_images[i]->GetNrOfValidLines();
756 wxMessageBox(_(
"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."),_(
"Warning"),wxOK | wxICON_INFORMATION,
this);
760 wxArrayString choices;
761 choices.push_back(_(
"Save lens parameters to ini file"));
762 choices.push_back(_(
"Save lens parameters to lens database"));
763 wxSingleChoiceDialog save_dlg(
this,_(
"Saving lens data"),_(
"Save lens"),choices);
764 if(save_dlg.ShowModal()==wxID_OK)
766 if(save_dlg.GetSelection()==0)
782 wxMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."),_(
"Warning"),wxOK | wxICON_INFORMATION,
this);
786 wxFileDialog dlg(
this,_(
"Save project file"),wxEmptyString,wxEmptyString,
787 _(
"Project files (*.pto)|*.pto|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
788 dlg.SetDirectory(wxConfigBase::Get()->Read(wxT(
"/actualPath"),wxT(
"")));
789 if (dlg.ShowModal() == wxID_OK)
791 wxConfig::Get()->Write(wxT(
"/actualPath"), dlg.GetDirectory());
792 wxFileName filename(dlg.GetPath());
793 if(!filename.HasExt())
794 filename.SetExt(wxT(
"pto"));
795 if (filename.FileExists())
797 int d = wxMessageBox(wxString::Format(_(
"File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
798 _(
"Save project"), wxYES_NO | wxICON_QUESTION);
813 XRCCTRL(*
this,
"lenscal_remove_image",wxButton)->Enable(selected);
849 wxMessageBox(_(
"There are invalid values in the input boxes.\nPlease check your inputs."),_(
"Warning"),wxOK | wxICON_INFORMATION,
this);
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 StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Store window size and position in configfile/registry.
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.
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) ...
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