pto_var.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00011 /*  This program is free software; you can redistribute it and/or
00012  *  modify it under the terms of the GNU General Public
00013  *  License as published by the Free Software Foundation; either
00014  *  version 2 of the License, or (at your option) any later version.
00015  *
00016  *  This software is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *  General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public
00022  *  License along with this software. If not, see
00023  *  <http://www.gnu.org/licenses/>.
00024  *
00025  */
00026 
00027 #include <fstream>
00028 #include <sstream>
00029 #include <getopt.h>
00030 #include <panodata/Panorama.h>
00031 #include <panodata/ImageVariableTranslate.h>
00032 #include <panodata/ImageVariableGroup.h>
00033 #include <panodata/StandardImageVariableGroups.h>
00034 #include "hugin_utils/utils.h"
00035 #include "panodata/ParseExp.h"
00036 
00037 // parse a single variable and put result in struct ParseVar
00038 void ParseSingleOptVar(Parser::ParseVarVec& varVec, const std::string& s, std::ostream& errorStream)
00039 {
00040     // parse following regex ([!]?)([a-zA-Z]{1,3})(\\d*?) 
00041     std::string tempString(s);
00042     Parser::ParseVar var;
00043     var.flag = (tempString[0] == '!');
00044     if (var.flag)
00045     {
00046         tempString.erase(0, 1);
00047     };
00048     if (Parser::ParseVarNumber(tempString, var))
00049     {
00050         varVec.push_back(var);
00051     }
00052     else
00053     {
00054         errorStream << "The expression \"" << tempString << "\" is not a valid image variable." << std::endl;
00055     };
00056 };
00057 
00058 void ParseSingleLinkVar(Parser::ParseVarVec& varVec, const std::string& s, std::ostream& errorStream)
00059 {
00060     // parse following regex ([a-zA-Z]{1,3})(\\d+?)
00061     Parser::ParseVar var;
00062     if (Parser::ParseVarNumber(s, var))
00063     {
00064         if (var.imgNr >= 0)
00065         {
00066             varVec.push_back(var);
00067         }
00068         else
00069         {
00070             errorStream << "The expression \"" << s << "\" does not contain a valid image number." << std::endl;
00071         }
00072     }
00073     else
00074     {
00075         errorStream << "The expression \"" << s << "\" is not a valid image variable." << std::endl;
00076     };
00077 };
00078 
00079 // adds given varname to optVec
00080 // does some additional checking:
00081 //   1. don't add y,p,r for anchor image
00082 //   2. handle vignetting and EMoR parameters as group
00083 void AddToOptVec(HuginBase::OptimizeVector& optVec, std::string varname, size_t imgNr,
00084                  std::set<size_t> refImgs, bool linkRefImgsYaw, bool linkRefImgsPitch, bool linkRefImgsRoll, std::vector<std::set<std::string> > groupedVars)
00085 {
00086     if(varname=="y")
00087     {
00088         if(!set_contains(refImgs, imgNr) || linkRefImgsYaw)
00089         {
00090             optVec[imgNr].insert(varname);
00091         };
00092     }
00093     else
00094     {
00095         if(varname=="p")
00096         {
00097             if(!set_contains(refImgs, imgNr) || linkRefImgsPitch)
00098             {
00099                 optVec[imgNr].insert(varname);
00100             };
00101         }
00102         else
00103         {
00104             if(varname=="r")
00105             {
00106                 if(!set_contains(refImgs, imgNr) || linkRefImgsRoll)
00107                 {
00108                     optVec[imgNr].insert(varname);
00109                 };
00110             }
00111             else
00112             {
00113                 if(varname=="TrX" || varname=="TrY" || varname=="TrZ" || varname=="Tpy" || varname=="Tpp")
00114                 {
00115                     if(!set_contains(refImgs, imgNr))
00116                     {
00117                         optVec[imgNr].insert(varname);
00118                     };
00119                 }
00120                 else
00121                 {
00122                     for(size_t i=0; i<groupedVars.size(); i++)
00123                     {
00124                         if(set_contains(groupedVars[i], varname))
00125                         {
00126                             for(std::set<std::string>::const_iterator it=groupedVars[i].begin(); it!=groupedVars[i].end(); ++it)
00127                             {
00128                                 optVec[imgNr].insert(*it);
00129                             };
00130                             return;
00131                         };
00132                     };
00133                     optVec[imgNr].insert(varname);
00134                 };
00135             };
00136         };
00137     };
00138 };
00139 
00140 // remove given variable from optvec, handle also correct grouped variables
00141 void RemoveFromOptVec(HuginBase::OptimizeVector& optVec, std::string varname, size_t imgNr, std::vector<std::set<std::string> > groupedVars)
00142 {
00143     for(size_t i=0; i<groupedVars.size(); i++)
00144     {
00145         if(set_contains(groupedVars[i], varname))
00146         {
00147             for(std::set<std::string>::const_iterator it=groupedVars[i].begin(); it!=groupedVars[i].end(); ++it)
00148             {
00149                 optVec[imgNr].erase(*it);
00150             };
00151             return;
00152         };
00153     };
00154     optVec[imgNr].erase(varname);
00155 };
00156 
00157 // link or unlink the parsed image variables
00158 void UnLinkVars(HuginBase::Panorama& pano, Parser::ParseVarVec parseVec, bool link)
00159 {
00160     for(size_t i=0; i<parseVec.size(); i++)
00161     {
00162         //skip invalid image numbers
00163         if(parseVec[i].imgNr<0 || parseVec[i].imgNr>=(int)pano.getNrOfImages())
00164         {
00165             continue;
00166         };
00167 
00168         //convert to ImageVariableGroup::IVE_name format
00169         std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> variables;
00170 #define image_variable( name, type, default_value ) \
00171     if (HuginBase::PTOVariableConverterFor##name::checkApplicability(parseVec[i].varname))\
00172     {\
00173         variables.insert(HuginBase::ImageVariableGroup::IVE_##name);\
00174     };
00175 #include "panodata/image_variables.h"
00176 #undef image_variable
00177 
00178         if(!variables.empty())
00179         {
00180             //lens variable
00181             if(set_contains(HuginBase::StandardImageVariableGroups::getLensVariables(), *variables.begin()))
00182             {
00183                 HuginBase::ImageVariableGroup group(HuginBase::StandardImageVariableGroups::getLensVariables(), pano);
00184                 if (link)
00185                 {
00186                     std::cout << "Linking";
00187                     group.linkVariableImage(*variables.begin(), parseVec[i].imgNr);
00188                 }
00189                 else
00190                 {
00191                     std::cout << "Unlinking";
00192                     group.unlinkVariableImage(*variables.begin(), parseVec[i].imgNr);
00193                     group.updatePartNumbers();
00194                 }
00195                 std::cout << " image variable " << parseVec[i].varname << " for image " << parseVec[i].imgNr << std::endl;
00196             }
00197             else
00198             {
00199                 //stack variables
00200                 // handle yaw, pitch, roll, TrX, TrY and TrZ always together
00201                 if(set_contains(HuginBase::StandardImageVariableGroups::getStackVariables(), *variables.begin()))
00202                 {
00203                     HuginBase::ImageVariableGroup group(HuginBase::StandardImageVariableGroups::getStackVariables(), pano);
00204                     if (link)
00205                     {
00206                         std::cout << "Linking";
00207                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Yaw, parseVec[i].imgNr);
00208                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Pitch, parseVec[i].imgNr);
00209                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Roll, parseVec[i].imgNr);
00210                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_X, parseVec[i].imgNr);
00211                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Y, parseVec[i].imgNr);
00212                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Z, parseVec[i].imgNr);
00213                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlaneYaw, parseVec[i].imgNr);
00214                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlanePitch, parseVec[i].imgNr);
00215                     }
00216                     else
00217                     {
00218                         std::cout << "Unlinking";
00219                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Yaw, parseVec[i].imgNr);
00220                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Pitch, parseVec[i].imgNr);
00221                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Roll, parseVec[i].imgNr);
00222                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_X, parseVec[i].imgNr);
00223                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Y, parseVec[i].imgNr);
00224                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Z, parseVec[i].imgNr);
00225                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlaneYaw, parseVec[i].imgNr);
00226                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlanePitch, parseVec[i].imgNr);
00227                         group.updatePartNumbers();
00228                     }
00229                     std::cout << " image position (ypr, TrXYZ, Tpyp) for image " << parseVec[i].imgNr << std::endl;
00230                 }
00231                 else
00232                 {
00233                     std::cerr << "Warning: " << parseVec[i].varname << " is not a valid linkable variable." << std::endl;
00234                 };
00235             };
00236         };
00237     };
00238 };
00239 
00240 // parse number, take an optional % sign into account
00241 // in case of a relativ value the result is normed to 1
00242 bool ParseCoordinateRelativ(const std::string& s, double& val, bool& relativ)
00243 {
00244     size_t pos = s.find('%');
00245     relativ = (pos != std::string::npos);
00246     if (relativ)
00247     {
00248         if (pos < s.length() - 1)
00249         {
00250             // there are characters afters the percent sign
00251             // this is not supported
00252             return false;
00253         };
00254         if( hugin_utils::stringToDouble(s.substr(0, pos), val))
00255         {
00256             val /= 100.0;
00257             return true;
00258         };
00259     }
00260     else
00261     {
00262         // enforce integer values
00263         int intValue;
00264         if (hugin_utils::stringToInt(s, intValue))
00265         {
00266             val = intValue;
00267             return true;
00268         };
00269     };
00270     return false;
00271 }
00272 
00273 // parse given crop string s and set corresponding crop in pano for images in UIntSet
00274 void SetCropToImages(const std::string& s, HuginBase::Panorama& pano, HuginBase::UIntSet& imgs)
00275 {
00276     std::vector<std::string> coords = hugin_utils::SplitString(s, ",");
00277     if (coords.size() == 2)
00278     {
00279         // only 2 coordinates, take them as width and height and activate autocenter crop
00280         double width, height;
00281         bool relWidth = false;
00282         bool relHeight = false;
00283         if (ParseCoordinateRelativ(coords[0], width, relWidth) && ParseCoordinateRelativ(coords[1], height, relHeight))
00284         {
00285             for (auto& i : imgs)
00286             {
00287                 HuginBase::SrcPanoImage img = pano.getSrcImage(i);
00288                 vigra::Rect2D cropRect;
00289                 cropRect.setSize(relWidth ? (img.getWidth()*width) : width, relHeight ? (img.getHeight()*height) : height);
00290                 img.setCropRect(cropRect);
00291                 img.setAutoCenterCrop(true);
00292                 pano.setSrcImage(i, img);
00293                 pano.changeFinished();
00294                 // print result
00295                 std::cout << "Set crop for image " << i << " to " << pano.getImage(i).getCropRect() << std::endl;
00296             };
00297         }
00298         else
00299         {
00300             std::cerr << "Could not parse crop string \"" << s << "\"." << std::endl;
00301             return;
00302         };
00303     }
00304     else
00305     {
00306         if (coords.size() == 4)
00307         {
00308             // we got 4 coordinates
00309             int left, right, top, bottom;
00310             if (hugin_utils::stringToInt(coords[0], left) && hugin_utils::stringToInt(coords[1], right) &&
00311                 hugin_utils::stringToInt(coords[2], top) && hugin_utils::stringToInt(coords[3], bottom))
00312             {
00313                 vigra::Rect2D cropRect;
00314                 if (right > left && bottom > top)
00315                 {
00316                     cropRect.setUpperLeft(vigra::Point2D(left, top));
00317                     cropRect.setLowerRight(vigra::Point2D(right, bottom));
00318                 }
00319                 else
00320                 {
00321                     std::cerr << "Crop \"" << s << "\" is an invalid crop area." << std::endl;
00322                     return;
00323                 };
00324                 for (auto& i : imgs)
00325                 {
00326                     HuginBase::SrcPanoImage img = pano.getSrcImage(i);
00327                     img.setAutoCenterCrop(false);
00328                     img.setCropRect(cropRect);
00329                     pano.setSrcImage(i, img);
00330                     pano.changeFinished();
00331                     // print result
00332                     std::cout << "Set crop for image " << i << " to " << pano.getImage(i).getCropRect() << std::endl;
00333                 };
00334             }
00335             else
00336             {
00337                 std::cerr << "Could not parse crop values \"" << s << "\"." << std::endl;
00338                 return;
00339             };
00340         }
00341         else
00342         {
00343             std::cerr << "Invalid coordinates \"" << s << "\"." << std::endl;
00344             return;
00345         }
00346     };
00347     return;
00348 }
00349 
00350 // set the crop from the string
00351 void SetCrop(HuginBase::Panorama& pano, const std::string& crop)
00352 {
00353     // split string at ';'
00354     std::vector<std::string> splitResult = hugin_utils::SplitString(crop, ";");
00355     // now process each sub-string
00356     for (auto& s : splitResult)
00357     {
00358         std::string subString = hugin_utils::StrTrim(s);
00359         if (subString.empty())
00360         {
00361             continue;
00362         };
00363         size_t pos = subString.find("=");
00364         if(subString[0]=='i' && pos==std::string::npos)
00365         { 
00366             std::cerr << "Crop expression \"" << s << "\" is not a valid crop." << std::endl;
00367             continue;
00368         };
00369         if (subString[0] == 'i')
00370         {
00371             if (pos < 2)
00372             {
00373                 std::cerr << "Crop expression \"" << s << "\" does not contain a valid image number."<< std::endl;
00374                 continue;
00375             };
00376             unsigned int imgNr;
00377             if(!hugin_utils::stringToUInt(subString.substr(1, pos-1), imgNr))
00378             { 
00379                 std::cerr << "Crop expression \"" << s << "\" does not contain a valid image number." << std::endl;
00380                 continue;
00381             };
00382             if (imgNr >= pano.getNrOfImages())
00383             {
00384                 std::cerr << "Pano does not contain image with number " << imgNr << std::endl;
00385                 continue;
00386             };
00387             HuginBase::UIntSet imgs;
00388             imgs.insert(imgNr);
00389             SetCropToImages(subString.substr(pos + 1), pano, imgs);
00390         }
00391         else
00392         {
00393             // update crop for all images
00394             HuginBase::UIntSet imgs;
00395             fill_set(imgs, 0, pano.getNrOfImages() - 1);
00396             SetCropToImages(subString, pano, imgs);
00397         };
00398     };
00399 };
00400 
00401 static void usage(const char* name)
00402 {
00403     std::cout << name << ": change image variables inside pto files" << std::endl
00404         << name << " version " << hugin_utils::GetHuginVersion() << std::endl
00405         << std::endl
00406         << "Usage:  " << name << " [options] --opt|--link|--unlink|--set varlist input.pto" << std::endl
00407         << std::endl
00408         << "     -o, --output=file.pto  Output Hugin PTO file. Default: <filename>_var.pto" << std::endl
00409         << "     -h, --help             Shows this help" << std::endl
00410         << std::endl
00411         << "     --opt varlist          Change optimizer variables" << std::endl
00412         << "     --modify-opt           Modify the existing optimizer variables" << std::endl
00413         << "                            (without pto_var will start with an" << std::endl
00414         << "                             empty variables set)" << std::endl
00415         << "                            Examples:" << std::endl
00416         << "           --opt=y,p,r        Optimize yaw, pitch and roll of all images" << std::endl
00417         << "                              (special treatment for anchor image applies)" << std::endl
00418         << "           --opt=v0,b2        Optimize hfov of image 0 and barrel distortion" << std::endl
00419         << "                              of image 2" << std::endl
00420         << "           --opt=v,!v0        Optimize field of view for all images except" << std::endl
00421         << "                              for the first image" << std::endl
00422         << "           --opt=!a,!b,!c     Don't optimise distortion (works only with" << std::endl
00423         << "                              switch --modify-opt together)" << std::endl
00424         << std::endl
00425         << "     --link varlist         Link given variables" << std::endl
00426         << "                            Example:" << std::endl
00427         << "           --link=v3          Link hfov of image 3" << std::endl
00428         << "           --link=a1,b1,c1    Link distortions parameter for image 1" << std::endl
00429         << std::endl
00430         << "     --unlink varlist       Unlink given variables" << std::endl
00431         << "                            Examples:" << std::endl
00432         << "           --unlink=v5        Unlink hfov for image 5" << std::endl
00433         << "           --unlink=a2,b2,c2  Unlink distortions parameters for image 2" << std::endl
00434         << std::endl
00435         << "     --set varlist          Sets variables to new values" << std::endl
00436         << "                            Examples:" << std::endl
00437         << "           --set=y0=0,r0=0,p0=0  Resets position of image 0" << std::endl
00438         << "           --set=Vx4=-10,Vy4=10  Sets vignetting offset for image 4" << std::endl
00439         << "           --set=v=20            Sets the field of view to 20 for all images" << std::endl
00440         << "           --set=y=val+20        Increase yaw by 20 deg for all images" << std::endl
00441         << "           --set=v=val*1.1       Increase fov by 10 % for all images" << std::endl
00442         << "           --set=y=i*20          Set yaw to 0, 20, 40, ..." << std::endl
00443         << "     --set-from-file filename  Sets variables to new values" << std::endl
00444         << "                               It reads the varlist from a file" << std::endl
00445         << std::endl
00446         << "     --crop=left,right,top,bottom Set the crop for all images" << std::endl
00447         << "     --crop=width,height       Set the crop for all images and activate" << std::endl
00448         << "                               autocenter for crop" << std::endl
00449         << "                               relative values can be used with %" << std::endl
00450         << "     --crop=iNUM=left,right,top,bottom Set the crop for image NUM" << std::endl
00451         << "     --crop=iNUM=width,height  Set the crop for image NUM and" <<std::endl
00452         << "                             activate autocenter for crop"<<std::endl
00453         << "                             These switches can be used several times."<<std::endl
00454         << std::endl;
00455 }
00456 
00457 int main(int argc, char* argv[])
00458 {
00459     // parse arguments
00460     const char* optstring = "o:h";
00461 
00462     enum
00463     {
00464         SWITCH_OPT=1000,
00465         SWITCH_LINK,
00466         SWITCH_UNLINK,
00467         SWITCH_SET,
00468         SWITCH_SET_FILE,
00469         OPT_MODIFY_OPTVEC,
00470         SWITCH_CROP
00471     };
00472     static struct option longOptions[] =
00473     {
00474         {"output", required_argument, NULL, 'o' },
00475         {"opt", required_argument, NULL, SWITCH_OPT },
00476         {"link", required_argument, NULL, SWITCH_LINK },
00477         {"unlink", required_argument, NULL, SWITCH_UNLINK },
00478         {"set", required_argument, NULL, SWITCH_SET },
00479         {"set-from-file", required_argument, NULL, SWITCH_SET_FILE },
00480         {"modify-opt", no_argument, NULL, OPT_MODIFY_OPTVEC },
00481         {"crop", required_argument, NULL, SWITCH_CROP },
00482         {"help", no_argument, NULL, 'h' },
00483         0
00484     };
00485 
00486     Parser::ParseVarVec optVars;
00487     Parser::ParseVarVec linkVars;
00488     Parser::ParseVarVec unlinkVars;
00489     std::string setVars, crop;
00490     bool modifyOptVec=false;
00491     int c;
00492     std::string output;
00493     while ((c = getopt_long (argc, argv, optstring, longOptions,nullptr)) != -1)
00494     {
00495         switch (c)
00496         {
00497             case 'o':
00498                 output = optarg;
00499                 break;
00500             case 'h':
00501                 usage(hugin_utils::stripPath(argv[0]).c_str());
00502                 return 0;
00503             case SWITCH_OPT:
00504                 Parser::ParseVariableString(optVars, std::string(optarg), std::cerr, ParseSingleOptVar);
00505                 break;
00506             case SWITCH_LINK:
00507                 Parser::ParseVariableString(linkVars, std::string(optarg), std::cerr, ParseSingleLinkVar);
00508                 break;
00509             case SWITCH_UNLINK:
00510                 Parser::ParseVariableString(unlinkVars, std::string(optarg), std::cerr, ParseSingleLinkVar);
00511                 break;
00512             case SWITCH_SET:
00513                 if (!setVars.empty())
00514                 {
00515                     setVars.append(",");
00516                 };
00517                 setVars.append(optarg);
00518                 break;
00519             case SWITCH_SET_FILE:
00520                 {
00521                     std::ifstream ifs(optarg);
00522                     if(ifs.is_open())
00523                     {
00524                         std::ostringstream contents;
00525                         contents << ifs.rdbuf();
00526                         ifs.close();
00527                         setVars = contents.str();
00528                     }
00529                     else
00530                     {
00531                         std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not open file " << optarg << std::endl;
00532                         return 1;
00533                     };
00534                 };
00535                 break;
00536             case OPT_MODIFY_OPTVEC:
00537                 modifyOptVec=true;
00538                 break;
00539             case SWITCH_CROP:
00540                 if (!crop.empty())
00541                 {
00542                     crop.append(";");
00543                 };
00544                 crop.append(optarg);
00545                 break;
00546             case ':':
00547             case '?':
00548                 // missing argument or invalid switch
00549                 return 1;
00550                 break;
00551             default:
00552                 // this should not happen
00553                 abort();
00554 
00555         }
00556     }
00557 
00558     if (argc - optind != 1)
00559     {
00560         if (argc - optind < 1)
00561         {
00562             std::cerr << hugin_utils::stripPath(argv[0]) << ": No project file given." << std::endl;
00563         }
00564         else
00565         {
00566             std::cerr << hugin_utils::stripPath(argv[0]) << ": Only one project file expected." << std::endl;
00567         };
00568         return 1;
00569     };
00570 
00571     if(optVars.empty() && linkVars.empty() && unlinkVars.empty() && setVars.empty() && crop.empty())
00572     {
00573         std::cerr << hugin_utils::stripPath(argv[0]) << ": no variables to modify given" << std::endl;
00574         return 1;
00575     };
00576 
00577     std::string input=argv[optind];
00578     // read panorama
00579     HuginBase::Panorama pano;
00580     std::ifstream prjfile(input.c_str());
00581     if (!prjfile.good())
00582     {
00583         std::cerr << "could not open script : " << input << std::endl;
00584         return 1;
00585     }
00586     pano.setFilePrefix(hugin_utils::getPathPrefix(input));
00587     AppBase::DocumentData::ReadWriteError err = pano.readData(prjfile);
00588     if (err != AppBase::DocumentData::SUCCESSFUL)
00589     {
00590         std::cerr << "error while parsing panos tool script: " << input << std::endl;
00591         std::cerr << "AppBase::DocumentData::ReadWriteError code: " << err << std::endl;
00592         return 1;
00593     }
00594 
00595     if(pano.getNrOfImages()==0)
00596     {
00597         std::cerr << "error: project file does not contains any image" << std::endl;
00598         std::cerr << "aborting processing" << std::endl;
00599         return 1;
00600     };
00601 
00602     //link/unlink variables
00603     if(!linkVars.empty())
00604     {
00605         std::cout << "Linking image variables" << std::endl;
00606         UnLinkVars(pano, linkVars, true);
00607         std::cout << std::endl;
00608     };
00609 
00610     if(!unlinkVars.empty())
00611     {
00612         std::cout << "Unlinking image variables" << std::endl;
00613         UnLinkVars(pano, unlinkVars, false);
00614         std::cout << std::endl;
00615     };
00616 
00617     // set variables to new value
00618     if(!setVars.empty())
00619     {
00620         std::cout << "Setting image variables" << std::endl;
00621         Parser::PanoParseExpression(pano, setVars);
00622         std::cout << std::endl;
00623     };
00624 
00625     // update optimzer vector
00626     if(!optVars.empty())
00627     {
00628         std::cout << "Updating optimizer variables" << std::endl;
00629         std::set<size_t> refImgs=pano.getRefImages();
00630         bool linkRefImgsYaw=false;
00631         bool linkRefImgsPitch=false;
00632         bool linkRefImgsRoll=false;
00633         pano.checkRefOptStatus(linkRefImgsYaw, linkRefImgsPitch, linkRefImgsRoll);
00634 
00635         //simplify handling of variable groups
00636         std::vector<std::set<std::string> > groupedVars;
00637         std::set<std::string> varSet;
00638         varSet.insert("Vb");
00639         varSet.insert("Vc");
00640         varSet.insert("Vd");
00641         groupedVars.push_back(varSet);
00642         varSet.clear();
00643         varSet.insert("Vx");
00644         varSet.insert("Vy");
00645         groupedVars.push_back(varSet);
00646         varSet.clear();
00647         varSet.insert("Ra");
00648         varSet.insert("Rb");
00649         varSet.insert("Rc");
00650         varSet.insert("Rd");
00651         varSet.insert("Re");
00652         groupedVars.push_back(varSet);
00653 
00654         HuginBase::OptimizeVector optVec;
00655         if(modifyOptVec)
00656         {
00657             optVec=pano.getOptimizeVector();
00658         };
00659         if(optVec.size()!=pano.getNrOfImages())
00660         {
00661             optVec.resize(pano.getNrOfImages());
00662         };
00663         for(size_t i=0; i<optVars.size(); i++)
00664         {
00665             //skip invalid image numbers
00666             if(optVars[i].imgNr>=(int)pano.getNrOfImages())
00667             {
00668                 continue;
00669             };
00670             if(optVars[i].imgNr==-1)
00671             {
00672                 for(size_t imgNr=0; imgNr<pano.getNrOfImages(); imgNr++)
00673                 {
00674                     if(optVars[i].flag)
00675                     {
00676                         RemoveFromOptVec(optVec, optVars[i].varname, imgNr, groupedVars);
00677                     }
00678                     else
00679                     {
00680                         AddToOptVec(optVec, optVars[i].varname, imgNr, refImgs, linkRefImgsYaw, linkRefImgsPitch, linkRefImgsRoll, groupedVars);
00681                     };
00682                 };
00683             }
00684             else
00685             {
00686                 if(optVars[i].flag)
00687                 {
00688                     RemoveFromOptVec(optVec, optVars[i].varname, optVars[i].imgNr, groupedVars);
00689                 }
00690                 else
00691                 {
00692                     AddToOptVec(optVec, optVars[i].varname, optVars[i].imgNr, refImgs, true, true, true, groupedVars);
00693                 };
00694             };
00695         };
00696         pano.setOptimizerSwitch(0);
00697         pano.setPhotometricOptimizerSwitch(0);
00698         pano.setOptimizeVector(optVec);
00699         std::cout << "Optimizer variables:" << std::endl;
00700         for (size_t i = 0; i < optVec.size(); ++i)
00701         {
00702             std::cout << "Image " << i << ": ";
00703             std::copy(optVec[i].begin(), optVec[i].end(), std::ostream_iterator<std::string>(std::cout, " "));
00704             std::cout << std::endl;
00705         };
00706         std::cout << std::endl;
00707     };
00708 
00709     // update crop
00710     if (!crop.empty())
00711     {
00712         std::cout << "Setting image crop" << std::endl;
00713         SetCrop(pano, crop);
00714         std::cout << std::endl;
00715     };
00716 
00717     //write output
00718     HuginBase::UIntSet imgs;
00719     fill_set(imgs,0, pano.getNrOfImages()-1);
00720     // Set output .pto filename if not given
00721     if (output=="")
00722     {
00723         output=input.substr(0,input.length()-4).append("_var.pto");
00724     }
00725     std::ofstream of(output.c_str());
00726     pano.printPanoramaScript(of, pano.getOptimizeVector(), pano.getOptions(), imgs, false, hugin_utils::getPathPrefix(input));
00727     std::cout << std::endl << "Written output to " << output << std::endl;
00728     return 0;
00729 }

Generated on 22 May 2018 for Hugintrunk by  doxygen 1.4.7