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

Generated on 4 Aug 2015 for Hugintrunk by  doxygen 1.4.7