41 std::string tempString(s);
43 var.
flag = (tempString[0] ==
'!');
46 tempString.erase(0, 1);
50 varVec.push_back(var);
54 errorStream <<
"The expression \"" << tempString <<
"\" is not a valid image variable." << std::endl;
66 varVec.push_back(var);
70 errorStream <<
"The expression \"" << s <<
"\" does not contain a valid image number." << std::endl;
75 errorStream <<
"The expression \"" << s <<
"\" is not a valid image variable." << std::endl;
84 std::set<size_t> refImgs,
bool linkRefImgsYaw,
bool linkRefImgsPitch,
bool linkRefImgsRoll, std::vector<std::set<std::string> > groupedVars)
90 optVec[imgNr].insert(varname);
99 optVec[imgNr].insert(varname);
108 optVec[imgNr].insert(varname);
113 if(varname==
"TrX" || varname==
"TrY" || varname==
"TrZ" || varname==
"Tpy" || varname==
"Tpp")
117 optVec[imgNr].insert(varname);
122 for(
size_t i=0; i<groupedVars.size(); i++)
126 for(std::set<std::string>::const_iterator it=groupedVars[i].begin(); it!=groupedVars[i].end(); ++it)
128 optVec[imgNr].insert(*it);
133 optVec[imgNr].insert(varname);
143 for(
size_t i=0; i<groupedVars.size(); i++)
147 for(std::set<std::string>::const_iterator it=groupedVars[i].begin(); it!=groupedVars[i].end(); ++it)
149 optVec[imgNr].erase(*it);
154 optVec[imgNr].erase(varname);
160 for(
size_t i=0; i<parseVec.size(); i++)
163 if(parseVec[i].imgNr<0 || parseVec[i].imgNr>=(
int)pano.
getNrOfImages())
169 std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> variables;
170 #define image_variable( name, type, default_value ) \
171 if (HuginBase::PTOVariableConverterFor##name::checkApplicability(parseVec[i].varname))\
173 variables.insert(HuginBase::ImageVariableGroup::IVE_##name);\
176 #undef image_variable
178 if(!variables.empty())
186 std::cout <<
"Linking";
187 group.linkVariableImage(*variables.begin(), parseVec[i].imgNr);
191 std::cout <<
"Unlinking";
192 group.unlinkVariableImage(*variables.begin(), parseVec[i].imgNr);
193 group.updatePartNumbers();
195 std::cout <<
" image variable " << parseVec[i].varname <<
" for image " << parseVec[i].imgNr << std::endl;
206 std::cout <<
"Linking";
207 group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Yaw, parseVec[i].imgNr);
208 group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Pitch, parseVec[i].imgNr);
209 group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Roll, parseVec[i].imgNr);
210 group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_X, parseVec[i].imgNr);
211 group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Y, parseVec[i].imgNr);
212 group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Z, parseVec[i].imgNr);
213 group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlaneYaw, parseVec[i].imgNr);
214 group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlanePitch, parseVec[i].imgNr);
218 std::cout <<
"Unlinking";
219 group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Yaw, parseVec[i].imgNr);
220 group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Pitch, parseVec[i].imgNr);
221 group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Roll, parseVec[i].imgNr);
222 group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_X, parseVec[i].imgNr);
223 group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Y, parseVec[i].imgNr);
224 group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Z, parseVec[i].imgNr);
225 group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlaneYaw, parseVec[i].imgNr);
226 group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlanePitch, parseVec[i].imgNr);
227 group.updatePartNumbers();
229 std::cout <<
" image position (ypr, TrXYZ, Tpyp) for image " << parseVec[i].imgNr << std::endl;
233 std::cerr <<
"Warning: " << parseVec[i].varname <<
" is not a valid linkable variable." << std::endl;
247 size_t pos = s.find(
'%');
248 relativ = (pos != std::string::npos);
251 if (pos < s.length() - 1)
280 if (coords.size() == 2)
283 double width, height;
284 bool relWidth =
false;
285 bool relHeight =
false;
291 vigra::Rect2D cropRect;
293 img.setCropRect(cropRect);
294 img.setAutoCenterCrop(
true);
298 std::cout <<
"Set crop for image " << i <<
" to " << pano.
getImage(i).getCropRect() << std::endl;
303 std::cerr <<
"Could not parse crop string \"" << s <<
"\"." << std::endl;
309 if (coords.size() == 4)
312 int left, right, top, bottom;
316 vigra::Rect2D cropRect;
317 if (right > left && bottom > top)
319 cropRect.setUpperLeft(vigra::Point2D(left, top));
320 cropRect.setLowerRight(vigra::Point2D(right, bottom));
324 std::cerr <<
"Crop \"" << s <<
"\" is an invalid crop area." << std::endl;
330 img.setAutoCenterCrop(
false);
331 img.setCropRect(cropRect);
335 std::cout <<
"Set crop for image " << i <<
" to " << pano.
getImage(i).getCropRect() << std::endl;
340 std::cerr <<
"Could not parse crop values \"" << s <<
"\"." << std::endl;
346 std::cerr <<
"Invalid coordinates \"" << s <<
"\"." << std::endl;
359 for (
auto& s : splitResult)
362 if (subString.empty())
366 size_t pos = subString.find(
"=");
367 if(subString[0]==
'i' && pos==std::string::npos)
369 std::cerr <<
"Crop expression \"" << s <<
"\" is not a valid crop." << std::endl;
372 if (subString[0] ==
'i')
376 std::cerr <<
"Crop expression \"" << s <<
"\" does not contain a valid image number."<< std::endl;
382 std::cerr <<
"Crop expression \"" << s <<
"\" does not contain a valid image number." << std::endl;
387 std::cerr <<
"Pano does not contain image with number " << imgNr << std::endl;
409 for (
auto& img : imagesString)
422 std::cout << (enable ?
"Enabling" :
"Disabling") <<
" image " << imgNr << std::endl;
426 std::cerr <<
"Pano does not contain image with number " << imgNr << (enable ?
" to activate." :
" to disable.") << std::endl;
431 std::cerr << (enable ?
"Enable images: " :
"Disable images: ") <<
432 "string " << img <<
" can't be parsed as valid number." << std::endl;
439 std::cout << name <<
": change image variables inside pto files" << std::endl
442 <<
"Usage: " << name <<
" [options] --opt|--link|--unlink|--set varlist input.pto" << std::endl
444 <<
" -o, --output=file.pto Output Hugin PTO file. Default: <filename>_var.pto" << std::endl
445 <<
" -h, --help Shows this help" << std::endl
447 <<
" --opt varlist Change optimizer variables" << std::endl
448 <<
" --modify-opt Modify the existing optimizer variables" << std::endl
449 <<
" (without pto_var will start with an" << std::endl
450 <<
" empty variables set)" << std::endl
451 <<
" Examples:" << std::endl
452 <<
" --opt=y,p,r Optimize yaw, pitch and roll of all images" << std::endl
453 <<
" (special treatment for anchor image applies)" << std::endl
454 <<
" --opt=v0,b2 Optimize hfov of image 0 and barrel distortion" << std::endl
455 <<
" of image 2" << std::endl
456 <<
" --opt=v,!v0 Optimize field of view for all images except" << std::endl
457 <<
" for the first image" << std::endl
458 <<
" --opt=!a,!b,!c Don't optimise distortion (works only with" << std::endl
459 <<
" switch --modify-opt together)" << std::endl
461 <<
" --link varlist Link given variables" << std::endl
462 <<
" Example:" << std::endl
463 <<
" --link=v3 Link hfov of image 3" << std::endl
464 <<
" --link=a1,b1,c1 Link distortions parameter for image 1" << std::endl
466 <<
" --unlink varlist Unlink given variables" << std::endl
467 <<
" Examples:" << std::endl
468 <<
" --unlink=v5 Unlink hfov for image 5" << std::endl
469 <<
" --unlink=a2,b2,c2 Unlink distortions parameters for image 2" << std::endl
471 <<
" --set varlist Sets variables to new values" << std::endl
472 <<
" Examples:" << std::endl
473 <<
" --set=y0=0,r0=0,p0=0 Resets position of image 0" << std::endl
474 <<
" --set=Vx4=-10,Vy4=10 Sets vignetting offset for image 4" << std::endl
475 <<
" --set=v=20 Sets the field of view to 20 for all images" << std::endl
476 <<
" --set=y=val+20 Increase yaw by 20 deg for all images" << std::endl
477 <<
" --set=v=val*1.1 Increase fov by 10 % for all images" << std::endl
478 <<
" --set=y=i*20 Set yaw to 0, 20, 40, ..." << std::endl
479 <<
" --set-from-file filename Sets variables to new values" << std::endl
480 <<
" It reads the varlist from a file" << std::endl
482 <<
" --crop=left,right,top,bottom Set the crop for all images" << std::endl
483 <<
" --crop=width,height Set the crop for all images and activate" << std::endl
484 <<
" autocenter for crop" << std::endl
485 <<
" relative values can be used with %" << std::endl
486 <<
" --crop=iNUM=left,right,top,bottom Set the crop for image NUM" << std::endl
487 <<
" --crop=iNUM=width,height Set the crop for image NUM and" << std::endl
488 <<
" activate autocenter for crop" << std::endl
489 <<
" These switches can be used several times." << std::endl
491 <<
" --anchor=NUM Sets the image NUM as anchor for geometric" << std::endl
492 <<
" optimisation." << std::endl
493 <<
" --color-anchor=NUM Sets the image NUM as anchor for photometric" << std::endl
494 <<
" optimisation." << std::endl
496 <<
" --enable-image=NUM1[,NUM2...] Enables images for stitching" << std::endl
497 <<
" --disable-image=NUM1[,NUM2...] Disables images for stitching" << std::endl
501 int main(
int argc,
char* argv[])
504 const char* optstring =
"o:h";
520 static struct option longOptions[] =
522 {
"output", required_argument, NULL,
'o' },
523 {
"opt", required_argument, NULL, SWITCH_OPT },
524 {
"link", required_argument, NULL, SWITCH_LINK },
525 {
"unlink", required_argument, NULL, SWITCH_UNLINK },
526 {
"set", required_argument, NULL, SWITCH_SET },
527 {
"set-from-file", required_argument, NULL, SWITCH_SET_FILE },
528 {
"modify-opt", no_argument, NULL, OPT_MODIFY_OPTVEC },
529 {
"crop", required_argument, NULL, SWITCH_CROP },
530 {
"anchor", required_argument, NULL, SWITCH_ANCHOR },
531 {
"color-anchor", required_argument, NULL, SWITCH_COLOR_ANCHOR },
532 {
"enable-image", required_argument, NULL, SWITCH_ENABLE_IMAGE },
533 {
"disable-image", required_argument, NULL, SWITCH_DISABLE_IMAGE },
534 {
"help", no_argument, NULL,
'h' },
541 std::string setVars, crop, enableImages, disableImages;
543 int colorAnchor = -1;
544 bool modifyOptVec=
false;
547 while ((c = getopt_long (argc, argv, optstring, longOptions,
nullptr)) != -1)
567 if (!setVars.empty())
571 setVars.append(optarg);
573 case SWITCH_SET_FILE:
575 std::ifstream ifs(optarg);
578 std::ostringstream contents;
579 contents << ifs.rdbuf();
581 setVars = contents.str();
590 case OPT_MODIFY_OPTVEC:
605 std::cerr <<
"ERROR: Number " << anchor <<
" for --anchor has to be >=0." << std::endl;
611 std::cerr <<
"ERROR: \"" << optarg <<
"\" is not a valid number for --anchor parameter." << std::endl;
615 case SWITCH_COLOR_ANCHOR:
620 std::cerr <<
"ERROR: Number " << colorAnchor <<
" for --color-anchor has to be >=0." << std::endl;
626 std::cerr <<
"ERROR: \"" << optarg <<
"\" is not a valid number for --color-anchor parameter." << std::endl;
630 case SWITCH_ENABLE_IMAGE:
631 if (!enableImages.empty())
633 enableImages.append(
",");
635 enableImages.append(optarg);
637 case SWITCH_DISABLE_IMAGE:
638 if (!disableImages.empty())
640 disableImages.append(
",");
642 disableImages.append(optarg);
656 if (argc - optind != 1)
658 if (argc - optind < 1)
669 if (optVars.empty() && linkVars.empty() && unlinkVars.empty() && setVars.empty() && crop.empty() && anchor < 0 && colorAnchor < 0
670 && enableImages.empty() && disableImages.empty())
676 std::string input=argv[optind];
685 if(!linkVars.empty())
687 std::cout <<
"Linking image variables" << std::endl;
688 UnLinkVars(pano, linkVars,
true);
689 std::cout << std::endl;
692 if(!unlinkVars.empty())
694 std::cout <<
"Unlinking image variables" << std::endl;
695 UnLinkVars(pano, unlinkVars,
false);
696 std::cout << std::endl;
702 std::cout <<
"Setting image variables" << std::endl;
704 std::cout << std::endl;
712 std::cout <<
"WARNING: Image number " << anchor <<
" is not a valid number for the anchor image." << std::endl;
717 std::cout <<
"Setting optimizer anchor to image " << anchor << std::endl;
724 if (colorAnchor >= 0)
728 std::cout <<
"WARNING: Image number " << anchor <<
" is not a valid number for the color anchor image." << std::endl;
733 std::cout <<
"Setting color anchor to image " << colorAnchor << std::endl;
742 std::cout <<
"Updating optimizer variables" << std::endl;
744 bool linkRefImgsYaw=
false;
745 bool linkRefImgsPitch=
false;
746 bool linkRefImgsRoll=
false;
750 std::vector<std::set<std::string> > groupedVars;
751 std::set<std::string> varSet;
755 groupedVars.push_back(varSet);
759 groupedVars.push_back(varSet);
766 groupedVars.push_back(varSet);
777 for(
size_t i=0; i<optVars.size(); i++)
784 if(optVars[i].imgNr==-1)
794 AddToOptVec(optVec, optVars[i].varname, imgNr, refImgs, linkRefImgsYaw, linkRefImgsPitch, linkRefImgsRoll, groupedVars);
802 RemoveFromOptVec(optVec, optVars[i].varname, optVars[i].imgNr, groupedVars);
806 AddToOptVec(optVec, optVars[i].varname, optVars[i].imgNr, refImgs,
true,
true,
true, groupedVars);
813 std::cout <<
"Optimizer variables:" << std::endl;
814 for (
size_t i = 0; i < optVec.size(); ++i)
816 std::cout <<
"Image " << i <<
": ";
817 std::copy(optVec[i].begin(), optVec[i].end(), std::ostream_iterator<std::string>(std::cout,
" "));
818 std::cout << std::endl;
820 std::cout << std::endl;
826 std::cout <<
"Setting image crop" << std::endl;
828 std::cout << std::endl;
832 if (!enableImages.empty())
834 std::cout <<
"Activating images" << std::endl;
836 std::cout << std::endl;
838 if (!disableImages.empty())
840 std::cout <<
"Disabling images" << std::endl;
842 std::cout << std::endl;
850 std::cout << std::endl <<
"Written project file " << output << std::endl;
std::set< size_t > getRefImages()
returns set of reference image and images linked with reference images
void ParseVariableString(ParseVarVec &parseVec, const std::string &input, std::ostream &errorStream, void(*func)(ParseVarVec &, const std::string &, std::ostream &))
parse complete variables string
static const std::set< ConstImageVariableGroup::ImageVariableEnum > & getLensVariables()
Get the set of lens image variables.
void AddToOptVec(HuginBase::OptimizeVector &optVec, std::string varname, size_t imgNr, std::set< size_t > refImgs, bool linkRefImgsYaw, bool linkRefImgsPitch, bool linkRefImgsRoll, std::vector< std::set< std::string > > groupedVars)
void updateOptimizeVector()
updates the optimize vector according to master switches
std::string StrTrim(const std::string &str)
remove trailing and leading white spaces and tabs
void checkRefOptStatus(bool &linkRefImgsYaw, bool &linkRefImgsPitch, bool &linkRefImgsRoll)
checks if yaw/pitch/roll of reference image can be check, it depends on number and type of control po...
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
std::string GetOutputFilename(const std::string &out, const std::string &in, const std::string &suffix)
construct output filename, if ouput is known return this value otherwise use the input filename and a...
void SetCropToImages(const std::string &s, HuginBase::Panorama &pano, HuginBase::UIntSet &imgs)
void setPhotometricOptimizerSwitch(const int newSwitch)
sets the photometric optimizer master switch
IMPEX bool ParseVarNumber(const std::string &s, Parser::ParseVar &var)
parse string s and store result in ParseVar var
Somewhere to specify what variables belong to what.
bool set_contains(const _Container &c, const typename _Container::key_type &key)
struct to save parsed variables and optional image numbers
int getHeight() const
Get the height of the image in pixels.
void setOptimizerSwitch(const int newSwitch)
set optimizer master switch
unsigned int colorReferenceImage
Declare the ImageVariableGroup and ImageVariableGroupObserver classes.
void setOptimizeVector(const OptimizeVector &optvec)
set optimize setting
bool stringToUInt(const std::string &s, unsigned int &val)
convert string to unsigned integer value, returns true, if sucessful
std::set< unsigned int > UIntSet
void ParseSingleLinkVar(Parser::ParseVarVec &varVec, const std::string &s, std::ostream &errorStream)
IMPEX void PanoParseExpression(HuginBase::Panorama &pano, const std::string &expression, std::ostream &statusStream=std::cout, std::ostream &errorStream=std::cerr)
parses the given expression and apply the changes to the Panorama
void ParseSingleOptVar(Parser::ParseVarVec &varVec, const std::string &s, std::ostream &errorStream)
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
const OptimizeVector & getOptimizeVector() const
return the optimize settings stored inside panorama
std::vector< ParseVar > ParseVarVec
std::size_t getNrOfImages() const
number of images.
int getWidth() const
Get the width of the image in pixels.
bool ReadPTOFile(const std::string &filename, const std::string &prefix="")
read pto file from the given filename into Panorama object it does some checks on the file and issues...
void activateImage(unsigned int imgNr, bool active=true)
mark an image as active or inactive.
bool stringToInt(const std::string &s, int &val)
convert string to integer value, returns true, if sucessful
bool stringToDouble(const STR &str_, double &dest)
convert a string to a double, ignore localisation.
void RemoveFromOptVec(HuginBase::OptimizeVector &optVec, std::string varname, size_t imgNr, std::vector< std::set< std::string > > groupedVars)
Same as above, but use a non const panorama.
void changeFinished(bool keepDirty)
notify observers about changes in this class
Convenience functions for SrcPanoImage to use on the image variables.
const PanoramaOptions & getOptions() const
returns the options for this panorama
void EnableImages(HuginBase::Panorama &pano, const std::string &imageList, const bool enable)
void setSize(vigra::Size2D val)
Set the image size in pixels.
void SetCrop(const std::string &cropString, HuginBase::Panorama &pano, HuginBase::PanoramaOptions &options)
std::string GetHuginVersion()
return a string with version numbers
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
void fill_set(_Container &c, typename _Container::key_type begin, typename _Container::key_type end)
void setOptions(const PanoramaOptions &opt)
set new output settings This is not used directly for optimizing/stiching, but it can be feed into ru...
void setSrcImage(unsigned int nr, const SrcPanoImage &img)
set input image parameters
std::vector< std::string > SplitString(const std::string &s, const std::string &sep)
split string s at given sep, returns vector of strings
All variables of a source image.
This file specifies what image variables SrcPanoImg should have.
function to parse expressions from strings
bool ParseCoordinateRelativ(const std::string &s, double &val, bool &relativ)
static const std::set< ConstImageVariableGroup::ImageVariableEnum > & getStackVariables()
Get the set of stack image variables.
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
unsigned int optimizeReferenceImage
int main(int argc, char *argv[])