Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hugin_lensdb.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
12 /* This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This software is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public
23  * License along with this software. If not, see
24  * <http://www.gnu.org/licenses/>.
25  *
26  */
27 
28 #include <iostream>
29 #include <string>
30 #include <fstream>
31 #include "hugin_config.h"
32 #include <filesystem>
33 #include <getopt.h>
34 #include <panodata/Panorama.h>
35 #include <hugin_utils/stl_utils.h>
36 #include <lensdb/LensDB.h>
39 
40 typedef std::vector<std::filesystem::path> pathVec;
41 
42 
43 template <class iteratorType>
44 bool iterateFileSystem(std::string src, pathVec& projectFiles)
45 {
46  try
47  {
48  for(iteratorType it(src); it != iteratorType(); it++)
49  {
50  std::string ext=hugin_utils::toupper(it->path().extension().string());
51  if(ext==".PTO")
52  {
53  projectFiles.push_back(*it);
54  };
55  }
56  }
57  catch(std::filesystem::filesystem_error& e)
58  {
59  std::cout << e.what() << std::endl;
60  return false;
61  }
62  return true;
63 };
64 
65 void FindPTOFiles(pathVec& projectFiles, std::string src, bool recursive)
66 {
67  if(recursive)
68  {
69  iterateFileSystem<std::filesystem::recursive_directory_iterator>(src, projectFiles);
70  }
71  else
72  {
73  iterateFileSystem<std::filesystem::directory_iterator>(src, projectFiles);
74  };
75 };
76 
77 bool CheckProjectFile(const std::filesystem::path filename)
78 {
79  // open project file
81  const std::string input = filename.string();
82  if (!pano.ReadPTOFile(input, hugin_utils::getPathPrefix(input)))
83  {
84  return 1;
85  };
86  if (pano.getNrOfImages() == 0)
87  {
88  return false;
89  };
90  std::cout << "Checking " << filename.string() << "..." << std::endl;
92  if (lenses.getLenses().getNumberOfParts()==1)
93  {
94  // read the EXIF data
95  for (size_t i = 0; i < pano.getNrOfImages(); ++i)
96  {
98  if (!img.readEXIF())
99  {
100  std::cout << " Ignored (File missing or missing metadata)" << std::endl;
101  return false;
102  }
103  pano.setSrcImage(i, img);
104  };
105  // update cp errors
107  // now save in database
109  {
110  std::cout << " Saved." << std::endl;
111  return true;
112  }
113  else
114  {
115  std::cout << " Ignored." << std::endl;
116  return false;
117  }
118  };
119  std::cout << " Ignored (More than one lens)." << std::endl;
120  return false;
121 };
122 
123 static void usage(const char* name)
124 {
125  std::cout << name << ": tool for lens database maintenance" << std::endl
126  << name << " version " << hugin_utils::GetHuginVersion() << std::endl
127  << std::endl
128  << "Usage: hugin_lensdb [--recursive] --populate BASEPATH " << std::endl
129  << " Populate database with information from all pto files" << std::endl
130  << " in given BASEPATH" << std::endl
131  << " With --recursive switch all subfolders will also be" << std::endl
132  << " searched." << std::endl
133  << " hugin_lensdb --compress" << std::endl
134  << " Compresses the database by replacing single values" << std::endl
135  << " with averaged values." << std::endl
136  << " hugin_lensdb --remove-lens=LENS" << std::endl
137  << " Removes given lens from the database." << std::endl
138  << " hugin_lensdb --remove-camera=MAKER|MODEL" << std::endl
139  << " Removes given camera from the database." << std::endl
140  << " hugin_lensdb --export-database=FILENAME" << std::endl
141  << " Export data from database to external file." << std::endl
142  << " hugin_lensdb --import-from-file=FILENAME" << std::endl
143  << " Import data from external file." << std::endl
144  << std::endl;
145 };
146 
147 int main(int argc, char* argv[])
148 {
149  // parse arguments
150  const char* optstring = "crph";
151  enum
152  {
153  REMOVE_LENS=1000,
154  REMOVE_CAM=1001,
155  EXPORT_DB=1002,
156  IMPORT_DB=1003,
157  };
158 
159  static struct option longOptions[] =
160  {
161  { "compress", no_argument, NULL, 'c' },
162  { "recursive", no_argument, NULL, 'r' },
163  { "populate", required_argument, NULL, 'p' },
164  { "remove-lens", required_argument, NULL, REMOVE_LENS },
165  { "remove-camera", required_argument, NULL, REMOVE_CAM },
166  { "export-database", required_argument, NULL, EXPORT_DB },
167  { "import-from-file", required_argument, NULL, IMPORT_DB },
168  { "help", no_argument, NULL, 'h' },
169  0
170  };
171 
172  bool recursive=false;
173  bool populate = false;
174  bool compress = false;
175  std::string basepath;
176  std::string lensToRemove;
177  std::string camToRemove;
178  std::string exportDatabase;
179  std::string importDatabase;
180  int c;
181  while ((c = getopt_long (argc, argv, optstring, longOptions,nullptr)) != -1)
182  {
183  switch (c)
184  {
185  case 'h':
186  usage(hugin_utils::stripPath(argv[0]).c_str());
187  return 0;
188  case 'c':
189  compress=true;
190  break;
191  case 'r':
192  recursive=true;
193  break;
194  case 'p':
195  populate = true;
196  basepath = hugin_utils::StrTrim(std::string(optarg));
197  break;
198  case REMOVE_LENS:
199  lensToRemove = hugin_utils::StrTrim(std::string(optarg));
200  break;
201  case REMOVE_CAM:
202  camToRemove = hugin_utils::StrTrim(std::string(optarg));
203  break;
204  case EXPORT_DB:
205  exportDatabase = hugin_utils::StrTrim(std::string(optarg));
206  break;
207  case IMPORT_DB:
208  importDatabase = hugin_utils::StrTrim(std::string(optarg));
209  break;
210  case ':':
211  case '?':
212  // missing argument or invalid switch
213  return 1;
214  break;
215  default:
216  // this should not happen
217  abort();
218  }
219  }
220 
221  if (!exportDatabase.empty() && !importDatabase.empty())
222  {
223  std::cerr << hugin_utils::stripPath(argv[0]) << ": Export and import can not be done at the same time. " << std::endl;
224  return -1;
225  };
226 
227  if (!populate && !compress && lensToRemove.empty() && camToRemove.empty() && exportDatabase.empty() && importDatabase.empty())
228  {
229  std::cout << "Lensdatabase file: " << HuginBase::LensDB::LensDB::GetSingleton().GetDBFilename() << std::endl;
230  std::cout << "Nothing to do." << std::endl;
231  };
232 
233  if (populate)
234  {
235  std::filesystem::path p(basepath);
236  if (std::filesystem::exists(p))
237  {
238  p = std::filesystem::absolute(p);
239  if (std::filesystem::is_directory(p))
240  {
241  pathVec projectFiles;
242  FindPTOFiles(projectFiles, p.string(), recursive);
243  if (projectFiles.empty())
244  {
245  std::cerr << "ERROR: No project files found in given directory " << p.string() << std::endl;
246  return 1;
247  };
248  for (pathVec::const_iterator it = projectFiles.begin(); it != projectFiles.end(); ++it)
249  {
250  CheckProjectFile(*it);
251  };
252  }
253  else
254  {
255  std::cerr << "ERROR: " << basepath << " is not a directory." << std::endl;
256  return 1;
257  };
258  }
259  else
260  {
261  std::cerr << "ERROR: Path " << basepath << " does not exists." << std::endl;
262  return 1;
263  }
264  };
265 
266  if (compress)
267  {
268  std::cout << "Compressing database..." << std::endl;
269  if(HuginBase::LensDB::LensDB::GetSingleton().CleanUpDatabase())
270  {
271  std::cout << "Successful." << std::endl;
272  }
273  else
274  {
275  std::cout << "FAILED." << std::endl;
276  }
277  };
278  // remove lens
279  if (!lensToRemove.empty())
280  {
281  std::cout << "Removing lens \"" << lensToRemove << "\"..." << std::endl;
283  {
284  std::cout << "Successful." << std::endl;
285  }
286  else
287  {
288  std::cout << "FAILED." << std::endl;
289  }
290  };
291  // remove camera
292  if (!camToRemove.empty())
293  {
294  std::vector<std::string> input = hugin_utils::SplitString(camToRemove, "|");
295  if (input.size() == 2)
296  {
297  std::cout << "Removing camera \"" << input[1] << "\" (Maker: \"" << input[0] << "\")..." << std::endl;
298  if (HuginBase::LensDB::LensDB::GetSingleton().RemoveCamera(input[0], input[1]))
299  {
300  std::cout << "Successful." << std::endl;
301  }
302  else
303  {
304  std::cout << "FAILED." << std::endl;
305  }
306  }
307  else
308  {
309  std::cout << "\"" << camToRemove << "\" is not a valid string for the camera." << std::endl
310  << " Use syntax MAKER|MODEL (separate camera maker and model by |)" << std::endl;
311  };
312  };
313  // export database
314  if (!exportDatabase.empty())
315  {
316  std::cout << "Exporting database to \"" << exportDatabase << "\"..." << std::endl;
318  {
319  std::cout << "Successful." << std::endl;
320  }
321  else
322  {
323  std::cout << "FAILED." << std::endl;
324  };
325  };
326  // import database
327  if (!importDatabase.empty())
328  {
329  std::cout << "Importing data from \"" << importDatabase << "\"..." << std::endl;
331  {
332  std::cout << "Successful." << std::endl;
333  }
334  else
335  {
336  std::cout << "FAILED." << std::endl;
337  };
338  };
340  return 0;
341 }
std::string StrTrim(const std::string &str)
remove trailing and leading white spaces and tabs
Definition: utils.cpp:208
static LensDB & GetSingleton()
returns the static LensDB instance
Definition: LensDB.cpp:2001
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
Definition: Panorama.cpp:1620
Somewhere to specify what variables belong to what.
bool SaveLensDataFromPano(const HuginBase::Panorama &pano)
routine for automatically saving information from pano into database
Definition: LensDB.cpp:2553
std::vector< std::filesystem::path > pathVec
bool RemoveLens(const std::string &lensname)
remove all database entry which refers to given lens
Definition: LensDB.cpp:2517
std::string toupper(const std::string &s)
Definition: stl_utils.h:59
static void Clean()
cleanup the static LensDB instance, must be called at the end of the program
Definition: LensDB.cpp:2010
std::string GetDBFilename() const
returns the filename of the lens database
Definition: LensDB.cpp:2019
bool ExportToFile(const std::string &filename)
export database to file
Definition: LensDB.cpp:2535
class to access Hugins camera and lens database
void calcCtrlPointErrors(PanoramaData &pano)
Update the Ctrl Point errors without optimizing.
Model for a panorama.
Definition: Panorama.h:152
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
Definition: utils.cpp:184
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
bool ReadPTOFile(const std::string &filename, const std::string &prefix="")
read pto file from the given filename into Panorama object it does some checks on the file and issues...
Definition: Panorama.cpp:2023
ImageVariableGroup & getLenses()
Get the ImageVariableGroup representing the group of lens variables.
bool iterateFileSystem(std::string src, pathVec &projectFiles)
Utility calls into PanoTools using CPP interface.
bool ImportFromFile(const std::string &filename)
import data from external file
Definition: LensDB.cpp:2544
void FindPTOFiles(pathVec &projectFiles, std::string src, bool recursive)
static void usage()
Definition: Main.cpp:32
bool readEXIF()
try to fill out information about the image, by examining the exif data
std::string GetHuginVersion()
return a string with version numbers
Definition: utils.cpp:907
void setSrcImage(unsigned int nr, const SrcPanoImage &img)
set input image parameters
std::vector< std::string > SplitString(const std::string &s, const std::string &sep)
split string s at given sep, returns vector of strings
Definition: utils.cpp:294
bool RemoveCamera(const std::string &maker, const std::string &model)
remove all database entry which refers to given camera
Definition: LensDB.cpp:2526
std::size_t getNumberOfParts() const
get the number of parts.
All variables of a source image.
Definition: SrcPanoImage.h:194
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
Definition: utils.cpp:160
bool CheckProjectFile(const std::filesystem::path filename)
int main(int argc, char *argv[])
Definition: Main.cpp:167