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

Generated on 23 May 2016 for Hugintrunk by  doxygen 1.4.7