pto_lensstack.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, write to the Free Software
00023  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  *
00025  */
00026 
00027 #include <hugin_version.h>
00028 
00029 #include <fstream>
00030 #include <sstream>
00031 #include <getopt.h>
00032 #ifndef WIN32
00033 #include <unistd.h>
00034 #endif
00035 #include <panodata/Panorama.h>
00036 #include <panodata/StandardImageVariableGroups.h>
00037 #include <boost/algorithm/string.hpp>
00038 #include <boost/regex.hpp>
00039 #include <boost/lexical_cast.hpp>
00040 
00041 using namespace std;
00042 using namespace HuginBase;
00043 using namespace AppBase;
00044 
00045 struct ParsedImg
00046 {
00047     int imgNr;
00048     int lensStackNr;
00049 };
00050 
00051 typedef std::vector<ParsedImg> ParseImgVec;
00052 
00053 // parse a single variable and put result in struct ParseVar
00054 void ParseSingleImage(ParseImgVec& varVec, std::string s, std::string regExpression)
00055 {
00056     boost::regex reg(regExpression);
00057     boost::smatch matches;
00058     if(boost::regex_match(s, matches, reg))
00059     {
00060         bool valid=true;
00061         if(matches.size()>1)
00062         {
00063             ParsedImg var;
00064             // parse image number
00065             std::string temp(matches[1].first, matches[1].second);
00066             try
00067             {
00068                 var.imgNr=boost::lexical_cast<int>(temp);
00069             }
00070             catch (boost::bad_lexical_cast)
00071             {
00072                 var.imgNr=-1;
00073             };
00074                 // read lens/stack number
00075             if(matches.size()>2)
00076             {
00077                 temp=std::string(matches[2].first, matches[2].second);
00078                 try
00079                 {
00080                     var.lensStackNr=boost::lexical_cast<int>(temp);
00081                 }
00082                 catch (boost::bad_lexical_cast)
00083                 {
00084                     valid=false;
00085                 };
00086             };
00087             if(valid)
00088             {
00089                 varVec.push_back(var);
00090             };
00091         };
00092     };
00093 };
00094 
00095 //parse complete variables string
00096 void ParseImageLensStackString(ParseImgVec& parseVec, std::string input, std::string regExpression)
00097 {
00098     std::vector<std::string> splitResult;
00099     boost::algorithm::split(splitResult, input, boost::algorithm::is_any_of(", "), boost::algorithm::token_compress_on);
00100     for(size_t i=0; i<splitResult.size();i++)
00101     {
00102         ParseSingleImage(parseVec, splitResult[i], regExpression);
00103     };
00104 };
00105 
00106 // assign a new lens/stack
00107 void NewPart(Panorama& pano, std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> vars, unsigned int imgNr)
00108 {
00109     for (std::set<HuginBase::ImageVariableGroup::ImageVariableEnum>::iterator it = vars.begin();  it != vars.end(); it++)
00110     {
00111         switch (*it)
00112         {
00113 #define image_variable( name, type, default_value )\
00114             case HuginBase::ImageVariableGroup::IVE_##name:\
00115                 pano.unlinkImageVariable##name(imgNr);\
00116                 break;
00117 #include <panodata/image_variables.h>
00118 #undef image_variable
00119         }
00120     }
00121 };
00122 
00123 static void usage(const char* name)
00124 {
00125     cout << name << ": modify assigned lenses and stack in pto files" << endl
00126          << name << " version " << DISPLAY_VERSION << endl
00127          << endl
00128          << "Usage:  " << name << " [options] --switches imglist input.pto" << endl
00129          << endl
00130          << "     -o, --output=file.pto   Output Hugin PTO file. Default: <filename>_lens.pto" << endl
00131          << "     -h, --help              Shows this help" << endl
00132          << endl
00133          << "     --new-lens imglist      Assign to given images a new lens number" << endl
00134          << "     --new-stack imglist     Assign to given images a new stack number" << endl
00135          << "                               Examples:" << endl
00136          << "           --new-lens i2          Image 2 gets a new lens" << endl
00137          << "           --new-stack i4,i5      Images 4 and 5 get a new stack" << endl    
00138          << endl
00139          << "     --change-lens imglist   Assign to given images a new lens number" << endl
00140          << "     --change-stack imglist  Assign to given images a new stack number" << endl
00141          << "                               Examples:" << endl
00142          << "           --change-lens i2=0      Image 2 is assigned lens number 0" << endl
00143          << "           --change-stack i4=0,i5=1   Image 4 is assigned to stack 0," << endl
00144          << "                                      image 5 to stack number 1" << endl    
00145          << endl;
00146 }
00147 
00148 int main(int argc, char* argv[])
00149 {
00150     // parse arguments
00151     const char* optstring = "o:h";
00152 
00153     enum
00154     {
00155         SWITCH_NEW_LENS=1000,
00156         SWITCH_NEW_STACK,
00157         SWITCH_CHANGE_LENS,
00158         SWITCH_CHANGE_STACK
00159     };
00160     static struct option longOptions[] =
00161     {
00162         {"output", required_argument, NULL, 'o' },
00163         {"new-lens", required_argument, NULL, SWITCH_NEW_LENS },
00164         {"new-stack", required_argument, NULL, SWITCH_NEW_STACK },
00165         {"change-lens", required_argument, NULL, SWITCH_CHANGE_LENS },
00166         {"change-stack", required_argument, NULL, SWITCH_CHANGE_STACK },
00167         {"help", no_argument, NULL, 'h' },
00168         0
00169     };
00170 
00171     ParseImgVec newLensImgs;
00172     ParseImgVec newStackImgs;
00173     ParseImgVec changeLensImgs;
00174     ParseImgVec changeStackImgs;
00175     int c;
00176     int optionIndex = 0;
00177     string output;
00178     while ((c = getopt_long (argc, argv, optstring, longOptions,&optionIndex)) != -1)
00179     {
00180         switch (c)
00181         {
00182             case 'o':
00183                 output = optarg;
00184                 break;
00185             case 'h':
00186                 usage(argv[0]);
00187                 return 0;
00188             case SWITCH_NEW_LENS:
00189                 ParseImageLensStackString(newLensImgs, std::string(optarg), "i(\\d+?)");
00190                 break;
00191             case SWITCH_NEW_STACK:
00192                 ParseImageLensStackString(newStackImgs, std::string(optarg), "i(\\d+?)");
00193                 break;
00194             case SWITCH_CHANGE_LENS:
00195                 ParseImageLensStackString(changeLensImgs, std::string(optarg), "i(\\d+?)=(\\d+?)");
00196                 break;
00197             case SWITCH_CHANGE_STACK:
00198                 ParseImageLensStackString(changeStackImgs, std::string(optarg), "i(\\d+?)=(\\d+?)");
00199                 break;
00200             case ':':
00201                 cerr <<"Option " << longOptions[optionIndex].name << " requires a parameter" << endl;
00202                 return 1;
00203                 break;
00204             case '?':
00205                 break;
00206             default:
00207                 abort ();
00208         }
00209     }
00210 
00211     if (argc - optind == 0)
00212     {
00213         cout << "Error: " << argv[0] << " needs at least one project file." << endl;
00214         return 1;
00215     };
00216     if (argc - optind != 1)
00217     {
00218         cout << "Error: " << argv[0] << " can only work on one project file at one time" << endl;
00219         return 1;
00220     };
00221 
00222     if(newLensImgs.size() + newStackImgs.size() + changeLensImgs.size() + changeStackImgs.size()==0)
00223     {
00224         cerr << "Error: no images/lens/stacks to modify given" << endl;
00225         return 1;
00226     };
00227 
00228     string input=argv[optind];
00229     // read panorama
00230     Panorama pano;
00231     ifstream prjfile(input.c_str());
00232     if (!prjfile.good())
00233     {
00234         cerr << "could not open script : " << input << endl;
00235         return 1;
00236     }
00237     pano.setFilePrefix(hugin_utils::getPathPrefix(input));
00238     DocumentData::ReadWriteError err = pano.readData(prjfile);
00239     if (err != DocumentData::SUCCESSFUL)
00240     {
00241         cerr << "error while parsing panos tool script: " << input << endl;
00242         cerr << "DocumentData::ReadWriteError code: " << err << endl;
00243         return 1;
00244     }
00245 
00246     if(pano.getNrOfImages()==0)
00247     {
00248         cerr << "error: project file does not contains any image" << endl;
00249         cerr << "aborting processing" << endl;
00250         return 1;
00251     };
00252 
00253     // new lenses
00254     if(newLensImgs.size()>0)
00255     {
00256         HuginBase::StandardImageVariableGroups variable_groups(pano);
00257         if(variable_groups.getLenses().getNumberOfParts()<pano.getNrOfImages())
00258         {
00259             for(size_t i=0; i<newLensImgs.size(); i++)
00260             {
00261                 //skip invalid image numbers
00262                 if(newLensImgs[i].imgNr<0 || newLensImgs[i].imgNr>=(int)pano.getNrOfImages())
00263                 {
00264                     continue;
00265                 };
00266                 NewPart(pano, HuginBase::StandardImageVariableGroups::getLensVariables(), newLensImgs[i].imgNr);
00267             };
00268         }
00269         else
00270         {
00271             cout << "Warning: Pto project contains already for each image an own lens" << endl
00272                  << "         Nothing to do." << endl;
00273         };
00274     };
00275 
00276     // new stacks
00277     if(newStackImgs.size()>0)
00278     {
00279         HuginBase::StandardImageVariableGroups variable_groups(pano);
00280         if(variable_groups.getStacks().getNumberOfParts()<pano.getNrOfImages())
00281         {
00282             for(size_t i=0; i<newStackImgs.size(); i++)
00283             {
00284                 //skip invalid image numbers
00285                 if(newStackImgs[i].imgNr<0 || newStackImgs[i].imgNr>=(int)pano.getNrOfImages())
00286                 {
00287                     continue;
00288                 };
00289                 NewPart(pano, HuginBase::StandardImageVariableGroups::getStackVariables(), newStackImgs[i].imgNr);
00290             };
00291         }
00292         else
00293         {
00294             cout << "Warning: Pto project contains already for each image an own stack" << endl
00295                  << "         Nothing to do." << endl;
00296         };
00297     };
00298 
00299     // change lenses
00300     if(changeLensImgs.size()>0)
00301     {
00302         HuginBase::StandardImageVariableGroups variable_groups(pano);
00303         size_t lensCount=variable_groups.getLenses().getNumberOfParts();
00304         if(lensCount>1)
00305         {
00306             for(size_t i=0; i<changeLensImgs.size(); i++)
00307             {
00308                 //skip invalid image numbers
00309                 if(changeLensImgs[i].imgNr<0 || changeLensImgs[i].imgNr>=(int)pano.getNrOfImages())
00310                 {
00311                     continue;
00312                 };
00313                 if(changeLensImgs[i].lensStackNr<0 || changeLensImgs[i].lensStackNr>=lensCount)
00314                 {
00315                     continue;
00316                 };
00317                 ImageVariableGroup group(StandardImageVariableGroups::getLensVariables(), pano);
00318                 group.switchParts(changeLensImgs[i].imgNr, changeLensImgs[i].lensStackNr);
00319             };
00320         }
00321         else
00322         {
00323             cout << "Warning: Pto project contains only one lens." << endl
00324                  << "         Therefor the lens can not be changed. Use --new-lens instead." << endl;
00325         };
00326     };
00327 
00328     // change stacks
00329     if(changeStackImgs.size()>0)
00330     {
00331         HuginBase::StandardImageVariableGroups variable_groups(pano);
00332         size_t stackCount=variable_groups.getStacks().getNumberOfParts();
00333         if(stackCount>1)
00334         {
00335             for(size_t i=0; i<changeStackImgs.size(); i++)
00336             {
00337                 //skip invalid image numbers
00338                 if(changeStackImgs[i].imgNr<0 || changeStackImgs[i].imgNr>=(int)pano.getNrOfImages())
00339                 {
00340                     continue;
00341                 };
00342                 if(changeStackImgs[i].lensStackNr<0 || changeStackImgs[i].lensStackNr>=stackCount)
00343                 {
00344                     continue;
00345                 };
00346                 ImageVariableGroup group(StandardImageVariableGroups::getStackVariables(), pano);
00347                 group.switchParts(changeStackImgs[i].imgNr, changeStackImgs[i].lensStackNr);
00348             };
00349         }
00350         else
00351         {
00352             cout << "Warning: Pto project contains only one stack." << endl
00353                  << "         Therefore the stack can not be changed. Use --new-stack instead." << endl;
00354         };
00355     };
00356 
00357     //write output
00358     UIntSet imgs;
00359     fill_set(imgs,0, pano.getNrOfImages()-1);
00360     // Set output .pto filename if not given
00361     if (output=="")
00362     {
00363         output=input.substr(0,input.length()-4).append("_lens.pto");
00364     }
00365     ofstream of(output.c_str());
00366     pano.printPanoramaScript(of, pano.getOptimizeVector(), pano.getOptions(), imgs, false, hugin_utils::getPathPrefix(input));
00367 
00368     cout << endl << "Written output to " << output << endl;
00369     return 0;
00370 }

Generated on Sun Sep 21 01:25:43 2014 for Hugintrunk by  doxygen 1.3.9.1