00001
00002
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
00358 UIntSet imgs;
00359 fill_set(imgs,0, pano.getNrOfImages()-1);
00360
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 }