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

Generated on 4 Aug 2015 for Hugintrunk by  doxygen 1.4.7