hugin_lensdb.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00012 /*  This program is free software; you can redistribute it and/or
00013  *  modify it under the terms of the GNU General Public
00014  *  License as published by the Free Software Foundation; either
00015  *  version 2 of the License, or (at your option) any later version.
00016  *
00017  *  This software is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  *  General Public License for more details.
00021  *
00022  *  You should have received a copy of the GNU General Public
00023  *  License along with this software. If not, see
00024  *  <http://www.gnu.org/licenses/>.
00025  *
00026  */
00027 
00028 #include <iostream>
00029 #include <string>
00030 #include <fstream>
00031 #include "hugin_config.h"
00032 #include <hugin_utils/filesystem.h>
00033 #include <getopt.h>
00034 #include <panodata/Panorama.h>
00035 #include <hugin_utils/stl_utils.h>
00036 #include <lensdb/LensDB.h>
00037 #include <panodata/StandardImageVariableGroups.h>
00038 #include <hugin_base/panotools/PanoToolsUtils.h>
00039 
00040 typedef std::vector<fs::path> pathVec;
00041 
00042 
00043 template <class iteratorType>
00044 bool iterateFileSystem(std::string src, pathVec& projectFiles)
00045 {
00046     try
00047     {
00048         for(iteratorType it(src); it != iteratorType(); it++)
00049         {
00050             std::string ext=hugin_utils::toupper(it->path().extension().string());
00051             if(ext==".PTO")
00052             {
00053                 projectFiles.push_back(*it);
00054             };
00055         }
00056     }
00057     catch(fs::filesystem_error& e)
00058     {
00059         std::cout << e.what() << std::endl;
00060         return false;
00061     }
00062     return true;
00063 };
00064 
00065 void FindPTOFiles(pathVec& projectFiles, std::string src, bool recursive)
00066 {
00067     if(recursive)
00068     {
00069         iterateFileSystem<fs::recursive_directory_iterator>(src, projectFiles);
00070     }
00071     else
00072     {
00073         iterateFileSystem<fs::directory_iterator>(src, projectFiles);
00074     };
00075 };
00076 
00077 bool CheckProjectFile(const fs::path filename)
00078 {
00079     // open project file
00080     HuginBase::Panorama pano;
00081     std::string input = filename.string();
00082     std::ifstream prjfile(input.c_str());
00083     if (!prjfile.good())
00084     {
00085         std::cerr << "ERROR: Could not open script: " << filename.string() << endl;
00086         return false;
00087     }
00088     std::string inputPathPrefix = hugin_utils::getPathPrefix(input);
00089     pano.setFilePrefix(inputPathPrefix);
00090     AppBase::DocumentData::ReadWriteError err = pano.readData(prjfile);
00091     if (err != AppBase::DocumentData::SUCCESSFUL)
00092     {
00093         std::cerr << "ERROR: error while parsing panos tool script: " << input << std::endl
00094                   << "DocumentData::ReadWriteError code: " << err << std::endl;
00095         return false;
00096     };
00097     prjfile.close();
00098     if (pano.getNrOfImages() == 0)
00099     {
00100         return false;
00101     };
00102     std::cout << "Checking " << filename.string() << "..." << std::endl;
00103     HuginBase::StandardImageVariableGroups lenses(pano);
00104     if (lenses.getLenses().getNumberOfParts()==1)
00105     {
00106         // read the EXIF data
00107         for (size_t i = 0; i < pano.getNrOfImages(); ++i)
00108         {
00109             HuginBase::SrcPanoImage img = pano.getSrcImage(i);
00110             if (!img.readEXIF())
00111             {
00112                 std::cout << " Ignored (File missing or missing metadata)" << std::endl;
00113                 return false;
00114             }
00115             pano.setSrcImage(i, img);
00116         };
00117         // update cp errors
00118         HuginBase::PTools::calcCtrlPointErrors(pano);
00119         // now save in database
00120         if (HuginBase::LensDB::SaveLensDataFromPano(pano))
00121         {
00122             std::cout << " Saved." << std::endl;
00123             return true;
00124         }
00125         else
00126         {
00127             std::cout << " Ignored." << std::endl;
00128             return false;
00129         }
00130     };
00131     std::cout << " Ignored (More than one lens)." << std::endl;
00132     return false;
00133 };
00134 
00135 static void usage(const char* name)
00136 {
00137     std::cout << name << ": tool for lens database maintenance" << std::endl
00138               << name << " version " << hugin_utils::GetHuginVersion() << std::endl
00139               << std::endl
00140               << "Usage:  hugin_lensdb [--recursive] --populate BASEPATH " << std::endl
00141               << "             Populate database with information from all pto files" << std::endl
00142               << "             in given BASEPATH" << std::endl
00143               << "             With --recursive switch all subfolders will also be" << std::endl
00144               << "             searched." << std::endl
00145               << "        hugin_lensdb --compress" << std::endl
00146               << "             Compresses the database by replacing single values" << std::endl
00147               << "             with averaged values." << std::endl
00148               << "        hugin_lensdb --remove-lens=LENS" << std::endl
00149               << "             Removes given lens from the database." << std::endl
00150               << "        hugin_lensdb --remove-camera=MAKER|MODEL" << std::endl
00151               << "             Removes given camera from the database." << std::endl
00152               << "        hugin_lensdb --export-database=FILENAME" << std::endl
00153               << "             Export data from database to external file." << std::endl
00154               << "        hugin_lensdb --import-from-file=FILENAME" << std::endl
00155               << "             Import data from external file." << std::endl
00156               << std::endl;
00157 };
00158 
00159 int main(int argc, char* argv[])
00160 {
00161     // parse arguments
00162     const char* optstring = "crph";
00163     enum
00164     {
00165         REMOVE_LENS=1000,
00166         REMOVE_CAM=1001,
00167         EXPORT_DB=1002,
00168         IMPORT_DB=1003,
00169     };
00170 
00171     static struct option longOptions[] =
00172     {
00173         { "compress", no_argument, NULL, 'c' },
00174         { "recursive", no_argument, NULL, 'r' },
00175         { "populate", required_argument, NULL, 'p' },
00176         { "remove-lens", required_argument, NULL, REMOVE_LENS },
00177         { "remove-camera", required_argument, NULL, REMOVE_CAM },
00178         { "export-database", required_argument, NULL, EXPORT_DB },
00179         { "import-from-file", required_argument, NULL, IMPORT_DB },
00180         { "help", no_argument, NULL, 'h' },
00181         0
00182     };
00183 
00184     bool recursive=false;
00185     bool populate = false;
00186     bool compress = false;
00187     std::string basepath;
00188     std::string lensToRemove;
00189     std::string camToRemove;
00190     std::string exportDatabase;
00191     std::string importDatabase;
00192     int c;
00193     while ((c = getopt_long (argc, argv, optstring, longOptions,nullptr)) != -1)
00194     {
00195         switch (c)
00196         {
00197             case 'h':
00198                 usage(hugin_utils::stripPath(argv[0]).c_str());
00199                 return 0;
00200             case 'c':
00201                 compress=true;
00202                 break;
00203             case 'r':
00204                 recursive=true;
00205                 break;
00206             case 'p':
00207                 populate = true;
00208                 basepath = hugin_utils::StrTrim(std::string(optarg));
00209                 break;
00210             case REMOVE_LENS:
00211                 lensToRemove = hugin_utils::StrTrim(std::string(optarg));
00212                 break;
00213             case REMOVE_CAM:
00214                 camToRemove = hugin_utils::StrTrim(std::string(optarg));
00215                 break;
00216             case EXPORT_DB:
00217                 exportDatabase = hugin_utils::StrTrim(std::string(optarg));
00218                 break;
00219             case IMPORT_DB:
00220                 importDatabase = hugin_utils::StrTrim(std::string(optarg));
00221                 break;
00222             case ':':
00223             case '?':
00224                 // missing argument or invalid switch
00225                 return 1;
00226                 break;
00227             default:
00228                 // this should not happen
00229                 abort();
00230         }
00231     }
00232 
00233     if (!exportDatabase.empty() && !importDatabase.empty())
00234     {
00235         std::cerr << hugin_utils::stripPath(argv[0]) << ": Export and import can not be done at the same time. " << std::endl;
00236         return -1;
00237     };
00238 
00239     if (!populate && !compress && lensToRemove.empty() && camToRemove.empty() && exportDatabase.empty() && importDatabase.empty())
00240     {
00241         std::cout << "Lensdatabase file: " << HuginBase::LensDB::LensDB::GetSingleton().GetDBFilename() << std::endl;
00242         std::cout << "Nothing to do." << std::endl;
00243     };
00244 
00245     if (populate)
00246     {
00247         fs::path p(basepath);
00248         if (fs::exists(p))
00249         {
00250             p = fs::absolute(p);
00251             if (fs::is_directory(p))
00252             {
00253                 pathVec projectFiles;
00254                 FindPTOFiles(projectFiles, p.string(), recursive);
00255                 if (projectFiles.empty())
00256                 {
00257                     std::cerr << "ERROR: No project files found in given directory " << p.string() << std::endl;
00258                     return 1;
00259                 };
00260                 for (pathVec::const_iterator it = projectFiles.begin(); it != projectFiles.end(); ++it)
00261                 {
00262                     CheckProjectFile(*it);
00263                 };
00264             }
00265             else
00266             {
00267                 std::cerr << "ERROR: " << basepath << " is not a directory." << std::endl;
00268                 return 1;
00269             };
00270         }
00271         else
00272         {
00273             std::cerr << "ERROR: Path " << basepath << " does not exists." << std::endl;
00274             return 1;
00275         }
00276     };
00277 
00278     if (compress)
00279     {
00280         std::cout << "Compressing database..." << std::endl;
00281         if(HuginBase::LensDB::LensDB::GetSingleton().CleanUpDatabase())
00282         {
00283             std::cout << "Successful." << std::endl;
00284         }
00285         else
00286         {
00287             std::cout << "FAILED." << std::endl;
00288         }
00289     };
00290     // remove lens
00291     if (!lensToRemove.empty())
00292     {
00293         std::cout << "Removing lens \"" << lensToRemove << "\"..." << std::endl;
00294         if (HuginBase::LensDB::LensDB::GetSingleton().RemoveLens(lensToRemove))
00295         {
00296             std::cout << "Successful." << std::endl;
00297         }
00298         else
00299         {
00300             std::cout << "FAILED." << std::endl;
00301         }
00302     };
00303     // remove camera
00304     if (!camToRemove.empty())
00305     {
00306         std::vector<std::string> input = hugin_utils::SplitString(camToRemove, "|");
00307         if (input.size() == 2)
00308         {
00309             std::cout << "Removing camera \"" << input[1] << "\" (Maker: \"" << input[0] << "\")..." << std::endl;
00310             if (HuginBase::LensDB::LensDB::GetSingleton().RemoveCamera(input[0], input[1]))
00311             {
00312                 std::cout << "Successful." << std::endl;
00313             }
00314             else
00315             {
00316                 std::cout << "FAILED." << std::endl;
00317             }
00318         }
00319         else
00320         {
00321             std::cout << "\"" << camToRemove << "\" is not a valid string for the camera." << std::endl
00322                 << "    Use syntax MAKER|MODEL (separate camera maker and model by |)" << std::endl;
00323         };
00324     };
00325     // export database
00326     if (!exportDatabase.empty())
00327     {
00328         std::cout << "Exporting database to \"" << exportDatabase << "\"..." << std::endl;
00329         if (HuginBase::LensDB::LensDB::GetSingleton().ExportToFile(exportDatabase))
00330         {
00331             std::cout << "Successful." << std::endl;
00332         }
00333         else
00334         {
00335             std::cout << "FAILED." << std::endl;
00336         };
00337     };
00338     // import database
00339     if (!importDatabase.empty())
00340     {
00341         std::cout << "Importing data from \"" << importDatabase << "\"..." << std::endl;
00342         if (HuginBase::LensDB::LensDB::GetSingleton().ImportFromFile(importDatabase))
00343         {
00344             std::cout << "Successful." << std::endl;
00345         }
00346         else
00347         {
00348             std::cout << "FAILED." << std::endl;
00349         };
00350     };
00351     HuginBase::LensDB::LensDB::Clean();
00352     return 0;
00353 }

Generated on 25 Apr 2018 for Hugintrunk by  doxygen 1.4.7