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

Generated on 3 Dec 2016 for Hugintrunk by  doxygen 1.4.7