pano_trafo.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00013 /*  This program is free software; you can redistribute it and/or
00014  *  modify it under the terms of the GNU General Public
00015  *  License as published by the Free Software Foundation; either
00016  *  version 2 of the License, or (at your option) any later version.
00017  *
00018  *  This software is distributed in the hope that it will be useful,
00019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021  *  General Public License for more details.
00022  *
00023  *  You should have received a copy of the GNU General Public
00024  *  License along with this software. If not, see
00025  *  <http://www.gnu.org/licenses/>.
00026  *
00027  *  KFJ 2010-12-28 I've thrown out C fprintf style IO, now
00028  *  it's all done with streams, removing the problem I had with
00029  *  unflushed output.
00030  *  I've also added a new mode where no image number is passed on
00031  *  the command line and instead the image number is passed with
00032  *  each coordinate pair.
00033  *
00034  */
00035 
00036 #include <fstream>
00037 #include <sstream>
00038 #include <getopt.h>
00039 
00040 #include <panodata/Panorama.h>
00041 #include <panotools/PanoToolsInterface.h>
00042 
00043 static void usage(const char* name)
00044 {
00045     std::cout << name << ": transform pixel coordinates" << std::endl
00046          << "pano_trafo version " << hugin_utils::GetHuginVersion() << std::endl
00047          << std::endl
00048          << "Usage:  " << name << " input.pto [ image_nr ]" << std::endl
00049          << std::endl
00050          << "pano_trafo reads pixel coordinates from standard input and" << std::endl
00051          << "prints the transformed coordinates to standard output." << std::endl
00052          << "If you pass an image number on the command line," << std::endl
00053          << "it reads pairs of coordinates and transforms them." << std::endl
00054          << "If you don't pass an image number, it will read triplets" << std::endl
00055          << "of the form <image number> <x coordinate> <y coordinate>" << std::endl
00056          << "and output the transformed coordinates." << std::endl
00057          << std::endl
00058          << "     -r|--recursive  Transform from panorama to image coordinates" << std::endl
00059          << "     -h|--help       Shows help" << std::endl
00060          << std::endl;
00061 }
00062 
00063 // alternative behaviour if no image number is passed.
00064 // main() with the original behaviour follows below.
00065 
00066 void work_on_triplets(const HuginBase::Panorama& pano, bool reverse)
00067 {
00068     // pano tools interface
00069     int images = pano.getNrOfImages() ;
00070     int image = 0 ;
00071 
00072     // instead of just one transform, create one for each image
00073 
00074     HuginBase::PTools::Transform* trafo_set =
00075         new HuginBase::PTools::Transform [ images ] ;
00076 
00077     if ( ! trafo_set )
00078     {
00079         std::cerr << "not enough memory" ; // very unlikely...
00080         exit ( -1 ) ;
00081     }
00082 
00083     for ( image = 0 ; image < images ; image++ )
00084     {
00085         if (reverse)
00086         {
00087             trafo_set[image].createTransform(pano.getSrcImage(image), pano.getOptions());
00088         }
00089         else
00090         {
00091             trafo_set[image].createInvTransform(pano.getSrcImage(image), pano.getOptions());
00092         }
00093     }
00094 
00095     // now we can process data triplets from cin
00096 
00097     double xin , yin , xout , yout ;
00098 
00099     while ( std::cin >> image >> xin >> yin )
00100     {
00101         if ( image < 0 || image >= images )
00102         {
00103             std::cerr << "no image " << image << " in pano" << std::endl ;
00104             exit ( 1 ) ; // we don't want an index out of range
00105         }
00106         trafo_set[image].transformImgCoord(xout, yout, xin, yin);
00107         std::cout << xout << " " << yout << std::endl ;
00108     }
00109     delete [] trafo_set;
00110 }
00111 
00112 int main(int argc, char* argv[])
00113 {
00114     // parse arguments
00115     const char* optstring = "hr";
00116     static struct option longOptions[] =
00117     {
00118         { "recursive", no_argument, NULL, 'r' },
00119         { "help", no_argument, NULL, 'h' },
00120         0
00121     };
00122     int c;
00123 
00124     bool reverse = false;
00125     while ((c = getopt_long(argc, argv, optstring, longOptions, nullptr)) != -1)
00126     {
00127         switch (c)
00128         {
00129             case 'h':
00130                 usage(hugin_utils::stripPath(argv[0]).c_str());
00131                 return 0;
00132             case 'r':
00133                 reverse = true;
00134                 break;
00135             case ':':
00136             case '?':
00137                 // missing argument or invalid switch
00138                 return 1;
00139                 break;
00140             default:
00141                 // this should not happen
00142                 abort();
00143         }
00144     }
00145 
00146     if (argc - optind < 1 || argc - optind > 2)
00147     {
00148         std::cerr << hugin_utils::stripPath(argv[0]) << ": Expected one project file and optional one image number" << std::endl;
00149         return 1;
00150     }
00151 
00152     std::string input=argv[optind];
00153 
00154     HuginBase::Panorama pano;
00155     std::ifstream prjfile(input.c_str());
00156     if (!prjfile.good())
00157     {
00158         std::cerr << "could not open script : " << input << std::endl;
00159         return 1;
00160     }
00161     pano.setFilePrefix(hugin_utils::getPathPrefix(input));
00162     AppBase::DocumentData::ReadWriteError err = pano.readData(prjfile);
00163     if (err != AppBase::DocumentData::SUCCESSFUL)
00164     {
00165         std::cerr << "error while parsing panos tool script: " << input << std::endl;
00166         std::cerr << "AppBase::DocumentData::ReadWriteError code: " << err << std::endl;
00167         return 1;
00168     }
00169 
00170     // set up output format
00171     std::cout.setf ( std::ios::fixed ) ;
00172     std::cout.precision ( 6 ) ; // should be ample
00173 
00174     if ( argc - optind == 1 )
00175     {
00176         // no image number was passed. This triggers the new
00177         // behaviour to accept triplets on cin
00178         work_on_triplets ( pano , reverse ) ;
00179         return 0;
00180     }
00181 
00182     // an image number was passed, so proceed
00183     // as in the original version
00184 
00185     int imageNumber = atoi(argv[optind+1]);
00186     if (imageNumber >= pano.getNrOfImages())
00187     {
00188         std::cerr << "Not enough images in panorama" << std::endl;
00189         return 1;
00190     }
00191 
00192     // pano tools interface
00193     HuginBase::PTools::Transform trafo;
00194     if (reverse)
00195     {
00196         trafo.createTransform(pano.getSrcImage(imageNumber), pano.getOptions());
00197     }
00198     else
00199     {
00200         trafo.createInvTransform(pano.getSrcImage(imageNumber), pano.getOptions());
00201     }
00202 
00203     double xin , yin , xout , yout ;
00204 
00205     // here's where the old-style IO was, now it's all streams.
00206     // It's also format-free input, so newlines don't matter
00207     while ( std::cin >> xin >> yin )
00208     {
00209         trafo.transformImgCoord(xout, yout, xin, yin);
00210         std::cout << xout << " " << yout << std::endl ;
00211     }
00212 }

Generated on 2 Dec 2016 for Hugintrunk by  doxygen 1.4.7