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

Generated on Thu Oct 2 01:25:41 2014 for Hugintrunk by  doxygen 1.3.9.1