Hugin trunk 0.1
Loading...
Searching...
No Matches
LensTools.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
10/* This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This software is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this software. If not, see
22 * <http://www.gnu.org/licenses/>.
23 *
24 */
25
26#include "panoinc_WX.h"
27#include <wx/msgdlg.h>
28#include "panoinc.h"
29#include "LensTools.h"
30#include <algorithm>
33#include "base_wx/PanoCommand.h"
34#include "wxutils.h"
35
37{
38 list->Clear();
40 for (auto& lensInfo : lensInfoVector)
41 {
42 list->Append(lensInfo.name, (void*)lensInfo.id);
43 };
44 list->SetSelection(0);
45}
47{
48 // add all lens types to vector
52 lensInfo.name = _("Normal (rectilinear)");
53 lensInfoVector.push_back(lensInfo);
55 lensInfo.name = _("Panoramic (cylindrical)");
56 lensInfoVector.push_back(lensInfo);
58 lensInfo.name = _("Circular fisheye");
59 lensInfoVector.push_back(lensInfo);
61 lensInfo.name = _("Full frame fisheye");
62 lensInfoVector.push_back(lensInfo);
64 lensInfo.name = _("Equirectangular");
65 lensInfoVector.push_back(lensInfo);
67 lensInfo.name = _("Orthographic");
68 lensInfoVector.push_back(lensInfo);
70 lensInfo.name = _("Stereographic");
71 lensInfoVector.push_back(lensInfo);
73 lensInfo.name = _("Equisolid");
74 lensInfoVector.push_back(lensInfo);
76 lensInfo.name = _("Fisheye Thoby");
77 lensInfoVector.push_back(lensInfo);
78 return lensInfoVector;
79}
80;
81
83{
84 list->Clear();
85 list->Append(_("enblend"), (void*)HuginBase::PanoramaOptions::ENBLEND_BLEND);
86 list->Append(_("builtin"), (void*)HuginBase::PanoramaOptions::INTERNAL_BLEND);
87 list->SetSelection(0);
88};
89
91{
92 for(unsigned int i=0;i<list->GetCount();i++)
93 {
94 if((size_t)list->GetClientData(i)==newValue)
95 {
96 list->SetSelection(i);
97 return;
98 };
99 };
100 list->SetSelection(0);
101};
102
104{
105 return (size_t)(list->GetClientData(list->GetSelection()));
106};
107
109{
110 wxString ps;
111 switch (img.getProjection())
112 {
113 case HuginBase::SrcPanoImage::RECTILINEAR: ps << _("Normal (rectilinear)"); break;
114 case HuginBase::SrcPanoImage::PANORAMIC: ps << _("Panoramic (cylindrical)"); break;
115 case HuginBase::SrcPanoImage::CIRCULAR_FISHEYE: ps << _("Circular fisheye"); break;
116 case HuginBase::SrcPanoImage::FULL_FRAME_FISHEYE: ps << _("Full frame fisheye"); break;
117 case HuginBase::SrcPanoImage::EQUIRECTANGULAR: ps << _("Equirectangular"); break;
118 case HuginBase::SrcPanoImage::FISHEYE_ORTHOGRAPHIC: ps << _("Orthographic"); break;
119 case HuginBase::SrcPanoImage::FISHEYE_STEREOGRAPHIC:ps << _("Stereographic"); break;
120 case HuginBase::SrcPanoImage::FISHEYE_EQUISOLID: ps << _("Equisolid"); break;
121 case HuginBase::SrcPanoImage::FISHEYE_THOBY: ps << _("Fisheye Thoby"); break;
122 }
123 return ps;
124};
125
127{
128 wxString s;
129 switch (img.getResponseType())
130 {
132 s = _("custom (EMoR)");
133 break;
135 s = _("Linear");
136 break;
137 default:
139 break;
140 };
141 return s;
142};
143
144void SaveLensParameters(const wxString filename, HuginBase::Panorama* pano, unsigned int imgNr)
145{
147 const HuginBase::Lens & lens = variable_groups.getLensForImage(imgNr);
148 const HuginBase::VariableMap & vars = pano->getImageVariables(imgNr);
149 // get the variable map
150 char * p = setlocale(LC_NUMERIC,NULL);
151 char * old_locale = strdup(p);
153 wxFileConfig cfg("hugin lens file",wxEmptyString,filename);
154 cfg.Write("Lens/image_width", (long) lens.getImageSize().x);
155 cfg.Write("Lens/image_height", (long) lens.getImageSize().y);
156 cfg.Write("Lens/type", (long) lens.getProjection());
157 cfg.Write("Lens/hfov", const_map_get(vars,"v").getValue());
158 cfg.Write("Lens/hfov_link", const_map_get(lens.variables,"v").isLinked() ? 1:0);
159 cfg.Write("Lens/crop", lens.getCropFactor());
160
161 // loop to save lens variables
162 const char ** varname = HuginBase::Lens::variableNames;
163 while (*varname)
164 {
165 //ignore hfov, hfov is separately handled by the code above
166 if (std::string(*varname) == "v")
167 {
168 varname++;
169 continue;
170 }
171 wxString key("Lens/");
172 key.append(wxString(*varname, wxConvLocal));
173 cfg.Write(key, const_map_get(vars,*varname).getValue());
174 key.append("_link");
175 cfg.Write(key, const_map_get(lens.variables,*varname).isLinked() ? 1:0);
176 varname++;
177 }
178
179 const HuginBase::SrcPanoImage & image = pano->getImage(imgNr);
180 cfg.Write("Lens/crop/enabled", image.getCropMode()==HuginBase::SrcPanoImage::NO_CROP ? 0l : 1l);
181 cfg.Write("Lens/crop/autoCenter", image.getAutoCenterCrop() ? 1l : 0l);
182 const vigra::Rect2D cropRect=image.getCropRect();
183 cfg.Write("Lens/crop/left", cropRect.left());
184 cfg.Write("Lens/crop/top", cropRect.top());
185 cfg.Write("Lens/crop/right", cropRect.right());
186 cfg.Write("Lens/crop/bottom", cropRect.bottom());
187
188 if (!image.getExifMake().empty() && !image.getExifModel().empty() && image.getExifFocalLength()>0)
189 {
190 // write exif data to ini file
191 cfg.Write("EXIF/CameraMake", wxString(image.getExifMake().c_str(), wxConvLocal));
192 cfg.Write("EXIF/CameraModel", wxString(image.getExifModel().c_str(), wxConvLocal));
193 cfg.Write("EXIF/FocalLength", image.getExifFocalLength());
194 cfg.Write("EXIF/Aperture", image.getExifAperture());
195 cfg.Write("EXIF/ISO", image.getExifISO());
196 cfg.Write("EXIF/CropFactor", image.getCropFactor());
197 cfg.Write("EXIF/Distance", image.getExifDistance());
198 }
199 cfg.Flush();
200
201 // reset locale
204};
205
207{
209 HuginBase::Lens lens=variable_groups.getLensForImage(*images.begin());
210 bool cropped=false;
211 bool autoCenterCrop=false;
212 vigra::Rect2D cropRect;
213 if (LoadLensParametersChoose(parent, lens, cropped, autoCenterCrop, cropRect))
214 {
215 // Merge the lens parameters with the image variable map.
216 HuginBase::VariableMapVector vars(images.size());
217 size_t i=0;
218 for(HuginBase::UIntSet::const_iterator it=images.begin();it!=images.end();++it,++i)
219 {
220 vars[i]=pano->getImageVariables(*it);
221 for (HuginBase::LensVarMap::iterator it2 = lens.variables.begin(); it2 != lens.variables.end(); ++it2)
222 {
223 if (it2->second.getName() == "Eev" || it2->second.getName() == "Er" || it2->second.getName() == "Eb")
224 {
225 continue;
226 };
227 vars[i].find(it2->first)->second.setValue(it2->second.getValue());
228 }
229 };
230
234 std::vector<PanoCommand::PanoCommand*> cmds;
235 // update links
236 std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> linkedVariables;
237 std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> unlinkedVariables;
238 for (HuginBase::LensVarMap::iterator it = lens.variables.begin(); it != lens.variables.end(); ++it)
239 {
240 if(it->second.getName()=="Eev" || it->second.getName() == "Er" || it->second.getName() == "Eb")
241 {
242 continue;
243 };
244#define image_variable( name, type, default_value ) \
245 if (HuginBase::PTOVariableConverterFor##name::checkApplicability(it->second.getName()))\
246 {\
247 if(it->second.isLinked())\
248 linkedVariables.insert(HuginBase::ImageVariableGroup::IVE_##name);\
249 else\
250 unlinkedVariables.insert(HuginBase::ImageVariableGroup::IVE_##name);\
251 }
253#undef image_variable
254 }
255 if (!linkedVariables.empty())
256 {
259 }
260 if (!unlinkedVariables.empty())
261 {
264 }
265 //update lens parameters
266 cmds.push_back(new PanoCommand::UpdateImagesVariablesCmd(*pano, images, vars));
267
268 // Set the lens projection type.
269 cmds.push_back(new PanoCommand::ChangeImageProjectionCmd(*pano, images, (HuginBase::SrcPanoImage::Projection) lens.getProjection()));
270 // update crop factor
271 cmds.push_back(new PanoCommand::ChangeImageCropFactorCmd(*pano,images,lens.getCropFactor()));
272 // update the crop rect
273 cmds.push_back(new PanoCommand::ChangeImageAutoCenterCropCmd(*pano,images,autoCenterCrop));
274 if(cropped)
275 {
276 cmds.push_back(new PanoCommand::ChangeImageCropRectCmd(*pano,images,cropRect));
277 }
278 else
279 {
280 cmds.push_back(new PanoCommand::ChangeImageCropModeCmd(*pano,images,HuginBase::BaseSrcPanoImage::NO_CROP));
281 };
283 return true;
284 }
285 else
286 {
287 return false;
288 };
289};
290
292 bool & cropped, bool & autoCenterCrop, vigra::Rect2D & cropRect)
293{
296 _("Load lens parameters"),
297 wxConfigBase::Get()->Read("/lensPath",wxEmptyString), wxEmptyString,
298 _("Lens Project Files (*.ini)|*.ini|All files (*.*)|*.*"),
300 dlg.SetDirectory(wxConfigBase::Get()->Read("/lensPath",wxEmptyString));
301 if (dlg.ShowModal() == wxID_OK)
302 {
303 fname = dlg.GetPath();
304 wxConfig::Get()->Write("/lensPath", dlg.GetDirectory()); // remember for later
305 // read with with standart C numeric format
306 char * p = setlocale(LC_NUMERIC,NULL);
307 char * old_locale = strdup(p);
309 {
310 wxFileConfig cfg("hugin lens file",wxEmptyString,fname);
311 long w=0;
312 cfg.Read("Lens/image_width", &w);
313 long h=0;
314 cfg.Read("Lens/image_height", &h);
315 if (w>0 && h>0) {
316 vigra::Size2D sz = lens.getImageSize();
317 if (w != sz.x || h != sz.y) {
318 std::cerr << "Image size: " << sz << " size in lens parameter file: " << w << "x" << h << std::endl;
319 if (hugin_utils::HuginMessageBox(_("Incompatible lens parameter file, image sizes do not match\nApply settings anyway?"),
321 {
324 return false;
325 }
326 }
327 } else {
328 // lens ini file didn't store the image size,
329 // assume everything is all right.
330 }
331 long integer=0;
332 if(cfg.Read("Lens/type", &integer))
333 {
335 };
336 double d=1;
337 if(cfg.Read("Lens/crop", &d))
338 {
339 lens.setCropFactor(d);
340 };
341 //special treatment for hfov, we are reading hfov and hfov_linked instead of v and v_linked
342 d=50;
343 if(cfg.Read("Lens/hfov", &d))
344 {
345 map_get(lens.variables,"v").setValue(d);
346 };
347 integer=1;
348 if(cfg.Read("Lens/hfov_linked", &integer))
349 {
350 map_get(lens.variables,"v").setLinked(integer != 0);
351 };
352 DEBUG_DEBUG("read lens hfov: " << d);
353
354 // loop to load lens variables
355 const char ** varname = HuginBase::Lens::variableNames;
356 while (*varname) {
357 wxString key("Lens/");
358 key.append(wxString(*varname, wxConvLocal));
359 d = 0;
360 if (cfg.Read(key,&d))
361 {
362 // only set value if variabe was found in the script
363 map_get(lens.variables, *varname).setValue(d);
364 integer = 1;
365 key.append("_link");
366 if(cfg.Read(key, &integer))
367 {
368 map_get(lens.variables, *varname).setLinked(integer != 0);
369 };
370 }
371 varname++;
372 }
373
374 // crop parameters
375 long v=0;
376 cfg.Read("Lens/crop/enabled", &v);
377 cropped=(v!=0);
378 if(cropped)
379 {
380 long left=0;
381 long top=0;
382 long right=0;
383 long bottom=0;
384 if(cfg.Read("Lens/crop/left", &left) && cfg.Read("Lens/crop/top", &top) &&
385 cfg.Read("Lens/crop/right", &right) && cfg.Read("Lens/crop/bottom", &bottom))
386 {
387 cropped=true;
388 cropRect=vigra::Rect2D(left,top,right,bottom);
389 }
390 else
391 {
392 cropped=false;
393 };
394 };
395 v=1;
396 if(cfg.Read("Lens/crop/autoCenter", &v))
397 {
398 autoCenterCrop=(v!=0);
399 };
400 }
401 // reset locale
404 return true;
405 }
406 else
407 {
408 return false;
409 };
410};
411
413{
414 if (images.size() == 1)
415 {
416 unsigned int imgNr = *(images.begin());
418 _("Save lens parameters file"),
419 wxConfigBase::Get()->Read("/lensPath",wxEmptyString), wxEmptyString,
420 _("Lens Project Files (*.ini)|*.ini|All files (*)|*"),
422 dlg.SetDirectory(wxConfigBase::Get()->Read("/lensPath",wxEmptyString));
423 if (dlg.ShowModal() == wxID_OK)
424 {
425 wxFileName filename(dlg.GetPath());
426 if(!filename.HasExt())
427 {
428 filename.SetExt("ini");
429 if (filename.Exists())
430 {
431 if (!hugin_utils::AskUserOverwrite(filename.GetFullPath(), _("Hugin"), wxGetActiveWindow()))
432 {
433 return;
434 }
435 }
436 }
437 wxConfig::Get()->Write("/lensPath", dlg.GetDirectory()); // remember for later
438 SaveLensParameters(filename.GetFullPath(),pano,imgNr);
439 }
440 }
441 else
442 {
443 wxLogError(_("Please select an image and try again"));
444 }
445}
446
448{
449 if (pano->getNrOfImages() < 2)
450 {
451 return true;
452 };
453 const size_t nrImages = pano->getNrOfImages();
454 bool stacksCorrectLinked = true;
455 for (size_t i = 0; i < nrImages - 1; ++i)
456 {
457 const HuginBase::SrcPanoImage& image1 = pano->getImage(i);
458 if (image1.YawisLinked())
459 {
460 for (size_t j = i + 1; j < nrImages && stacksCorrectLinked; ++j)
461 {
462 const HuginBase::SrcPanoImage& image2 = pano->getImage(j);
463 if (image1.YawisLinkedWith(image2))
464 {
466 image1.HFOVisLinkedWith(image2) &&
467 image1.RadialDistortionisLinkedWith(image2) &&
468 image1.RadialDistortionCenterShiftisLinkedWith(image2) &&
469 image1.ShearisLinkedWith(image2);
470 };
471 };
472 };
473 };
475 {
476 return true;
477 }
478 else
479 {
481 if (allowCancel)
482 {
483 flags = flags | wxCANCEL;
484 };
485 if (hugin_utils::HuginMessageBox(_("This project contains stacks with linked positions. But the lens parameters are not linked for these images.\nThis will result in unwanted results.\nPlease check and correct this before proceeding."),
486 _("Hugin"), flags, wxGetActiveWindow()) == wxOK)
487 {
488 return true;
489 }
490 else
491 {
492 return false;
493 };
494 };
495}
496
498{
500{
501 wxString s;
502 struct tm exifdatetime;
503 if (img->getExifDateTime(&exifdatetime) == 0)
504 {
506 s = s_datetime.Format();
507 }
508 else
509 {
510 s = wxString(img->getExifDate().c_str(), wxConvLocal);
511 }
512 return s;
513}
514
516{
517 wxString s;
518 if (img->getExifFocalLength() > 0.0)
519 {
520 if (img->getExifFocalLength35() > 0.0)
521 {
522 s = wxString::Format("%0.1f mm (%0.0f mm)", img->getExifFocalLength(), img->getExifFocalLength35());
523 }
524 else
525 {
526 s = wxString::Format("%0.1f mm", img->getExifFocalLength());
527 };
528 }
529 else
530 {
532 };
533 return s;
534};
535
537{
538 wxString s;
539 if (img->getExifAperture() > 0)
540 {
541 s = wxString::Format("F%.1f", img->getExifAperture());
542 }
543 else
544 {
546 };
547 return s;
548};
549
551{
552 wxString s;
553 const double exposureTime = img->getExifExposureTime();
554 if (exposureTime > 0.5)
555 {
556 if (exposureTime >= 1.0)
557 {
558 if (exposureTime >= 10.0)
559 {
560 s = wxString::Format("%3.0f s", exposureTime);
561 }
562 else
563 {
564 s = wxString::Format("%1.1f s", exposureTime);
565 }
566 }
567 else
568 {
569 s = wxString::Format("%1.2f s", exposureTime);
570 }
571 }
572 else
573 {
574 if (exposureTime > 1e-9)
575 {
576 s = wxString::Format("1/%0.0f s", 1.0 / exposureTime);
577 }
578 else
579 {
580 //Sanity
582 }
583 }
584 return s;
585};
586
588{
589 wxString s;
590 if (img->getExifISO() > 0)
591 {
592 s = wxString::Format("%0.0f", img->getExifISO());
593 }
594 else
595 {
597 };
598 return s;
599};
600
601};
602
603
604
Convenience functions for SrcPanoImage to use on the image variables.
void FillBlenderList(wxControlWithItems *list)
Fills a wxControlWithItem with all possible blender options, the client data contains the associated ...
Definition LensTools.cpp:82
void SaveLensParameters(const wxString filename, HuginBase::Panorama *pano, unsigned int imgNr)
save the lens parameters of the image to a lens file named filename
void FillLensProjectionList(wxControlWithItems *list)
Fills a wxControlWithItem with all input projection formats, the client data contains the associated ...
Definition LensTools.cpp:36
bool CheckLensStacks(HuginBase::Panorama *pano, bool allowCancel)
check, if lens and stacks are correctly linked shows message box with short information if not
wxString getProjectionString(const HuginBase::SrcPanoImage &img)
Returns translated projection for given image.
WXIMPEX HuginLensTools::LensInfoVector GetLensProjectionList()
return a vector with all available projections
Definition LensTools.cpp:46
void SaveLensParametersToIni(wxWindow *parent, HuginBase::Panorama *pano, const HuginBase::UIntSet images)
saves the lens parameters to ini files, provides all necessary dialogs
size_t GetSelectedValue(wxControlWithItems *list)
Returns the client value of the selected item from list.
bool ApplyLensParameters(wxWindow *parent, HuginBase::Panorama *pano, HuginBase::UIntSet images, PanoCommand::PanoCommand *&cmd)
applies lens parameter from user selected file to pano using GlobalCmdHist
wxString getResponseString(const HuginBase::SrcPanoImage &img)
Returns translated response type for given SrcPanoImage.
void SelectListValue(wxControlWithItems *list, size_t newValue)
Selects the given value (stored in the client data) in the given list item.
Definition LensTools.cpp:90
bool LoadLensParametersChoose(wxWindow *parent, HuginBase::Lens &lens, bool &cropped, bool &autoCenterCrop, vigra::Rect2D &cropRect)
load lens parameters from lens ini file
some helper classes for graphes
Somewhere to specify what variables belong to what.
@ RESPONSE_LINEAR
linear response
@ RESPONSE_EMOR
empirical model of response
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
void setProjection(LensProjectionFormat l)
set projection type
Definition Lens.h:60
double getCropFactor() const
get crop factor, d35mm/dreal
Definition Lens.h:73
void setCropFactor(double newCropFactor)
sets the crop factor
Definition Lens.h:77
LensVarMap variables
Definition Lens.h:106
LensProjectionFormat getProjection() const
get projection type
Definition Lens.h:56
static const char * variableNames[]
Definition Lens.h:110
Model for a panorama.
Definition Panorama.h:153
const VariableMap getImageVariables(unsigned int imgNr) const
Get the variables of an image.
Definition Panorama.cpp:128
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition Panorama.h:211
std::size_t getNrOfImages() const
number of images.
Definition Panorama.h:205
All variables of a source image.
const int getExifDateTime(struct tm *datetime) const
try to convert Exif date time string to struct tm
Change the linking of some variables across parts of an ImageVariableGroup containing some specified ...
PanoCommand to combine other PanoCommands.
Definition PanoCommand.h:40
Base class for all panorama commands.
Definition Command.h:39
update variables of a group of images
static uint16_t flags
#define WXIMPEX
#define DEBUG_DEBUG(msg)
Definition utils.h:68
This file specifies what image variables SrcPanoImg should have.
wxString GetIso(const HuginBase::SrcPanoImage *img)
returns formatted iso value
wxString GetFocalLength(const HuginBase::SrcPanoImage *img)
return focallength and focallength 35 mm as wxString
wxString GetExifDateTime(const HuginBase::SrcPanoImage *img)
returns Exif DateTimeOriginal as formatted wxString
wxString GetExposureTime(const HuginBase::SrcPanoImage *img)
returns formatted exposure time
wxString GetAperture(const HuginBase::SrcPanoImage *img)
returns formatted aperture value
std::vector< VariableMap > VariableMapVector
std::set< unsigned int > UIntSet
std::map< std::string, Variable > VariableMap
std::vector< LensInfo > LensInfoVector
vector of LensInfo to hold all available lens types
Definition LensTools.h:48
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
Definition wxutils.cpp:233
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition wxutils.cpp:176
include file for the hugin project
include file for the hugin project
Map::mapped_type & map_get(Map &m, const typename Map::key_type &key)
get a map element.
Definition stl_utils.h:98
const Map::mapped_type & const_map_get(const Map &m, const typename Map::key_type &key)
Definition stl_utils.h:110
structure to name of lens projections and their ids
Definition LensTools.h:43
HuginBase::BaseSrcPanoImage::Projection id
Definition LensTools.h:45
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