The new pto_gen.cpp works fine on Mac OS X. Will be in next (development) bundle.
Harry 2011/12/7 <[email protected]> > branch: > details: > http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/6f19ad8ebbf3 > changeset: 5689:6f19ad8ebbf3 > user: tmodes > date: Wed Dec 07 17:53:11 2011 +0100 > description: > > Added new tool pto_gen for generation of pto file from image files > > diffstat: > > src/hugin_base/hugin_utils/utils.cpp | 43 ++++ > src/hugin_base/hugin_utils/utils.h | 5 + > src/tools/CMakeLists.txt | 5 +- > src/tools/pto_gen.cpp | 351 > +++++++++++++++++++++++++++++++++++ > 4 files changed, 403 insertions(+), 1 deletions(-) > > diffs (450 lines): > > diff -r c2271b19d1a3 -r 6f19ad8ebbf3 src/hugin_base/hugin_utils/utils.cpp > --- a/src/hugin_base/hugin_utils/utils.cpp Sun Dec 04 09:38:58 2011 > +0100 > +++ b/src/hugin_base/hugin_utils/utils.cpp Wed Dec 07 17:53:11 2011 > +0100 > @@ -30,6 +30,7 @@ > #include <sys/time.h> > #endif > #include <time.h> > +#include <fstream> > #include <stdio.h> > #include <cstdio> > > @@ -222,5 +223,47 @@ > b = 0.0; > } > > +bool FileExists(const std::string filename) > +{ > + std::ifstream ifile(filename.c_str()); > + return !ifile.fail(); > +} > + > +std::string GetAbsoluteFilename(const std::string filename) > +{ > +#ifdef _WINDOWS > + char fullpath[_MAX_PATH]; > + _fullpath(fullpath,filename.c_str(),_MAX_PATH); > + return std::string(fullpath); > +#else > + //realpath works only with existing files > + //so as work around we create the file first, call then realpath > + //and delete the temp file > + /** @TODO replace realpath with function with works without this hack > */ > + bool tempFileCreated=false; > + if(!FileExists(filename)) > + { > + tempFileCreated=true; > + std::ofstream os(filename.c_str()); > + os.close(); > + }; > + char *real_path = realpath(filename.c_str(), NULL); > + std::string absPath; > + if(real_path!=NULL) > + { > + absPath=std::string(real_path); > + free(real_path); > + } > + else > + { > + absPath=filename; > + }; > + if(tempFileCreated) > + { > + remove(filename.c_str()); > + }; > + return absPath; > +#endif > +}; > > } //namespace > diff -r c2271b19d1a3 -r 6f19ad8ebbf3 src/hugin_base/hugin_utils/utils.h > --- a/src/hugin_base/hugin_utils/utils.h Sun Dec 04 09:38:58 2011 > +0100 > +++ b/src/hugin_base/hugin_utils/utils.h Wed Dec 07 17:53:11 2011 > +0100 > @@ -287,6 +287,11 @@ > IMPEX void ControlPointErrorColour(const double cperr, > double &r,double &g, double &b); > > + /** checks if file exists */ > + IMPEX bool FileExists(const std::string filename); > + > + /** returns the full absolute filename */ > + IMPEX std::string GetAbsoluteFilename(const std::string filename); > } // namespace > > > diff -r c2271b19d1a3 -r 6f19ad8ebbf3 src/tools/CMakeLists.txt > --- a/src/tools/CMakeLists.txt Sun Dec 04 09:38:58 2011 +0100 > +++ b/src/tools/CMakeLists.txt Wed Dec 07 17:53:11 2011 +0100 > @@ -35,6 +35,9 @@ > add_executable(pto_merge pto_merge.cpp) > target_link_libraries(pto_merge ${common_libs} ) > > +add_executable(pto_gen pto_gen.cpp) > +target_link_libraries(pto_gen ${common_libs} ) > + > add_executable(pano_trafo pano_trafo.cpp) > target_link_libraries(pano_trafo ${common_libs} ) > > @@ -45,6 +48,6 @@ > target_link_libraries(hugin_hdrmerge ${common_libs} ${image_libs} ) > > install(TARGETS nona vig_optimize autooptimiser fulla align_image_stack > linefind > - tca_correct pto2mk cpclean checkpto hugin_hdrmerge pano_trafo > pano_modify pto_merge > + tca_correct pto2mk cpclean checkpto hugin_hdrmerge pano_trafo > pano_modify pto_merge pto_gen > DESTINATION ${BINDIR}) > > diff -r c2271b19d1a3 -r 6f19ad8ebbf3 src/tools/pto_gen.cpp > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/src/tools/pto_gen.cpp Wed Dec 07 17:53:11 2011 +0100 > @@ -0,0 +1,351 @@ > +// -*- c-basic-offset: 4 -*- > + > +/** @file pto_gen.cpp > + * > + * @brief program to generate a pto file from given image files > + * > + * @author T. Modes > + * > + */ > + > +/* This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public > + * License as published by the Free Software Foundation; either > + * version 2 of the License, or (at your option) any later version. > + * > + * This software is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public > + * License along with this software; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 > USA > + * > + */ > + > +#include <hugin_version.h> > + > +#include <fstream> > +#include <getopt.h> > +#ifdef _WINDOWS > +#include <io.h> > +#endif > +#include <panodata/Panorama.h> > +#include <panodata/StandardImageVariableGroups.h> > +#include <algorithms/basic/CalculateMeanExposure.h> > +#include "hugin_utils/alphanum.h" > +#include <vigra/impex.hxx> > + > +using namespace std; > +using namespace HuginBase; > + > +static void usage(const char* name) > +{ > + cout << name << ": generate project file from images" << endl > + << name << " version " << DISPLAY_VERSION << endl > + << endl > + << "Usage: " << name << " [options] image1 [...]" << endl > + << endl > + << " Options:" << endl > + << " -o, --output=file.pto Output Hugin PTO file." << endl > + << " -p, --projection=INT Projection type (default: 0)" << > endl > + << " -f, --fov=FLOAT Horizontal field of view of > images (default: 50)" << endl > + << " -s, --stacklength=INT Number of images in stack" << > endl > + << " (default: 1, no stacks)" << endl > + << " -l, --linkstacks Link image positions in stacks" > << endl > + << " -h, --help Shows this help" << endl > + << endl; > +} > + > +int main(int argc, char* argv[]) > +{ > + // parse arguments > + const char* optstring = "o:p:f:s:lh"; > + > + static struct option longOptions[] = > + { > + {"output", required_argument, NULL, 'o' }, > + {"projection", required_argument, NULL, 'p' }, > + {"fov", required_argument, NULL, 'f' }, > + {"stacklength", required_argument, NULL, 's' }, > + {"linkstacks", no_argument, NULL, 'l' }, > + {"help", no_argument, NULL, 'h' }, > + 0 > + }; > + > + int c; > + int optionIndex = 0; > + string output; > + int projection=-1; > + float fov=-1; > + int stackLength=1; > + bool linkStacks=false; > + while ((c = getopt_long (argc, argv, optstring, > longOptions,&optionIndex)) != -1) > + { > + switch (c) > + { > + case 'o': > + output = optarg; > + break; > + case 'h': > + usage(argv[0]); > + return 0; > + case 'p': > + { > + projection=atoi(optarg); > + if((projection==0) && (strcmp(optarg,"0")!=0)) > + { > + cerr << "Could not parse image number."; > + return 1; > + }; > + if(projection<0) > + { > + cerr << "Invalid projection number." << endl; > + return 1; > + }; > + }; > + break; > + case 'f': > + fov=atof(optarg); > + if(fov<1 || fov>360) > + { > + cerr << "Invalid field of view"; > + return 1; > + }; > + break; > + case 's': > + stackLength=atoi(optarg); > + if(stackLength<1) > + { > + cerr << "Could not parse stack length." << endl; > + return 1; > + }; > + break; > + case 'l': > + linkStacks=true; > + break; > + case ':': > + cerr <<"Option " << longOptions[optionIndex].name << " > requires a number" << endl; > + return 1; > + break; > + case '?': > + break; > + default: > + abort (); > + } > + } > + > + if (argc - optind < 1) > + { > + usage(argv[0]); > + return 1; > + }; > + > + cout << "Generating pto file..." << endl; > + cout.flush(); > + > + std::vector<string> filelist; > + while(optind<argc) > + { > + string input=GetAbsoluteFilename(argv[optind]); > +#ifdef _WINDOWS > + //do globbing > + char drive[_MAX_DRIVE]; > + char dir[_MAX_DIR]; > + char fname[_MAX_FNAME]; > + char ext[_MAX_EXT]; > + char newFile[_MAX_PATH]; > + > + _splitpath(input.c_str(), drive, dir, NULL, NULL); > + > + struct _finddata_t finddata; > + intptr_t findhandle = _findfirst(input.c_str(), &finddata); > + if (findhandle != -1) > + { > + do > + { > + _splitpath(finddata.name, NULL, NULL, fname, ext); > + _makepath(newFile, drive, dir, fname, ext); > + //check if valid image file > + if(vigra::isImage(newFile)) > + { > + filelist.push_back(std::string(newFile)); > + }; > + } > + while (_findnext(findhandle, &finddata) == 0); > + _findclose(findhandle); > + } > +#else > + if(hugin_utils::FileExists(input)) > + { > + if(vigra::isImage(input.c_str())) > + { > + filelist.push_back(input); > + }; > + }; > +#endif > + optind++; > + }; > + > + if(filelist.size()==0) > + { > + cerr << "No valid image files given." << endl; > + return 1; > + }; > + > + //sort filenames > + sort(filelist.begin(),filelist.end(),doj::alphanum_less()); > + > + Panorama pano; > + for(size_t i=0; i<filelist.size();i++) > + { > + SrcPanoImage srcImage(filelist[i]); > + cout << "Reading " << filelist[i] << "..." << endl; > + if(projection>=0) > + { > + > srcImage.setProjection((HuginBase::BaseSrcPanoImage::Projection)projection); > + }; > + if(fov>0) > + { > + srcImage.setHFOV(fov); > + if(!srcImage.hasEXIFread()) > + { > + srcImage.setExifCropFactor(1.0); > + }; > + } > + else > + { > + //set plausible default value if they could not read from exif > + if(!srcImage.hasEXIFread()) > + { > + srcImage.setHFOV(50); > + srcImage.setExifCropFactor(1.0); > + }; > + }; > + try > + { > + vigra::ImageImportInfo info(filelist[i].c_str()); > + std::string pixelType=info.getPixelType(); > + if((pixelType=="UINT8") || (pixelType=="UINT16") || > (pixelType=="INT16")) > + { > + > srcImage.setResponseType(HuginBase::SrcPanoImage::RESPONSE_EMOR); > + } > + else > + { > + > srcImage.setResponseType(HuginBase::SrcPanoImage::RESPONSE_LINEAR); > + }; > + } > + catch(std::exception & e) > + { > + cerr << "ERROR: caught exception: " << e.what() << std::endl; > + cerr << "Could not get pixel type for file " << filelist[i] > << std::endl; > + }; > + > + pano.addImage(srcImage); > + }; > + > + if(pano.getNrOfImages()==0) > + { > + cerr << "Adding images to project files failed." << endl; > + return 1; > + }; > + > + //link lenses > + if(pano.getNrOfImages()>1) > + { > + StandardImageVariableGroups variable_groups(pano); > + ImageVariableGroup& lenses = variable_groups.getLenses(); > + > + for(size_t i=1;i<pano.getNrOfImages();i++) > + { > + int image=-1; > + const SrcPanoImage & srcImg=pano.getImage(i); > + for(size_t j=0;j<i;j++) > + { > + const SrcPanoImage & compareImg=pano.getImage(j); > + if(srcImg.getHFOV()==compareImg.getHFOV() && > + srcImg.getProjection()==compareImg.getProjection() && > + srcImg.getExifModel()==compareImg.getExifModel() && > + srcImg.getExifMake()==compareImg.getExifMake() && > + srcImg.getSize()==compareImg.getSize()) > + { > + image=j; > + break; > + }; > + }; > + if(image!=-1) > + { > + SrcPanoImage img=pano.getSrcImage(i); > + double ev=img.getExposureValue(); > + lenses.switchParts(i,lenses.getPartNumber(image)); > + > lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_ExposureValue, > i); > + img.setExposureValue(ev); > + > > lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceRed, > i); > + > > lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceBlue, > i); > + img.setWhiteBalanceRed(1); > + img.setWhiteBalanceBlue(1); > + pano.setSrcImage(i, img); > + }; > + }; > + cout << endl << "Assigned " << lenses.getNumberOfParts() << " > lenses." << endl; > + }; > + > + //link stacks > + if(stackLength>1) > + { > + stackLength=std::min<int>(stackLength,pano.getNrOfImages()); > + int stackCount=pano.getNrOfImages() / stackLength; > + if(pano.getNrOfImages() % stackLength > 0) > + { > + stackCount++; > + }; > + if(stackCount<pano.getNrOfImages()) > + { > + for(size_t stackNr=0;stackNr<stackCount;stackNr++) > + { > + size_t firstImgStack=stackNr*stackLength; > + for(size_t i=0;i<stackLength;i++) > + { > + if(firstImgStack+i<pano.getNrOfImages()) > + { > + > pano.linkImageVariableStack(firstImgStack,firstImgStack+i); > + if(linkStacks) > + { > + > pano.linkImageVariableYaw(firstImgStack,firstImgStack+i); > + > pano.linkImageVariablePitch(firstImgStack,firstImgStack+i); > + > pano.linkImageVariableRoll(firstImgStack,firstImgStack+i); > + }; > + }; > + }; > + }; > + cout << "Assigned " << stackCount << " stacks." << endl; > + }; > + }; > + > + //set output exposure value > + PanoramaOptions opt = pano.getOptions(); > + opt.outputExposureValue = > CalculateMeanExposure::calcMeanExposure(pano); > + pano.setOptions(opt); > + > + //output > + if(output=="") > + { > + > > output=hugin_utils::stripExtension(hugin_utils::stripPath(pano.getImage(0).getFilename())); > + if(pano.getNrOfImages()>1) > + { > + output.append("-"); > + > > output.append(hugin_utils::stripExtension(hugin_utils::stripPath(pano.getImage(pano.getNrOfImages()-1).getFilename()))); > + }; > + output=output.append(".pto"); > + }; > + output=GetAbsoluteFilename(output); > + //write output > + UIntSet imgs; > + fill_set(imgs,0, pano.getNrOfImages()-1); > + ofstream of(output.c_str()); > + pano.printPanoramaScript(of, pano.getOptimizeVector(), > pano.getOptions(), imgs, false, hugin_utils::getPathPrefix(output)); > + > + cout << endl << "Written output to " << output << endl; > + return 0; > +} > > > ------------------------------------------------------------------------------ > Cloud Services Checklist: Pricing and Packaging Optimization > This white paper is intended to serve as a reference, checklist and point > of > discussion for anyone considering optimizing the pricing and packaging > model > of a cloud services business. Read Now! > http://www.accelacomm.com/jaw/sfnl/114/51491232/ > _______________________________________________ > Hugin-cvs mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/hugin-cvs > -- You received this message because you are subscribed to the Google Groups "Hugin and other free panoramic software" group. A list of frequently asked questions is available at: http://wiki.panotools.org/Hugin_FAQ To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/hugin-ptx
