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 #ifdef _WIN32
00039 #include <getopt.h>
00040 #else
00041 #include <unistd.h>
00042 #endif
00043 
00044 #include <panodata/Panorama.h>
00045 #include <panotools/PanoToolsInterface.h>
00046 
00047 static void usage(const char* name)
00048 {
00049     std::cout << name << ": transform pixel coordinates" << std::endl
00050          << "pano_trafo version " << hugin_utils::GetHuginVersion() << std::endl
00051          << std::endl
00052          << "Usage:  " << name << " input.pto [ image_nr ]" << std::endl
00053          << std::endl
00054          << "pano_trafo reads pixel coordinates from standard input and" << std::endl
00055          << "prints the transformed coordinates to standard output." << std::endl
00056          << "If you pass an image number on the command line," << std::endl
00057          << "it reads pairs of coordinates and transforms them." << std::endl
00058          << "If you don't pass an image number, it will read triplets" << std::endl
00059          << "of the form <image number> <x coordinate> <y coordinate>" << std::endl
00060          << "and output the transformed coordinates." << std::endl
00061          << std::endl
00062          << "     -r       Transform from panorama to image coordinates" << std::endl
00063          << "     -h       shows help" << std::endl
00064          << std::endl;
00065 }
00066 
00067 // alternative behaviour if no image number is passed.
00068 // main() with the original behaviour follows below.
00069 
00070 void work_on_triplets(const HuginBase::Panorama& pano, bool reverse)
00071 {
00072     // pano tools interface
00073     int images = pano.getNrOfImages() ;
00074     int image = 0 ;
00075 
00076     // instead of just one transform, create one for each image
00077 
00078     HuginBase::PTools::Transform* trafo_set =
00079         new HuginBase::PTools::Transform [ images ] ;
00080 
00081     if ( ! trafo_set )
00082     {
00083         std::cerr << "not enough memory" ; // very unlikely...
00084         exit ( -1 ) ;
00085     }
00086 
00087     for ( image = 0 ; image < images ; image++ )
00088     {
00089         if (reverse)
00090         {
00091             trafo_set[image].createTransform(pano.getSrcImage(image), pano.getOptions());
00092         }
00093         else
00094         {
00095             trafo_set[image].createInvTransform(pano.getSrcImage(image), pano.getOptions());
00096         }
00097     }
00098 
00099     // now we can process data triplets from cin
00100 
00101     double xin , yin , xout , yout ;
00102 
00103     while ( std::cin >> image >> xin >> yin )
00104     {
00105         if ( image < 0 || image >= images )
00106         {
00107             std::cerr << "no image " << image << " in pano" << std::endl ;
00108             exit ( 1 ) ; // we don't want an index out of range
00109         }
00110         trafo_set[image].transformImgCoord(xout, yout, xin, yin);
00111         std::cout << xout << " " << yout << std::endl ;
00112     }
00113     delete [] trafo_set;
00114 }
00115 
00116 int main(int argc, char* argv[])
00117 {
00118     // parse arguments
00119     const char* optstring = "hr";
00120 
00121     int c;
00122     bool reverse = false;
00123     while ((c = getopt (argc, argv, optstring)) != -1)
00124     {
00125         switch (c)
00126         {
00127             case 'h':
00128                 usage(hugin_utils::stripPath(argv[0]).c_str());
00129                 return 0;
00130             case 'r':
00131                 reverse = true;
00132                 break;
00133             case '?':
00134                 break;
00135             default:
00136                 abort ();
00137         }
00138     }
00139 
00140     if (argc - optind < 1 || argc - optind > 2)
00141     {
00142         usage(hugin_utils::stripPath(argv[0]).c_str());
00143         return 1;
00144     }
00145 
00146     std::string input=argv[optind];
00147 
00148     HuginBase::Panorama pano;
00149     std::ifstream prjfile(input.c_str());
00150     if (!prjfile.good())
00151     {
00152         std::cerr << "could not open script : " << input << std::endl;
00153         return 1;
00154     }
00155     pano.setFilePrefix(hugin_utils::getPathPrefix(input));
00156     AppBase::DocumentData::ReadWriteError err = pano.readData(prjfile);
00157     if (err != AppBase::DocumentData::SUCCESSFUL)
00158     {
00159         std::cerr << "error while parsing panos tool script: " << input << std::endl;
00160         std::cerr << "AppBase::DocumentData::ReadWriteError code: " << err << std::endl;
00161         return 1;
00162     }
00163 
00164     // set up output format
00165     std::cout.setf ( std::ios::fixed ) ;
00166     std::cout.precision ( 6 ) ; // should be ample
00167 
00168     if ( argc - optind == 1 )
00169     {
00170         // no image number was passed. This triggers the new
00171         // behaviour to accept triplets on cin
00172         work_on_triplets ( pano , reverse ) ;
00173         return 0;
00174     }
00175 
00176     // an image number was passed, so proceed
00177     // as in the original version
00178 
00179     int imageNumber = atoi(argv[optind+1]);
00180     if (imageNumber >= pano.getNrOfImages())
00181     {
00182         std::cerr << "Not enough images in panorama" << std::endl;
00183         return 1;
00184     }
00185 
00186     // pano tools interface
00187     HuginBase::PTools::Transform trafo;
00188     if (reverse)
00189     {
00190         trafo.createTransform(pano.getSrcImage(imageNumber), pano.getOptions());
00191     }
00192     else
00193     {
00194         trafo.createInvTransform(pano.getSrcImage(imageNumber), pano.getOptions());
00195     }
00196 
00197     double xin , yin , xout , yout ;
00198 
00199     // here's where the old-style IO was, now it's all streams.
00200     // It's also format-free input, so newlines don't matter
00201     while ( std::cin >> xin >> yin )
00202     {
00203         trafo.transformImgCoord(xout, yout, xin, yin);
00204         std::cout << xout << " " << yout << std::endl ;
00205     }
00206 }

Generated on 26 Jun 2016 for Hugintrunk by  doxygen 1.4.7