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 #ifndef WIN32
00031 #include <unistd.h>
00032 #endif
00033 #include <panodata/Panorama.h>
00034 #include <panodata/ImageVariableTranslate.h>
00035 #include <panodata/ImageVariableGroup.h>
00036 #include <panodata/StandardImageVariableGroups.h>
00037 #include "hugin_utils/utils.h"
00038 #include "ParseExp.h"
00039 
00040 using namespace std;
00041 using namespace HuginBase;
00042 using namespace AppBase;
00043 
00044 struct ParseVar
00045 {
00046     std::string varname;
00047     int imgNr;
00048     std::string expression;
00049     bool removeOpt;
00050     ParseVar(): varname(""), imgNr(-1), expression(""), removeOpt(false) {};
00051 };
00052 
00053 typedef std::vector<ParseVar> ParseVarVec;
00054 
00055 bool ParseVarNumber(const std::string&s, ParseVar& var)
00056 {
00057     std::size_t pos = s.find_first_of("0123456789");
00058     std::string varName;
00059     if (pos == std::string::npos)
00060     {
00061         varName = s;
00062         var.imgNr = -1;
00063     }
00064     else
00065     {
00066         if (pos == 0)
00067         {
00068             return false;
00069         };
00070         varName = s.substr(0, pos);
00071         if (!hugin_utils::stringToInt(s.substr(pos, s.length() - pos), var.imgNr))
00072         {
00073             return false;
00074         };
00075     }
00076 #define image_variable( name, type, default_value ) \
00077     if (HuginBase::PTOVariableConverterFor##name::checkApplicability(varName))\
00078     {\
00079         var.varname=varName;\
00080         return true;\
00081     };
00082 #include "panodata/image_variables.h"
00083 #undef image_variable
00084     return false;
00085 };
00086 
00087 // parse a single variable and put result in struct ParseVar
00088 void ParseSingleOptVar(ParseVarVec& varVec, const std::string& s)
00089 {
00090     // parse following regex ([!]?)([a-zA-Z]{1,3})(\\d*?) 
00091     std::string tempString(s);
00092     ParseVar var;
00093     var.removeOpt = (tempString[0] == '!');
00094     if (var.removeOpt)
00095     {
00096         tempString.erase(0, 1);
00097     };
00098     if (ParseVarNumber(tempString, var))
00099     {
00100         varVec.push_back(var);
00101     };
00102 };
00103 
00104 void ParseSingleLinkVar(ParseVarVec& varVec, const std::string& s)
00105 {
00106     // parse following regex ([a-zA-Z]{1,3})(\\d+?)
00107     ParseVar var;
00108     if (ParseVarNumber(s, var))
00109     {
00110         varVec.push_back(var);
00111     };
00112 };
00113 
00114 void ParseSingleVar(ParseVarVec& varVec, const std::string& s)
00115 {
00116     // parse following regex ([a-zA-Z]{1,3})(\\d*?)=(.*)
00117     const std::size_t pos = s.find_first_of("=", 0);
00118     if (pos != std::string::npos && pos > 0 && pos < s.length() - 1)
00119     {
00120         ParseVar var;
00121         const std::string tempString(s.substr(0, pos));
00122         if (ParseVarNumber(tempString, var))
00123         {
00124             var.expression = s.substr(pos + 1, s.length() - pos - 1);
00125             varVec.push_back(var);
00126         };
00127     };
00128 };
00129 
00130 //parse complete variables string
00131 void ParseVariableString(ParseVarVec& parseVec, const std::string& input, void (*func)(ParseVarVec&, const std::string&))
00132 {
00133     std::vector<std::string> splitResult = hugin_utils::SplitString(input, ", ");
00134     for(size_t i=0; i<splitResult.size(); i++)
00135     {
00136         (*func)(parseVec, splitResult[i]);
00137     };
00138 };
00139 
00140 // adds given varname to optVec
00141 // does some additional checking:
00142 //   1. don't add y,p,r for anchor image
00143 //   2. handle vignetting and EMoR parameters as group
00144 void AddToOptVec(HuginBase::OptimizeVector& optVec, std::string varname, size_t imgNr,
00145                  std::set<size_t> refImgs, bool linkRefImgsYaw, bool linkRefImgsPitch, bool linkRefImgsRoll, std::vector<std::set<std::string> > groupedVars)
00146 {
00147     if(varname=="y")
00148     {
00149         if(!set_contains(refImgs, imgNr) || linkRefImgsYaw)
00150         {
00151             optVec[imgNr].insert(varname);
00152         };
00153     }
00154     else
00155     {
00156         if(varname=="p")
00157         {
00158             if(!set_contains(refImgs, imgNr) || linkRefImgsPitch)
00159             {
00160                 optVec[imgNr].insert(varname);
00161             };
00162         }
00163         else
00164         {
00165             if(varname=="r")
00166             {
00167                 if(!set_contains(refImgs, imgNr) || linkRefImgsRoll)
00168                 {
00169                     optVec[imgNr].insert(varname);
00170                 };
00171             }
00172             else
00173             {
00174                 if(varname=="TrX" || varname=="TrY" || varname=="TrZ" || varname=="Tpy" || varname=="Tpp")
00175                 {
00176                     if(!set_contains(refImgs, imgNr))
00177                     {
00178                         optVec[imgNr].insert(varname);
00179                     };
00180                 }
00181                 else
00182                 {
00183                     for(size_t i=0; i<groupedVars.size(); i++)
00184                     {
00185                         if(set_contains(groupedVars[i], varname))
00186                         {
00187                             for(std::set<std::string>::const_iterator it=groupedVars[i].begin(); it!=groupedVars[i].end(); ++it)
00188                             {
00189                                 optVec[imgNr].insert(*it);
00190                             };
00191                             return;
00192                         };
00193                     };
00194                     optVec[imgNr].insert(varname);
00195                 };
00196             };
00197         };
00198     };
00199 };
00200 
00201 // remove given variable from optvec, handle also correct grouped variables
00202 void RemoveFromOptVec(HuginBase::OptimizeVector& optVec, std::string varname, size_t imgNr, std::vector<std::set<std::string> > groupedVars)
00203 {
00204     for(size_t i=0; i<groupedVars.size(); i++)
00205     {
00206         if(set_contains(groupedVars[i], varname))
00207         {
00208             for(std::set<std::string>::const_iterator it=groupedVars[i].begin(); it!=groupedVars[i].end(); ++it)
00209             {
00210                 optVec[imgNr].erase(*it);
00211             };
00212             return;
00213         };
00214     };
00215     optVec[imgNr].erase(varname);
00216 };
00217 
00218 // link or unlink the parsed image variables
00219 void UnLinkVars(Panorama& pano, ParseVarVec parseVec, bool link)
00220 {
00221     for(size_t i=0; i<parseVec.size(); i++)
00222     {
00223         //skip invalid image numbers
00224         if(parseVec[i].imgNr<0 || parseVec[i].imgNr>=(int)pano.getNrOfImages())
00225         {
00226             continue;
00227         };
00228 
00229         //convert to ImageVariableGroup::IVE_name format
00230         std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> variables;
00231 #define image_variable( name, type, default_value ) \
00232     if (HuginBase::PTOVariableConverterFor##name::checkApplicability(parseVec[i].varname))\
00233     {\
00234         variables.insert(HuginBase::ImageVariableGroup::IVE_##name);\
00235     };
00236 #include "panodata/image_variables.h"
00237 #undef image_variable
00238 
00239         if(!variables.empty())
00240         {
00241             //lens variable
00242             if(set_contains(HuginBase::StandardImageVariableGroups::getLensVariables(), *variables.begin()))
00243             {
00244                 HuginBase::ImageVariableGroup group(HuginBase::StandardImageVariableGroups::getLensVariables(), pano);
00245                 if (link)
00246                 {
00247                     group.linkVariableImage(*variables.begin(), parseVec[i].imgNr);
00248                 }
00249                 else
00250                 {
00251                     group.unlinkVariableImage(*variables.begin(), parseVec[i].imgNr);
00252                     group.updatePartNumbers();
00253                 }
00254             }
00255             else
00256             {
00257                 //stack variables
00258                 // handle yaw, pitch, roll, TrX, TrY and TrZ always together
00259                 if(set_contains(HuginBase::StandardImageVariableGroups::getStackVariables(), *variables.begin()))
00260                 {
00261                     HuginBase::ImageVariableGroup group(HuginBase::StandardImageVariableGroups::getStackVariables(), pano);
00262                     if (link)
00263                     {
00264                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Yaw, parseVec[i].imgNr);
00265                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Pitch, parseVec[i].imgNr);
00266                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Roll, parseVec[i].imgNr);
00267                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_X, parseVec[i].imgNr);
00268                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Y, parseVec[i].imgNr);
00269                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_Z, parseVec[i].imgNr);
00270                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlaneYaw, parseVec[i].imgNr);
00271                         group.linkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlanePitch, parseVec[i].imgNr);
00272                     }
00273                     else
00274                     {
00275                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Yaw, parseVec[i].imgNr);
00276                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Pitch, parseVec[i].imgNr);
00277                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Roll, parseVec[i].imgNr);
00278                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_X, parseVec[i].imgNr);
00279                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Y, parseVec[i].imgNr);
00280                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_Z, parseVec[i].imgNr);
00281                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlaneYaw, parseVec[i].imgNr);
00282                         group.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_TranslationPlanePitch, parseVec[i].imgNr);
00283                         group.updatePartNumbers();
00284                     }
00285                 }
00286                 else
00287                 {
00288                     cerr << "Warning: " << parseVec[i].varname << " is not a valid linkable variable." << endl;
00289                 };
00290             };
00291         };
00292     };
00293 };
00294 
00295 bool UpdateSingleVar(Panorama& pano, ParseVar parseVar, size_t imgNr)
00296 {
00297     double val=pano.getImage(imgNr).getVar(parseVar.varname);
00298     Parser::ConstantMap constMap;
00299     constMap["i"]=1.0*imgNr;
00300     constMap["val"]=val;
00301     cout << "Updating variable " << parseVar.varname << imgNr << ": " << val;
00302     if(Parser::ParseExpression(parseVar.expression, val, constMap))
00303     {
00304         cout << " -> " << val << endl;
00305         HuginBase::Variable var(parseVar.varname, val);
00306         pano.updateVariable(imgNr, var);
00307         return true;
00308     }
00309     else
00310     {
00311         cout << endl;
00312         cerr << "Could not parse given expression \"" << parseVar.expression << "\" for image " << imgNr << "." << endl;
00313         return false;
00314     };
00315 };
00316 
00317 static void usage(const char* name)
00318 {
00319     cout << name << ": change image variables inside pto files" << endl
00320          << name << " version " << hugin_utils::GetHuginVersion() << endl
00321          << endl
00322          << "Usage:  " << name << " [options] --opt|--link|--unlink|--set varlist input.pto" << endl
00323          << endl
00324          << "     -o, --output=file.pto  Output Hugin PTO file. Default: <filename>_var.pto" << endl
00325          << "     -h, --help             Shows this help" << endl
00326          << endl
00327          << "     --opt varlist          Change optimizer variables" << endl
00328          << "     --modify-opt           Modify the existing optimizer variables" << endl
00329          << "                            (without pto_var will start with an" << endl
00330          << "                             empty variables set)" << endl
00331          << "                            Examples:" << endl
00332          << "           --opt y,p,r        Optimize yaw, pitch and roll of all images" << endl
00333          << "                              (special treatment for anchor image applies)" << endl
00334          << "           --opt v0,b2        Optimize hfov of image 0 and barrel distortion" << endl
00335          << "                              of image 2" << endl
00336          << "           --opt v,!v0        Optimize field of view for all images except" << endl
00337          << "                              for the first image" << endl
00338          << "           --opt !a,!b,!c     Don't optimise distortion (works only with" << endl
00339          << "                              switch --modify-opt together)" << endl
00340          << endl
00341          << "     --link varlist         Link given variables" << endl
00342          << "                            Example:" << endl
00343          << "           --link v3          Link hfov of image 3" << endl
00344          << "           --link a1,b1,c1    Link distortions parameter for image 1" << endl
00345          << endl
00346          << "     --unlink varlist       Unlink given variables" << endl
00347          << "                            Examples:" << endl
00348          << "           --unlink v5        Unlink hfov for image 5" << endl
00349          << "           --unlink a2,b2,c2  Unlink distortions parameters for image 2" << endl
00350          << endl
00351          << "     --set varlist          Sets variables to new values" << endl
00352          << "                            Examples:" << endl
00353          << "           --set y0=0,r0=0,p0=0  Resets position of image 0" << endl
00354          << "           --set Vx4=-10,Vy4=10  Sets vignetting offset for image 4" << endl
00355          << "           --set v=20            Sets the field of view to 20 for all images" << endl
00356          << "           --set y=val+20        Increase yaw by 20 deg for all images" << endl
00357          << "           --set v=val*1.1       Increase fov by 10 % for all images" << endl
00358          << "           --set y=i*20          Set yaw to 0, 20, 40, ..." << endl
00359          << "     --set-from-file filename  Sets variables to new values" << endl
00360          << "                               It reads the varlist from a file" << endl
00361          << endl;
00362 }
00363 
00364 int main(int argc, char* argv[])
00365 {
00366     // parse arguments
00367     const char* optstring = "o:h";
00368 
00369     enum
00370     {
00371         SWITCH_OPT=1000,
00372         SWITCH_LINK,
00373         SWITCH_UNLINK,
00374         SWITCH_SET,
00375         SWITCH_SET_FILE,
00376         OPT_MODIFY_OPTVEC
00377     };
00378     static struct option longOptions[] =
00379     {
00380         {"output", required_argument, NULL, 'o' },
00381         {"opt", required_argument, NULL, SWITCH_OPT },
00382         {"link", required_argument, NULL, SWITCH_LINK },
00383         {"unlink", required_argument, NULL, SWITCH_UNLINK },
00384         {"set", required_argument, NULL, SWITCH_SET },
00385         {"set-from-file", required_argument, NULL, SWITCH_SET_FILE },
00386         {"modify-opt", no_argument, NULL, OPT_MODIFY_OPTVEC },
00387         {"help", no_argument, NULL, 'h' },
00388         0
00389     };
00390 
00391     ParseVarVec optVars;
00392     ParseVarVec linkVars;
00393     ParseVarVec unlinkVars;
00394     ParseVarVec setVars;
00395     bool modifyOptVec=false;
00396     int c;
00397     int optionIndex = 0;
00398     string output;
00399     while ((c = getopt_long (argc, argv, optstring, longOptions,&optionIndex)) != -1)
00400     {
00401         switch (c)
00402         {
00403             case 'o':
00404                 output = optarg;
00405                 break;
00406             case 'h':
00407                 usage(hugin_utils::stripPath(argv[0]).c_str());
00408                 return 0;
00409             case SWITCH_OPT:
00410                 ParseVariableString(optVars, std::string(optarg), ParseSingleOptVar);
00411                 break;
00412             case SWITCH_LINK:
00413                 ParseVariableString(linkVars, std::string(optarg), ParseSingleLinkVar);
00414                 break;
00415             case SWITCH_UNLINK:
00416                 ParseVariableString(unlinkVars, std::string(optarg), ParseSingleLinkVar);
00417                 break;
00418             case SWITCH_SET:
00419                 ParseVariableString(setVars, std::string(optarg), ParseSingleVar);
00420                 break;
00421             case SWITCH_SET_FILE:
00422                 {
00423                     ifstream ifs(optarg);
00424                     if(ifs.is_open())
00425                     {
00426                         ostringstream contents;
00427                         contents << ifs.rdbuf();
00428                         ifs.close();
00429                         string s(contents.str());
00430                         hugin_utils::ReplaceAll(s, "\n", ',');
00431                         ParseVariableString(setVars, s, ParseSingleVar);
00432                     }
00433                     else
00434                     {
00435                         cerr << "Could not open file " << optarg << endl;
00436                     };
00437                 };
00438                 break;
00439             case OPT_MODIFY_OPTVEC:
00440                 modifyOptVec=true;
00441                 break;
00442             case ':':
00443                 cerr <<"Option " << longOptions[optionIndex].name << " requires a parameter." << endl;
00444                 return 1;
00445                 break;
00446             case '?':
00447                 break;
00448             default:
00449                 abort ();
00450         }
00451     }
00452 
00453     if (argc - optind == 0)
00454     {
00455         cerr << "Error: " << argv[0] << " needs at least one project file." << endl;
00456         return 1;
00457     };
00458     if (argc - optind != 1)
00459     {
00460         cout << "Error: " << argv[0] << " can only work on one project file at one time" << endl;
00461         return 1;
00462     };
00463 
00464     if(optVars.size() + linkVars.size() + unlinkVars.size() + setVars.size()==0)
00465     {
00466         cerr << "Error: no variables to modify given" << endl;
00467         return 1;
00468     };
00469 
00470     string input=argv[optind];
00471     // read panorama
00472     Panorama pano;
00473     ifstream prjfile(input.c_str());
00474     if (!prjfile.good())
00475     {
00476         cerr << "could not open script : " << input << endl;
00477         return 1;
00478     }
00479     pano.setFilePrefix(hugin_utils::getPathPrefix(input));
00480     DocumentData::ReadWriteError err = pano.readData(prjfile);
00481     if (err != DocumentData::SUCCESSFUL)
00482     {
00483         cerr << "error while parsing panos tool script: " << input << endl;
00484         cerr << "DocumentData::ReadWriteError code: " << err << endl;
00485         return 1;
00486     }
00487 
00488     if(pano.getNrOfImages()==0)
00489     {
00490         cerr << "error: project file does not contains any image" << endl;
00491         cerr << "aborting processing" << endl;
00492         return 1;
00493     };
00494 
00495     //link/unlink variables
00496     if(linkVars.size()>0)
00497     {
00498         UnLinkVars(pano, linkVars, true);
00499     };
00500 
00501     if(unlinkVars.size()>0)
00502     {
00503         UnLinkVars(pano, unlinkVars, false);
00504     };
00505 
00506     // set variables to new value
00507     if(setVars.size()>0)
00508     {
00509         for(size_t i=0; i<setVars.size(); i++)
00510         {
00511             //skip invalid image numbers
00512             if(setVars[i].imgNr>=(int)pano.getNrOfImages())
00513             {
00514                 continue;
00515             };
00516             if(setVars[i].imgNr<0)
00517             {
00518                 UIntSet updatedImgs;
00519                 for(size_t j=0; j<pano.getNrOfImages(); j++)
00520                 {
00521                     //if we already update the variable in this image via links, skip it
00522                     if(set_contains(updatedImgs, j))
00523                     {
00524                         continue;
00525                     };
00526                     // skip following images, if expression could not parsed
00527                     if(!UpdateSingleVar(pano, setVars[i], j))
00528                     {
00529                         break;
00530                     };
00531                     updatedImgs.insert(j);
00532                     if(j==pano.getNrOfImages()-1)
00533                     {
00534                         break;
00535                     };
00536                     // now remember linked variables
00537                     const HuginBase::SrcPanoImage& img1=pano.getImage(j);
00538 #define image_variable( name, type, default_value ) \
00539     if (HuginBase::PTOVariableConverterFor##name::checkApplicability(setVars[i].varname))\
00540     {\
00541         if(img1.name##isLinked())\
00542         {\
00543             for(size_t k=j+1; k<pano.getNrOfImages(); k++)\
00544             {\
00545                 if(img1.name##isLinkedWith(pano.getImage(k)))\
00546                 {\
00547                     updatedImgs.insert(k);\
00548                 }\
00549             };\
00550         };\
00551     };
00552 #include "panodata/image_variables.h"
00553 #undef image_variable
00554                 };
00555             }
00556             else
00557             {
00558                 UpdateSingleVar(pano, setVars[i], setVars[i].imgNr);
00559             };
00560         };
00561     };
00562 
00563     // update optimzer vector
00564     if(optVars.size()>0)
00565     {
00566         std::set<size_t> refImgs=pano.getRefImages();
00567         bool linkRefImgsYaw=false;
00568         bool linkRefImgsPitch=false;
00569         bool linkRefImgsRoll=false;
00570         pano.checkRefOptStatus(linkRefImgsYaw, linkRefImgsPitch, linkRefImgsRoll);
00571 
00572         //simplify handling of variable groups
00573         std::vector<std::set<std::string> > groupedVars;
00574         std::set<std::string> varSet;
00575         varSet.insert("Vb");
00576         varSet.insert("Vc");
00577         varSet.insert("Vd");
00578         groupedVars.push_back(varSet);
00579         varSet.clear();
00580         varSet.insert("Vx");
00581         varSet.insert("Vy");
00582         groupedVars.push_back(varSet);
00583         varSet.clear();
00584         varSet.insert("Ra");
00585         varSet.insert("Rb");
00586         varSet.insert("Rc");
00587         varSet.insert("Rd");
00588         varSet.insert("Re");
00589         groupedVars.push_back(varSet);
00590 
00591         HuginBase::OptimizeVector optVec;
00592         if(modifyOptVec)
00593         {
00594             optVec=pano.getOptimizeVector();
00595         };
00596         if(optVec.size()!=pano.getNrOfImages())
00597         {
00598             optVec.resize(pano.getNrOfImages());
00599         };
00600         for(size_t i=0; i<optVars.size(); i++)
00601         {
00602             //skip invalid image numbers
00603             if(optVars[i].imgNr>=(int)pano.getNrOfImages())
00604             {
00605                 continue;
00606             };
00607             if(optVars[i].imgNr==-1)
00608             {
00609                 for(size_t imgNr=0; imgNr<pano.getNrOfImages(); imgNr++)
00610                 {
00611                     if(optVars[i].removeOpt)
00612                     {
00613                         RemoveFromOptVec(optVec, optVars[i].varname, imgNr, groupedVars);
00614                     }
00615                     else
00616                     {
00617                         AddToOptVec(optVec, optVars[i].varname, imgNr, refImgs, linkRefImgsYaw, linkRefImgsPitch, linkRefImgsRoll, groupedVars);
00618                     };
00619                 };
00620             }
00621             else
00622             {
00623                 if(optVars[i].removeOpt)
00624                 {
00625                     RemoveFromOptVec(optVec, optVars[i].varname, optVars[i].imgNr, groupedVars);
00626                 }
00627                 else
00628                 {
00629                     AddToOptVec(optVec, optVars[i].varname, optVars[i].imgNr, refImgs, true, true, true, groupedVars);
00630                 };
00631             };
00632         };
00633         pano.setOptimizerSwitch(0);
00634         pano.setPhotometricOptimizerSwitch(0);
00635         pano.setOptimizeVector(optVec);
00636     };
00637 
00638     //write output
00639     UIntSet imgs;
00640     fill_set(imgs,0, pano.getNrOfImages()-1);
00641     // Set output .pto filename if not given
00642     if (output=="")
00643     {
00644         output=input.substr(0,input.length()-4).append("_var.pto");
00645     }
00646     ofstream of(output.c_str());
00647     pano.printPanoramaScript(of, pano.getOptimizeVector(), pano.getOptions(), imgs, false, hugin_utils::getPathPrefix(input));
00648 
00649     cout << endl << "Written output to " << output << endl;
00650     return 0;
00651 }

Generated on 31 Jul 2015 for Hugintrunk by  doxygen 1.4.7