Hugin trunk 0.1
Loading...
Searching...
No Matches
LensDB.cpp
Go to the documentation of this file.
1
8/* This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This software is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this software. If not, see
20 * <http://www.gnu.org/licenses/>.
21 *
22 */
23
24#include "LensDB.h"
25#include <iostream>
26#include <sstream>
27#include <fstream>
29#include <hugin_utils/utils.h>
30#include <sqlite3.h>
33
34namespace HuginBase
35{
36
37namespace LensDB
38{
39
41
42// internal class to handle all transfer from/to database
43// to prevent including of sqlite3.h into hugin_base header
45{
46public:
47 //struct for retrieving lens data
48 struct HFOVData
49 {
51 double HFOV;
52 };
53 struct CropData
54 {
57 };
59 {
61 double a, b, c;
62 };
64 {
66 double aperture;
67 double distance;
68 double Vb, Vc, Vd;
69 };
70 struct TCAdata
71 {
73 double ra, rb, rc, rd;
74 double ba, bb, bc, bd;
75 };
76 //constructor, open database
77 explicit Database(const std::string& filename) : m_filename(filename), m_runningTransaction(false)
78 {
80 int error = sqlite3_open(m_filename.c_str(), &m_db);
81 if (error)
82 {
83 std::cerr << "Can't open database: " << sqlite3_errmsg(m_db) << std::endl;
84 m_db = NULL;
85 m_filename = std::string();
86 };
87 if (newDB)
88 {
89 if (!CreateTables())
90 {
91 //something went wrong with the generation of the database structure
93 m_db = NULL;
94 m_filename = std::string();
95 };
96 }
97 else
98 {
99 // check version and update database when necessary
100 // not yet implemented
101 // if (GetDBVersion() < 2) UpdateDatabase();
102 };
103 };
104 // destructor, destroy database
106 {
107 if (m_db)
108 {
110 {
112 };
114 };
115 };
116 // create the tables for the database
118 {
119 const char* createDB = "PRAGMA user_version=1;"
120 "CREATE TABLE CameraCropTable (Maker TEXT, Model TEXT, Cropfactor REAL, PRIMARY KEY (Maker, Model));"
121 "CREATE TABLE LensProjectionTable (Lens TEXT PRIMARY KEY, Projection INTEGER);"
122 "CREATE TABLE LensHFOVTable (Lens TEXT, Focallength REAL, HFOV REAL, Weight INTEGER);"
123 "CREATE INDEX HFOV_IndexLens ON LensHFOVTable (Lens);"
124 "CREATE INDEX HFOV_IndexLens2 ON LensHFOVTable (Lens, Focallength);"
125 "CREATE TABLE LensCropTable (Lens TEXT, Focallength REAL, Width INTEGER, Height INTEGER, CropLeft INTEGER, CropRight INTEGER, CropTop INTEGER, CropBottom INTEGER, PRIMARY KEY (Lens, Focallength, Width, Height));"
126 "CREATE TABLE DistortionTable(Lens TEXT, Focallength REAL, a REAL, b REAL, c REAL, Weight INTEGER);"
127 "CREATE INDEX Dist_IndexLens ON DistortionTable (Lens);"
128 "CREATE INDEX Dist_IndexLensFocal ON DistortionTable (Lens, Focallength);"
129 "CREATE TABLE VignettingTable (Lens TEXT, Focallength REAL, Aperture REAL, Distance REAL, Vb REAL, Vc REAL, Vd REAL, Weight INTEGER);"
130 "CREATE INDEX Vig_IndexLens ON VignettingTable (Lens);"
131 "CREATE INDEX Vig_IndexLensFocal ON VignettingTable (Lens, Focallength);"
132 "CREATE INDEX Vig_IndexLensFocalApertureDistance ON VignettingTable (Lens, Focallength, Aperture, Distance);"
133 "CREATE TABLE TCATable (Lens TEXT, Focallength REAL, ra REAL, rb REAL, rc REAL, rd REAL, ba REAL, bb REAL, bc REAL, bd REAL, Weight INTEGER);"
134 "CREATE INDEX TCA_IndexLens ON TCATable (Lens);"
135 "CREATE INDEX TCA_IndexLensFocal ON TCATable (Lens, Focallength);"
136 "CREATE TABLE EMORTable (Maker TEXT, Model TEXT, ISO INTEGER, Ra REAL, Rb REAL, Rc REAL, Rd REAL, Re REAL, Weight INTEGER);"
137 "CREATE INDEX EMOR_Index_Cam ON EMORTable (Maker, Model);"
138 "CREATE INDEX EMOR_Index_CamISO ON EMORTable (Maker, Model, ISO);";
139 if (m_db == NULL)
140 {
141 return false;
142 };
144 {
145 return true;
146 }
147 else
148 {
149 std::cerr << "Could not create database structure." << std::endl;
150 return false;
151 };
152 };
153 // report the database version, implemented by PRAGMA user_version
154 // currently not used, for further extensions of the database structure
155 // @return db version, or -1 if db could not opened/initialized
156 int GetDBVersion() const
157 {
158 if (m_db == NULL)
159 {
160 return -1;
161 };
163 const char *tail;
164 int version = 0;
165 if (sqlite3_prepare_v2(m_db, "PRAGMA user_version;", -1, &statement, &tail) == SQLITE_OK)
166 {
168 {
170 };
171 };
173 return version;
174 };
175 // returns the filename of the database
176 std::string GetDBFilename() const
177 {
178 return m_filename;
179 };
180 // search for the crop factor of the given camera in the database
181 // returns true of camera was found, otherwise false
182 bool GetCropFactor(const std::string& maker, const std::string& model, double &cropFactor) const
183 {
184 cropFactor = 0;
185 if (m_db == NULL)
186 {
187 return false;
188 };
190 const char *tail;
191 if (sqlite3_prepare_v2(m_db, "SELECT Cropfactor FROM CameraCropTable WHERE Maker=?1 AND Model=?2;", -1, &statement, &tail) == SQLITE_OK)
192 {
193 sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
194 sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
196 {
197 cropFactor = sqlite3_column_double(statement, 0);
198 };
199 };
202 {
203 cropFactor = 0;
204 };
205 return cropFactor > 0.1;
206 };
207 // saves the crop factor for the given camera in the database
208 // returns true, if data were successful saved into db, false if errors occurred during saving
209 bool SaveCropFactor(const std::string& maker, const std::string& model, const double cropFactor)
210 {
211 if (m_db == NULL)
212 {
213 return false;
214 };
215 // do some range checking
217 {
218 return false;
219 };
221 const char *tail;
222 int returnValue = 0;
224 if (sqlite3_prepare_v2(m_db, "INSERT OR FAIL INTO CameraCropTable (Maker, Model, Cropfactor) VALUES(?1,?2,?3);", -1, &statement, &tail) == SQLITE_OK)
225 {
226 sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
227 sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
228 sqlite3_bind_double(statement, 3, cropFactor);
231 {
233 if (sqlite3_prepare_v2(m_db, "UPDATE CameraCropTable SET Cropfactor=?3 WHERE Maker=?1 AND Model=?2;", -1, &statement, &tail) == SQLITE_OK)
234 {
235 sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
236 sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
237 sqlite3_bind_double(statement, 3, cropFactor);
239 };
240 };
241 };
244 return returnValue == SQLITE_DONE;
245 };
246 // search for the projection of the given lens in the database
247 // returns true if lens information were was found, otherwise false
248 bool GetLensProjection(const std::string& lens, int &projection) const
249 {
250 projection = -1;
251 if (m_db == NULL)
252 {
253 return false;
254 };
256 const char *tail;
257 if (sqlite3_prepare_v2(m_db, "SELECT Projection FROM LensProjectionTable WHERE Lens=?1;", -1, &statement, &tail) == SQLITE_OK)
258 {
259 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
261 {
262 projection = sqlite3_column_int(statement, 0);
263 };
264 };
266 return projection != -1;
267 };
268 // saves the projection for the given lens in the database
269 // returns true, if data were successful saved into db, false if errors occurred during saving
270 bool SaveLensProjection(const std::string& lens, const int projection)
271 {
272 if (m_db == NULL)
273 {
274 return false;
275 };
277 const char *tail;
278 int returnValue = 0;
280 if (sqlite3_prepare_v2(m_db, "INSERT OR FAIL INTO LensProjectionTable (Lens, Projection) VALUES(?1,?2);", -1, &statement, &tail) == SQLITE_OK)
281 {
282 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
283 sqlite3_bind_int(statement, 2, projection);
286 {
288 if (sqlite3_prepare_v2(m_db, "UPDATE LensProjectionTable SET Projection=?2 WHERE Lens=?1;", -1, &statement, &tail) == SQLITE_OK)
289 {
290 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
291 sqlite3_bind_int(statement, 2, projection);
293 };
294 };
295 };
298 return returnValue == SQLITE_DONE;
299 };
300 // search for the HFOV for the given lens in the database
301 // returns true of data for lens was found, otherwise false
302 // returns 2 datasets with the values for the 2 focal lengths
303 bool GetHFOV(const std::string& lens, const double focallength, std::vector<HFOVData>& hfovData) const
304 {
305 hfovData.clear();
306 if (m_db == NULL)
307 {
308 return false;
309 };
311 const char *tail;
312 if (sqlite3_prepare_v2(m_db, "SELECT Focallength, SUM(HFOV*Weight)/SUM(Weight) FROM LensHFOVTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) ASC LIMIT 2;", -1, &statement, &tail) == SQLITE_OK)
313 {
314 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
315 sqlite3_bind_double(statement, 2, focallength);
317 {
321 hfovData.push_back(newhfovData);
322 };
323 };
325 return !hfovData.empty();
326 };
327 // saves the HFOV data in the database
328 // returns true, if data were successful saved into db, false if errors occurred during saving
329 bool SaveHFOV(const std::string& lens, const double focallength, const double HFOV, const int weight = 10)
330 {
331 if (m_db == NULL)
332 {
333 return false;
334 };
335 // range checking
336 if (HFOV < 0.1 || HFOV>360)
337 {
338 return false;
339 };
341 const char *tail;
342 int returnValue = 0;
343 if (sqlite3_prepare_v2(m_db, "INSERT INTO LensHFOVTable(Lens, Focallength, HFOV, Weight) VALUES(?1,?2,?3,?4);", -1, &statement, &tail) == SQLITE_OK)
344 {
345 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
346 sqlite3_bind_double(statement, 2, focallength);
348 sqlite3_bind_int(statement, 4, weight);
350 };
352 return returnValue == SQLITE_DONE;
353 };
354 // search for the crop of the given lens in the database
355 // returns true if lens information were was found, otherwise false
356 bool GetLensCrop(const std::string& lens, const double focal, const int width, const int height, std::vector<CropData> &cropData) const
357 {
358 cropData.clear();
359 if (m_db == NULL)
360 {
361 return false;
362 };
364 const char *tail;
365 if (sqlite3_prepare_v2(m_db, "SELECT Focallength, CropLeft, CropRight, CropTop, CropBottom FROM LensCropTable WHERE Lens=?1 AND Width=?2 AND Height=?3 ORDER BY ABS(Focallength-?4) ASC LIMIT 2;", -1, &statement, &tail) == SQLITE_OK)
366 {
367 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
368 sqlite3_bind_int(statement, 2, width);
369 sqlite3_bind_int(statement, 3, height);
372 {
379 cropData.push_back(newCropData);
380 };
381 };
383 return !cropData.empty();
384 };
385 // saves the crop for the given lens in the database
386 // returns true, if data were successful saved into db, false if errors occurred during saving
387 bool SaveLensCrop(const std::string& lens, const double focal, const int width, const int height, const int left, const int right, const int top, const int bottom)
388 {
389 if (m_db == NULL)
390 {
391 return false;
392 };
394 const char *tail;
395 int returnValue = 0;
397 if (sqlite3_prepare_v2(m_db, "INSERT OR FAIL INTO LensCropTable (Lens, Focallength, Width, Height, CropLeft, CropRight, CropTop, CropBottom) VALUES(?1,?2,?3,?4,?5,?6,?7,?8);", -1, &statement, &tail) == SQLITE_OK)
398 {
399 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
401 sqlite3_bind_int(statement, 3, width);
402 sqlite3_bind_int(statement, 4, height);
403 sqlite3_bind_int(statement, 5, left);
404 sqlite3_bind_int(statement, 6, right);
406 sqlite3_bind_int(statement, 8, bottom);
409 {
411 if (sqlite3_prepare_v2(m_db, "UPDATE LensCropTable SET CropLeft=?5, CropRight=?6, CropTop=?7, CropBottom=?8 WHERE Lens=?1 AND Focallength=?2 AND Width=?3 AND Height=?4;", -1, &statement, &tail) == SQLITE_OK)
412 {
413 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
415 sqlite3_bind_int(statement, 3, width);
416 sqlite3_bind_int(statement, 4, height);
417 sqlite3_bind_int(statement, 5, left);
418 sqlite3_bind_int(statement, 6, right);
420 sqlite3_bind_int(statement, 8, bottom);
422 };
423 };
424 };
427 return returnValue == SQLITE_DONE;
428 };
429 // removes the crop information for the given focallength and imagesize
430 bool RemoveLensCrop(const std::string& lens, const double focal, const int width, const int height)
431 {
432 if (m_db == NULL)
433 {
434 return false;
435 };
437 const char *tail;
438 int returnValue = 0;
439 if (sqlite3_prepare_v2(m_db, "DELETE FROM LensCropTable WHERE Lens=?1 AND Focallength=?2 AND Width=?3 AND Height=?4;", -1, &statement, &tail) == SQLITE_OK)
440 {
441 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
443 sqlite3_bind_int(statement, 3, width);
444 sqlite3_bind_int(statement, 4, height);
446 };
449 return returnValue == SQLITE_DONE;
450 };
451
452 // search for the distortion data for the given lens in the database
453 // returns true of data for lens was found, otherwise false
454 // returns 2 datasets with the values for the 2 nearest focal lengths
455 bool GetDistortionData(const std::string& lens, const double focallength, std::vector<Distortiondata>& distData) const
456 {
457 distData.clear();
458 if (m_db == NULL)
459 {
460 return false;
461 };
463 const char *tail;
464 if (sqlite3_prepare_v2(m_db, "SELECT Focallength, SUM(a*Weight)/SUM(Weight), SUM(b*Weight)/SUM(Weight), SUM(c*Weight)/SUM(Weight) FROM DistortionTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) ASC LIMIT 2;", -1, &statement, &tail) == SQLITE_OK)
465 {
466 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
467 sqlite3_bind_double(statement, 2, focallength);
469 {
475 distData.push_back(newDistData);
476 };
477 };
479 return !distData.empty();
480 };
481 // saves the distortion data in the database
482 // returns true, if data were successful saved into db, false if errors occurred during saving
483 bool SaveDistortion(const std::string& lens, const double focallength, const double a, const double b, const double c, const int weight = 10)
484 {
485 if (m_db == NULL)
486 {
487 return false;
488 };
490 const char *tail;
491 int returnValue = 0;
492 if (sqlite3_prepare_v2(m_db, "INSERT INTO DistortionTable(Lens, Focallength, a, b, c, Weight) VALUES(?1,?2,?3,?4,?5,?6);", -1, &statement, &tail) == SQLITE_OK)
493 {
494 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
495 sqlite3_bind_double(statement, 2, focallength);
499 sqlite3_bind_int(statement, 6, weight);
501 };
503 return returnValue == SQLITE_DONE;
504 };
505 // search for the vignetting data for the given lens in the database
506 // returns true of data for lens was found, otherwise false
507 // returns maximal 4 datasets: datasets of the 2 nearest focallengths and for each focallength the 2 nearest apertures
508 bool GetVignettingData(const std::string& lens, const double focallength, const double aperture, std::vector<Vignettingdata>& vigData) const
509 {
510 vigData.clear();
511 if (m_db == NULL)
512 {
513 return false;
514 };
516 const char *tail;
518 "SELECT Focallength, Aperture, SUM(Vb*Weight)/SUM(Weight), SUM(Vc*Weight)/SUM(Weight), SUM(Vd*Weight)/SUM(Weight) FROM VignettingTable "
519 "WHERE Lens = ?1 AND ("
520 "("
521 "Focallength IN "
522 "(SELECT Focallength FROM VignettingTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) LIMIT 1) "
523 "AND Aperture IN "
524 "(SELECT Aperture FROM VignettingTable WHERE Lens=?1 AND "
525 "Focallength IN "
526 "(SELECT Focallength from VignettingTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) LIMIT 1) "
527 "GROUP BY Aperture ORDER BY ABS(Aperture-?3) LIMIT 2)"
528 ") OR ("
529 "Focallength IN "
530 "(SELECT Focallength FROM VignettingTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) LIMIT 1 OFFSET 1) "
531 "AND Aperture IN "
532 "(SELECT Aperture FROM VignettingTable WHERE Lens=?1 AND "
533 "Focallength IN "
534 "(SELECT Focallength FROM VignettingTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) LIMIT 1 OFFSET 1) "
535 "GROUP BY Aperture ORDER BY ABS(Aperture-?3) LIMIT 2)"
536 ")"
537 ")"
538 "GROUP BY Focallength, Aperture ORDER BY Focallength, Aperture;",
539 -1, &statement, &tail) == SQLITE_OK)
540 {
541 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
542 sqlite3_bind_double(statement, 2, focallength);
543 sqlite3_bind_double(statement, 3, aperture);
545 {
552 vigData.push_back(newVigData);
553 };
554 };
556 return !vigData.empty();
557 };
558 // saves the vignetting data in the database
559 // returns true, if data were successful saved into db, false if errors occurred during saving
560 bool SaveVignetting(const std::string& lens, const double focallength, const double aperture, const double distance, const double Vb, const double Vc, const double Vd, const int weight = 10)
561 {
562 if (m_db == NULL)
563 {
564 return false;
565 };
567 const char *tail;
568 int returnValue = 0;
569 if (sqlite3_prepare_v2(m_db, "INSERT INTO VignettingTable(Lens, Focallength, Aperture, Distance, Vb, Vc, Vd, Weight) VALUES(?1,?2,?3,?4,?5,?6,?7,?8);", -1, &statement, &tail) == SQLITE_OK)
570 {
571 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
572 sqlite3_bind_double(statement, 2, focallength);
573 sqlite3_bind_double(statement, 3, aperture);
574 sqlite3_bind_double(statement, 4, distance);
578 sqlite3_bind_int(statement, 8, weight);
580 };
582 return returnValue == SQLITE_DONE;
583 };
584 // search for the tca data for the given lens in the database
585 // returns true of data for lens was found, otherwise false
586 // returns 2 datasets with the values for the 2 nearest focal lengths
587 bool GetTCAData(const std::string& lens, const double focallength, std::vector<TCAdata>& tcaData) const
588 {
589 tcaData.clear();
590 if (m_db == NULL)
591 {
592 return false;
593 };
595 const char *tail;
596 if (sqlite3_prepare_v2(m_db, "SELECT Focallength, SUM(ra*Weight)/SUM(Weight), SUM(rb*Weight)/SUM(Weight), SUM(rc*Weight)/SUM(Weight), SUM(rd*Weight)/SUM(Weight), SUM(ba*Weight)/SUM(Weight), SUM(bb*Weight)/SUM(Weight), SUM(bc*Weight)/SUM(Weight), SUM(bd*Weight)/SUM(Weight) FROM TCATable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) ASC LIMIT 2;", -1, &statement, &tail) == SQLITE_OK)
597 {
598 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
599 sqlite3_bind_double(statement, 2, focallength);
601 {
612 tcaData.push_back(newTCAData);
613 };
614 };
616 return !tcaData.empty();
617 };
618 // saves the tca data in the database
619 // returns true, if data were successful saved into db, false if errors occurred during saving
620 bool SaveTCAData(const std::string& lens, const double focallength, const double ra, const double rb, const double rc, const double rd,
621 const double ba, const double bb, const double bc, const double bd, const int weight = 10)
622 {
623 if (m_db == NULL)
624 {
625 return false;
626 };
628 const char *tail;
629 int returnValue = 0;
630 if (sqlite3_prepare_v2(m_db, "INSERT INTO TCATable(Lens, Focallength, ra, rb, rc, rd, ba, bb, bc, bd, Weight) VALUES(?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11);", -1, &statement, &tail) == SQLITE_OK)
631 {
632 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
633 sqlite3_bind_double(statement, 2, focallength);
642 sqlite3_bind_int(statement, 11, weight);
644 };
646 return returnValue == SQLITE_DONE;
647 };
648 // saves the EMoR data in the database
649 // returns true, if data were successful saved into db, false if errors occurred during saving
650 bool SaveEMoR(const std::string& maker, const std::string& model, const int iso, const double Ra, const double Rb, const double Rc, const double Rd, const double Re, const int weight = 10)
651 {
652 if (m_db == NULL)
653 {
654 return false;
655 };
657 const char *tail;
658 int returnValue = 0;
659 if (sqlite3_prepare_v2(m_db, "INSERT INTO EMORTable(Maker, Model, ISO, Ra, Rb, Rc, Rd, Re, Weight) VALUES(?1,?2,?3,?4,?5,?6,?7,?8,?9);", -1, &statement, &tail) == SQLITE_OK)
660 {
661 sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
662 sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
669 sqlite3_bind_int(statement, 9, weight);
671 };
673 return returnValue == SQLITE_DONE;
674 };
675 // return a list of lens names which has certain information
676 bool GetLensNames(const bool distortion, const bool vignetting, const bool tca, LensList& lensList) const
677 {
678 lensList.clear();
679 if (m_db == NULL)
680 {
681 return false;
682 };
684 const std::string statement_distortion("SELECT DISTINCT Lens FROM DistortionTable");
685 const std::string statement_vignetting("SELECT DISTINCT Lens FROM VignettingTable");
686 const std::string statement_tca("SELECT DISTINCT Lens FROM TCATable");
687 std::string statementString;
688 if (distortion)
689 {
691 };
692 if (vignetting)
693 {
694 if (!statementString.empty())
695 {
696 statementString.append(" UNION ");
697 };
699 };
700 if (tca)
701 {
702 if (!statementString.empty())
703 {
704 statementString.append(" UNION ");
705 };
707 };
708 if (statementString.empty())
709 {
710 return false;
711 };
712 const char *tail;
714 {
716 {
717 std::stringstream stream;
719 lensList.push_back(stream.str());
720 };
721 };
723 return !lensList.empty();
724 };
725 // clean up data base
726 bool CleanUp()
727 {
728 if (m_db == NULL)
729 {
730 return false;
731 };
734 "INSERT INTO DistortionTable(Lens, Focallength, a, b, c, Weight) "
735 "SELECT Lens, Focallength, SUM(a*Weight)/SUM(Weight), SUM(b*Weight)/SUM(Weight), SUM(c*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM DistortionTable GROUP By Lens, Focallength;"
736 "DELETE FROM DistortionTable WHERE Weight>=0;"
737 "UPDATE DistortionTable SET Weight=-Weight WHERE Weight<0;"
738 "INSERT INTO LensHFOVTable(Lens, Focallength, HFOV, Weight) "
739 "SELECT Lens, Focallength, SUM(HFOV*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM LensHFOVTable GROUP By Lens, Focallength;"
740 "DELETE FROM LensHFOVTable WHERE Weight>=0;"
741 "UPDATE LensHFOVTable SET Weight=-Weight WHERE Weight<0;"
742 "INSERT INTO TCATable(Lens, Focallength, ra, rb, rc, rd, ba, bb, bc, bd, Weight) "
743 "SELECT Lens, Focallength, SUM(ra*Weight)/SUM(Weight), SUM(rb*Weight)/SUM(Weight), SUM(rc*Weight)/SUM(Weight), SUM(rd*Weight)/SUM(Weight), SUM(ba*Weight)/SUM(Weight), SUM(bb*Weight)/SUM(Weight), SUM(bc*Weight)/SUM(Weight), SUM(bd*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM TCATable GROUP By Lens, Focallength;"
744 "DELETE FROM TCATable WHERE Weight>=0;"
745 "UPDATE TCATable SET Weight=-Weight WHERE Weight<0;"
746 "INSERT INTO VignettingTable(Lens, Focallength, Aperture, Distance, Vb, Vc, Vd, Weight) "
747 "SELECT Lens, Focallength, Aperture, Distance, SUM(Vb*Weight)/SUM(Weight), SUM(Vc*Weight)/SUM(Weight), SUM(Vd*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM VignettingTable GROUP By Lens, Focallength, Aperture, Distance;"
748 "DELETE FROM VignettingTable WHERE Weight>=0;"
749 "UPDATE VignettingTable SET Weight=-Weight WHERE Weight<0;"
750 "INSERT INTO EMORTable(Maker, Model, ISO, Ra, Rb, Rc, Rd, Re, Weight) "
751 "SELECT Maker, Model, ISO, SUM(Ra*Weight)/SUM(Weight), SUM(Rb*Weight)/SUM(Weight), SUM(Rc*Weight)/SUM(Weight), SUM(Rd*Weight)/SUM(Weight), SUM(Re*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM EMORTable GROUP By Maker, Model, ISO;"
752 "DELETE FROM EMORTable WHERE Weight>=0;"
753 "UPDATE EMORTable SET Weight=-Weight WHERE Weight<0;",
754 NULL, NULL, NULL);
756 return sqlite3_exec(m_db, "VACUUM;", NULL, NULL, NULL) == SQLITE_OK;
757 };
758 // remove lens from all tables
759 bool RemoveLens(const std::string& lensname)
760 {
761 if (m_db == NULL)
762 {
763 return false;
764 };
766 bool result = RemoveLensFromTable("LensProjectionTable", lensname);
767 result &= RemoveLensFromTable("LensHFOVTable", lensname);
768 result &= RemoveLensFromTable("LensCropTable", lensname);
769 result &= RemoveLensFromTable("DistortionTable", lensname);
770 result &= RemoveLensFromTable("VignettingTable", lensname);
771 result &= RemoveLensFromTable("TCATable", lensname);
773 return result;
774 };
775 // remove camera from database
776 bool RemoveCamera(const std::string& maker, const std::string& model)
777 {
778 if (m_db == NULL)
779 {
780 return false;
781 };
783 bool result = RemoveCameraFromTable("CameraCropTable", maker, model);
784 result &= RemoveCameraFromTable("EMORTable", maker, model);
786 return result;
787 };
788 // export to file
789 bool ExportToFile(const std::string& filename)
790 {
791 if (m_db == NULL)
792 {
793 return false;
794 };
795 CleanUp();
796 std::ofstream output(filename.c_str());
797 if (output.is_open())
798 {
799 output << "TABLE=CameraCropTable" << std::endl
800 << "COLUMNS=Maker;Model;Cropfactor" << std::endl;
801 OutputSQLToStream("SELECT Maker, Model, Cropfactor FROM CameraCropTable;", output);
802 output << "ENDTABLE" << std::endl
803 << "TABLE=LensProjectionTable" << std::endl
804 << "COLUMNS=Lens;Projection" << std::endl;
805 OutputSQLToStream("SELECT Lens, Projection FROM LensProjectionTable;", output);
806 output << "ENDTABLE" << std::endl
807 << "TABLE=LensHFOVTable" << std::endl
808 << "COLUMNS=Lens;Focallength;HFOV;Weight" << std::endl;
809 OutputSQLToStream("SELECT Lens, Focallength, HFOV, Weight FROM LensHFOVTable;", output);
810 output << "ENDTABLE" << std::endl
811 << "TABLE=LensCropTable" << std::endl
812 << "COLUMNS=Lens;Focallength;Width;Height;CropLeft;CropRight;CropTop;CropBottom" << std::endl;
813 OutputSQLToStream("SELECT Lens, Focallength, Width, Height, CropLeft, CropRight, CropTop, CropBottom FROM TABLE LensCropTable;", output);
814 output << "ENDTABLE" << std::endl
815 << "TABLE=DistortionTable" << std::endl
816 << "COLUMNS=Lens;Focallength;a;b;c;Weight" << std::endl;
817 OutputSQLToStream("SELECT Lens, Focallength, a, b, c, Weight FROM DistortionTable;", output);
818 output << "ENDTABLE" << std::endl
819 << "TABLE=VignettingTable" << std::endl
820 << "COLUMNS=Lens;Focallength;Aperture;Distance;Vb;Vc;Vd;Weight" << std::endl;
821 OutputSQLToStream("SELECT Lens, Focallength, Aperture, Distance, Vb, Vc, Vd, Weight FROM VignettingTable;", output);
822 output << "ENDTABLE" << std::endl
823 << "TABLE=TCATable" << std::endl
824 << "COLUMNS=Lens;Focallength;ra;rb;rc;rd;ba;bb;bc;bd;Weight" << std::endl;
825 OutputSQLToStream("SELECT Lens, Focallength, ra, rb, rc, rd, ba, bb, bc, bd, Weight FROM TCATable;", output);
826 output << "ENDTABLE" << std::endl
827 << "TABLE=EMORTable" << std::endl
828 << "COLUMNS=Maker;Model;ISO;Ra;Rb;Rc;Rd;Re;Weight" << std::endl;
829 OutputSQLToStream("SELECT Maker, Model, ISO, Ra, Rb, Rc, Rd, Re, Weight FROM EMORTable;", output);
830 output << "ENDTABLE" << std::endl;
831 output.close();
832 return true;
833 }
834 else
835 {
836 std::cerr << "Could not open file \"" << filename << "\"." << std::endl;
837 return false;
838 };
839 };
840 // import data from external file
841 bool ImportFromFile(const std::string& filename)
842 {
843 if (m_db == NULL)
844 {
845 return false;
846 };
847 std::ifstream input(filename);
848 if (input.is_open())
849 {
850 while (!input.eof())
851 {
852 std::string line;
853 std::getline(input, line);
854 if (line.empty())
855 {
856 continue;
857 };
858 if (line.compare(0, 6, "TABLE=") == 0)
859 {
860 std::vector<std::string> substring = hugin_utils::SplitString(line, "=");
861 if (substring.size() == 2)
862 {
863 if (substring[1] == "CameraCropTable")
864 {
865 std::cout << "\tImporting CameraCropTable..." << std::endl;
867 {
868 input.close();
869 std::cerr << "Error in input file." << std::endl;
870 return false;
871 };
872 }
873 else
874 {
875 if (substring[1] == "LensProjectionTable")
876 {
877 std::cout << "\tImporting LensProjectionTable..." << std::endl;
879 {
880 input.close();
881 std::cerr << "Error in input file." << std::endl;
882 return false;
883 };
884 }
885 else
886 {
887 if (substring[1] == "LensHFOVTable")
888 {
889 std::cout << "\tImporting LensHFOVTable..." << std::endl;
890 if (!ImportHFOV(input))
891 {
892 input.close();
893 std::cerr << "Error in input file." << std::endl;
894 return false;
895 };
896 }
897 else
898 {
899 if (substring[1] == "LensCropTable")
900 {
901 std::cout << "\tImporting LensCropTable..." << std::endl;
902 if (!ImportLensCrop(input))
903 {
904 input.close();
905 std::cerr << "Error in input file." << std::endl;
906 return false;
907 };
908 }
909 else
910 {
911 if (substring[1] == "DistortionTable")
912 {
913 std::cout << "\tImporting DistortionTable..." << std::endl;
915 {
916 input.close();
917 std::cerr << "Error in input file." << std::endl;
918 return false;
919 };
920 }
921 else
922 {
923 if (substring[1] == "VignettingTable")
924 {
925 std::cout << "\tImporting VignettingTable..." << std::endl;
927 {
928 input.close();
929 std::cerr << "Error in input file." << std::endl;
930 return false;
931 };
932 }
933 else
934 {
935 if (substring[1] == "TCATable")
936 {
937 std::cout << "\tImporting TCATable..." << std::endl;
938 if (!ImportTCA(input))
939 {
940 input.close();
941 std::cerr << "Error in input file." << std::endl;
942 return false;
943 };
944 }
945 else
946 {
947 if (substring[1] == "EMORTable")
948 {
949 std::cout << "\tImporting EMORTable..." << std::endl;
950 if (!ImportEMOR(input))
951 {
952 input.close();
953 std::cerr << "Error in input file." << std::endl;
954 return false;
955 };
956 }
957 else
958 {
959 input.close();
960 std::cerr << "Error in input file (Unknown table \"" << substring[1] << "\")." << std::endl;
961 return false;
962 };
963 };
964 };
965 };
966 };
967 };
968 };
969 };
970 }
971 else
972 {
973 std::cerr << "Error in input file (Could not parse table name)." << std::endl;
974 input.close();
975 return false;
976 };
977 }
978 else
979 {
980 std::cerr << "Error in input file (Could not find TABLE section)." << std::endl;
981 input.close();
982 return false;
983 };
984 };
985 input.close();
986 CleanUp();
987 return true;
988 }
989 else
990 {
991 std::cerr << "Could not open file \"" << filename << "\"." << std::endl;
992 return false;
993 };
994 };
995private:
996 // helper functions for BEGIN/COMMIT TRANSACTION
998 {
1000 {
1001 m_runningTransaction = (sqlite3_exec(m_db, "BEGIN TRANSACTION;", NULL, NULL, NULL) == SQLITE_OK);
1002 };
1003 };
1005 {
1007 {
1008 sqlite3_exec(m_db, "COMMIT TRANSACTION;", NULL, NULL, NULL);
1009 m_runningTransaction = false;
1010 };
1011 };
1012
1013 // removes the given lens from the selected table
1014 bool RemoveLensFromTable(const std::string& table, const std::string& lens)
1015 {
1017 const char *tail;
1018 int returnValue = 0;
1019 std::string sqlStatement("DELETE FROM ");
1020 sqlStatement.append(table);
1021 sqlStatement.append(" WHERE Lens=?;");
1023 {
1024 sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
1026 };
1028 return returnValue == SQLITE_DONE;
1029 };
1030 // remove given camera from selected table
1031 bool RemoveCameraFromTable(const std::string& table, const std::string& maker, const std::string& model)
1032 {
1034 const char *tail;
1035 int returnValue = 0;
1036 std::string sqlStatement("DELETE FROM ");
1037 sqlStatement.append(table);
1038 sqlStatement.append(" WHERE Maker=?1 AND Model=?2;");
1040 {
1041 sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
1042 sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
1044 };
1046 return returnValue == SQLITE_DONE;
1047 };
1048 // write result of sql statement to stream, the columns are separated by ;
1049 void OutputSQLToStream(const std::string& sqlstatement, std::ostream& stream)
1050 {
1052 const char *tail;
1054 {
1056 {
1057 const int count = sqlite3_column_count(statement);
1058 if (count > 0)
1059 {
1060 for (int i = 0; i < count; ++i)
1061 {
1063 if (i + 1 < count)
1064 {
1065 stream << ";";
1066 };
1067 };
1068 };
1069 stream << std::endl;
1070 };
1071 };
1073 }
1074 // import cropfactors from stream
1075 bool ImportCropFactor(std::istream& input)
1076 {
1077 std::string s;
1078 std::getline(input, s);
1079 // first line should contains the column list
1080 if (s.compare(0, 8, "COLUMNS=") != 0)
1081 {
1082 return false;
1083 };
1084 std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
1085 int indexMaker = -1;
1086 int indexModel = -1;
1087 int indexCropfactor = -1;
1088 for (size_t i = 0; i < columns.size(); ++i)
1089 {
1090 if (columns[i] == "Maker")
1091 {
1092 indexMaker = i;
1093 };
1094 if (columns[i] == "Model")
1095 {
1096 indexModel = i;
1097 };
1098 if (columns[i] == "Cropfactor")
1099 {
1101 };
1102 };
1103 if (indexMaker == -1)
1104 {
1105 std::cerr << "ERROR: Missing column \"Maker\"." << std::endl;
1106 return false;
1107 };
1108 if (indexModel == -1)
1109 {
1110 std::cerr << "ERROR: Missing column \"Model\"." << std::endl;
1111 return false;
1112 };
1113 if (indexCropfactor == -1)
1114 {
1115 std::cerr << "ERROR: Missing column \"Cropfactor\"." << std::endl;
1116 return false;
1117 };
1118 if (input.eof())
1119 {
1120 return false;
1121 };
1122 std::getline(input, s);
1123 while (!input.eof())
1124 {
1125 if (s == "ENDTABLE")
1126 {
1127 return true;
1128 }
1129 std::vector<std::string> items = hugin_utils::SplitString(s, ";");
1130 if (items.size() == columns.size())
1131 {
1132 //ignore lines with not matching count of items
1133 double cropfactor;
1135 {
1137 };
1138 };
1139 std::getline(input, s);
1140 };
1141 return false;
1142 };
1143 // import projection settings from stream
1144 bool ImportProjection(std::istream& input)
1145 {
1146 std::string s;
1147 std::getline(input, s);
1148 // first line should contains the column list
1149 if (s.compare(0, 8, "COLUMNS=") != 0)
1150 {
1151 return false;
1152 };
1153 std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
1154 int indexLens = -1;
1155 int indexProjection = -1;
1156 for (size_t i = 0; i < columns.size(); ++i)
1157 {
1158 if (columns[i] == "Lens")
1159 {
1160 indexLens = i;
1161 };
1162 if (columns[i] == "Projection")
1163 {
1165 };
1166 };
1167 if (indexLens == -1)
1168 {
1169 std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
1170 return false;
1171 };
1172 if (indexProjection == -1)
1173 {
1174 std::cerr << "ERROR: Missing column \"Projection\"." << std::endl;
1175 return false;
1176 };
1177 if (input.eof())
1178 {
1179 return false;
1180 };
1181 std::getline(input, s);
1182 while (!input.eof())
1183 {
1184 if (s == "ENDTABLE")
1185 {
1186 return true;
1187 }
1188 std::vector<std::string> items = hugin_utils::SplitString(s, ";");
1189 if (items.size() == columns.size())
1190 {
1191 //ignore lines with not matching count of items
1192 int projection;
1194 {
1195 SaveLensProjection(items[indexLens], projection);
1196 };
1197 };
1198 std::getline(input, s);
1199 };
1200 return false;
1201 };
1202 // import hfov values from stream
1203 bool ImportHFOV(std::istream& input)
1204 {
1205 std::string s;
1206 std::getline(input, s);
1207 // first line should contains the column list
1208 if (s.compare(0, 8, "COLUMNS=") != 0)
1209 {
1210 return false;
1211 };
1212 std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
1213 int indexLens = -1;
1214 int indexFocallength = -1;
1215 int indexHFOV = -1;
1216 int indexWeight = -1;
1217 for (size_t i = 0; i < columns.size(); ++i)
1218 {
1219 if (columns[i] == "Lens")
1220 {
1221 indexLens = i;
1222 };
1223 if (columns[i] == "Focallength")
1224 {
1226 };
1227 if (columns[i] == "HFOV")
1228 {
1229 indexHFOV = i;
1230 };
1231 if (columns[i] == "Weight")
1232 {
1233 indexWeight = i;
1234 };
1235 };
1236 if (indexLens == -1)
1237 {
1238 std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
1239 return false;
1240 };
1241 if (indexFocallength == -1)
1242 {
1243 std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
1244 return false;
1245 };
1246 if (indexHFOV == -1)
1247 {
1248 std::cerr << "ERROR: Missing column \"HFOV\"." << std::endl;
1249 return false;
1250 };
1251 if (indexWeight == -1)
1252 {
1253 std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
1254 return false;
1255 };
1256 if (input.eof())
1257 {
1258 return false;
1259 };
1260 std::getline(input, s);
1261 while (!input.eof())
1262 {
1263 if (s == "ENDTABLE")
1264 {
1265 return true;
1266 }
1267 std::vector<std::string> items = hugin_utils::SplitString(s, ";");
1268 if (items.size() == columns.size())
1269 {
1270 //ignore lines with not matching count of items
1271 double focallength;
1272 double hfov;
1273 int weight;
1277 if (valid)
1278 {
1279 SaveHFOV(items[indexLens], focallength, hfov, weight);
1280 };
1281 };
1282 std::getline(input, s);
1283 };
1284 return false;
1285 };
1286 // import crop values from stream
1287 bool ImportLensCrop(std::istream& input)
1288 {
1289 std::string s;
1290 std::getline(input, s);
1291 // first line should contains the column list
1292 if (s.compare(0, 8, "COLUMNS=") != 0)
1293 {
1294 return false;
1295 };
1296 std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
1297 int indexLens = -1;
1298 int indexFocallength = -1;
1299 int indexWidth = -1;
1300 int indexHeight = -1;
1301 int indexCropLeft = -1;
1302 int indexCropRight = -1;
1303 int indexCropTop = -1;
1304 int indexCropBottom = -1;
1305 for (size_t i = 0; i < columns.size(); ++i)
1306 {
1307 if (columns[i] == "Lens")
1308 {
1309 indexLens = i;
1310 };
1311 if (columns[i] == "Focallength")
1312 {
1314 };
1315 if (columns[i] == "Width")
1316 {
1317 indexWidth = i;
1318 };
1319 if (columns[i] == "Height")
1320 {
1321 indexHeight = i;
1322 };
1323 if (columns[i] == "CropLeft")
1324 {
1325 indexCropLeft = i;
1326 };
1327 if (columns[i] == "CropRight")
1328 {
1329 indexCropRight = i;
1330 };
1331 if (columns[i] == "CropTop")
1332 {
1333 indexCropTop = i;
1334 };
1335 if (columns[i] == "CropBottom")
1336 {
1338 };
1339 };
1340 if (indexLens == -1)
1341 {
1342 std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
1343 return false;
1344 };
1345 if (indexFocallength == -1)
1346 {
1347 std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
1348 return false;
1349 };
1350 if (indexWidth == -1)
1351 {
1352 std::cerr << "ERROR: Missing column \"Width\"." << std::endl;
1353 return false;
1354 };
1355 if (indexHeight == -1)
1356 {
1357 std::cerr << "ERROR: Missing column \"Height\"." << std::endl;
1358 return false;
1359 };
1360 if (indexCropLeft == -1)
1361 {
1362 std::cerr << "ERROR: Missing column \"CropLeft\"." << std::endl;
1363 return false;
1364 };
1365 if (indexCropRight == -1)
1366 {
1367 std::cerr << "ERROR: Missing column \"CropRight\"." << std::endl;
1368 return false;
1369 };
1370 if (indexCropTop == -1)
1371 {
1372 std::cerr << "ERROR: Missing column \"CropTop\"." << std::endl;
1373 return false;
1374 };
1375 if (indexCropBottom == -1)
1376 {
1377 std::cerr << "ERROR: Missing column \"CropBottom\"." << std::endl;
1378 return false;
1379 };
1380 if (input.eof())
1381 {
1382 return false;
1383 };
1384 std::getline(input, s);
1385 while (!input.eof())
1386 {
1387 if (s == "ENDTABLE")
1388 {
1389 return true;
1390 }
1391 std::vector<std::string> items = hugin_utils::SplitString(s, ";");
1392 if (items.size() == columns.size())
1393 {
1394 //ignore lines with not matching count of items
1395 double focallength;
1396 int width, height, cropLeft, cropRight, cropTop, cropBottom;
1404 if (valid)
1405 {
1406 SaveLensCrop(items[indexLens], focallength, width, height, cropLeft, cropRight, cropTop, cropBottom);
1407 };
1408 };
1409 std::getline(input, s);
1410 };
1411 return false;
1412 };
1413 // import distortion values from stream
1414 bool ImportDistortion(std::istream& input)
1415 {
1416 std::string s;
1417 std::getline(input, s);
1418 // first line should contains the column list
1419 if (s.compare(0, 8, "COLUMNS=") != 0)
1420 {
1421 return false;
1422 };
1423 std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
1424 int indexLens = -1;
1425 int indexFocallength = -1;
1426 int indexA = -1;
1427 int indexB = -1;
1428 int indexC = -1;
1429 int indexWeight = -1;
1430 for (size_t i = 0; i < columns.size(); ++i)
1431 {
1432 if (columns[i] == "Lens")
1433 {
1434 indexLens = i;
1435 };
1436 if (columns[i] == "Focallength")
1437 {
1439 };
1440 if (columns[i] == "a")
1441 {
1442 indexA = i;
1443 };
1444 if (columns[i] == "b")
1445 {
1446 indexB = i;
1447 };
1448 if (columns[i] == "c")
1449 {
1450 indexC = i;
1451 };
1452 if (columns[i] == "Weight")
1453 {
1454 indexWeight = i;
1455 };
1456 };
1457 if (indexLens == -1)
1458 {
1459 std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
1460 return false;
1461 };
1462 if (indexFocallength == -1)
1463 {
1464 std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
1465 return false;
1466 };
1467 if (indexA == -1)
1468 {
1469 std::cerr << "ERROR: Missing column \"a\"." << std::endl;
1470 return false;
1471 };
1472 if (indexB == -1)
1473 {
1474 std::cerr << "ERROR: Missing column \"b\"." << std::endl;
1475 return false;
1476 };
1477 if (indexC == -1)
1478 {
1479 std::cerr << "ERROR: Missing column \"c\"." << std::endl;
1480 return false;
1481 };
1482 if (indexWeight == -1)
1483 {
1484 std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
1485 return false;
1486 };
1487 if (input.eof())
1488 {
1489 return false;
1490 };
1491 std::getline(input, s);
1492 while (!input.eof())
1493 {
1494 if (s == "ENDTABLE")
1495 {
1496 return true;
1497 }
1498 std::vector<std::string> items = hugin_utils::SplitString(s, ";");
1499 if (items.size() == columns.size())
1500 {
1501 //ignore lines with not matching count of items
1502 double focallength, a, b, c;
1503 int weight;
1509 if (valid)
1510 {
1511 SaveDistortion(items[indexLens], focallength, a, b, c, weight);
1512 };
1513 };
1514 std::getline(input, s);
1515 };
1516 return false;
1517 };
1518 // import vignetting values from stream
1519 bool ImportVignetting(std::istream& input)
1520 {
1521 std::string s;
1522 std::getline(input, s);
1523 // first line should contains the column list
1524 if (s.compare(0, 8, "COLUMNS=") != 0)
1525 {
1526 return false;
1527 };
1528 std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
1529 int indexLens = -1;
1530 int indexFocallength = -1;
1531 int indexAperture = -1;
1532 int indexDistance = -1;
1533 int indexVb = -1;
1534 int indexVc = -1;
1535 int indexVd = -1;
1536 int indexWeight = -1;
1537 for (size_t i = 0; i < columns.size(); ++i)
1538 {
1539 if (columns[i] == "Lens")
1540 {
1541 indexLens = i;
1542 };
1543 if (columns[i] == "Focallength")
1544 {
1546 };
1547 if (columns[i] == "Aperture")
1548 {
1549 indexAperture = i;
1550 };
1551 if (columns[i] == "Distance")
1552 {
1553 indexDistance = i;
1554 };
1555 if (columns[i] == "Vb")
1556 {
1557 indexVb = i;
1558 };
1559 if (columns[i] == "Vc")
1560 {
1561 indexVc = i;
1562 };
1563 if (columns[i] == "Vd")
1564 {
1565 indexVd = i;
1566 };
1567 if (columns[i] == "Weight")
1568 {
1569 indexWeight = i;
1570 };
1571 };
1572 if (indexLens == -1)
1573 {
1574 std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
1575 return false;
1576 };
1577 if (indexFocallength == -1)
1578 {
1579 std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
1580 return false;
1581 };
1582 if (indexAperture == -1)
1583 {
1584 std::cerr << "ERROR: Missing column \"Aperture\"." << std::endl;
1585 return false;
1586 };
1587 if (indexDistance == -1)
1588 {
1589 std::cerr << "ERROR: Missing column \"Distance\"." << std::endl;
1590 return false;
1591 };
1592 if (indexVb == -1)
1593 {
1594 std::cerr << "ERROR: Missing column \"Vb\"." << std::endl;
1595 return false;
1596 };
1597 if (indexVc == -1)
1598 {
1599 std::cerr << "ERROR: Missing column \"Vc\"." << std::endl;
1600 return false;
1601 };
1602 if (indexVd == -1)
1603 {
1604 std::cerr << "ERROR: Missing column \"Vd\"." << std::endl;
1605 return false;
1606 };
1607 if (indexWeight == -1)
1608 {
1609 std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
1610 return false;
1611 };
1612 if (input.eof())
1613 {
1614 return false;
1615 };
1616 std::getline(input, s);
1617 while (!input.eof())
1618 {
1619 if (s == "ENDTABLE")
1620 {
1621 return true;
1622 }
1623 std::vector<std::string> items = hugin_utils::SplitString(s, ";");
1624 if (items.size() == columns.size())
1625 {
1626 //ignore lines with not matching count of items
1627 double focallength, aperture, distance, Vb, Vc, Vd;
1628 int weight;
1636 if (valid)
1637 {
1638 SaveVignetting(items[indexLens], focallength, aperture, distance, Vb, Vc, Vd, weight);
1639 };
1640 };
1641 std::getline(input, s);
1642 };
1643 return false;
1644 };
1645 // import tca values from stream
1646 bool ImportTCA(std::istream& input)
1647 {
1648 std::string s;
1649 std::getline(input, s);
1650 // first line should contains the column list
1651 if (s.compare(0, 8, "COLUMNS=") != 0)
1652 {
1653 return false;
1654 };
1655 std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
1656 int indexLens = -1;
1657 int indexFocallength = -1;
1658 int indexRa = -1;
1659 int indexRb = -1;
1660 int indexRc = -1;
1661 int indexRd = -1;
1662 int indexBa = -1;
1663 int indexBb = -1;
1664 int indexBc = -1;
1665 int indexBd = -1;
1666 int indexWeight = -1;
1667 for (size_t i = 0; i < columns.size(); ++i)
1668 {
1669 if (columns[i] == "Lens")
1670 {
1671 indexLens = i;
1672 };
1673 if (columns[i] == "Focallength")
1674 {
1676 };
1677 if (columns[i] == "ra")
1678 {
1679 indexRa = i;
1680 };
1681 if (columns[i] == "rb")
1682 {
1683 indexRb = i;
1684 };
1685 if (columns[i] == "rc")
1686 {
1687 indexRc = i;
1688 };
1689 if (columns[i] == "rd")
1690 {
1691 indexRd = i;
1692 };
1693 if (columns[i] == "ba")
1694 {
1695 indexBa = i;
1696 };
1697 if (columns[i] == "bb")
1698 {
1699 indexBb = i;
1700 };
1701 if (columns[i] == "bc")
1702 {
1703 indexBc = i;
1704 };
1705 if (columns[i] == "bd")
1706 {
1707 indexBd = i;
1708 };
1709 if (columns[i] == "Weight")
1710 {
1711 indexWeight = i;
1712 };
1713 };
1714 if (indexLens == -1)
1715 {
1716 std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
1717 return false;
1718 };
1719 if (indexFocallength == -1)
1720 {
1721 std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
1722 return false;
1723 };
1724 if (indexRa == -1)
1725 {
1726 std::cerr << "ERROR: Missing column \"ra\"." << std::endl;
1727 return false;
1728 };
1729 if (indexRb == -1)
1730 {
1731 std::cerr << "ERROR: Missing column \"rb\"." << std::endl;
1732 return false;
1733 };
1734 if (indexRc == -1)
1735 {
1736 std::cerr << "ERROR: Missing column \"rc\"." << std::endl;
1737 return false;
1738 };
1739 if (indexRd == -1)
1740 {
1741 std::cerr << "ERROR: Missing column \"rd\"." << std::endl;
1742 return false;
1743 };
1744 if (indexBa == -1)
1745 {
1746 std::cerr << "ERROR: Missing column \"ba\"." << std::endl;
1747 return false;
1748 };
1749 if (indexBb == -1)
1750 {
1751 std::cerr << "ERROR: Missing column \"bb\"." << std::endl;
1752 return false;
1753 };
1754 if (indexBc == -1)
1755 {
1756 std::cerr << "ERROR: Missing column \"bc\"." << std::endl;
1757 return false;
1758 };
1759 if (indexBd == -1)
1760 {
1761 std::cerr << "ERROR: Missing column \"bd\"." << std::endl;
1762 return false;
1763 };
1764 if (indexWeight == -1)
1765 {
1766 std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
1767 return false;
1768 };
1769 if (input.eof())
1770 {
1771 return false;
1772 };
1773 std::getline(input, s);
1774 while (!input.eof())
1775 {
1776 if (s == "ENDTABLE")
1777 {
1778 return true;
1779 }
1780 std::vector<std::string> items = hugin_utils::SplitString(s, ";");
1781 if (items.size() == columns.size())
1782 {
1783 //ignore lines with not matching count of items
1784 double focallength, ra, rb, rc, rd, ba, bb, bc, bd;
1785 int weight;
1796 if (valid)
1797 {
1798 SaveTCAData(items[indexLens], focallength, ra, rb, rc, rd, ba, bb, bc, bd, weight);
1799 };
1800 };
1801 std::getline(input, s);
1802 };
1803 return false;
1804 };
1805 // import emor values from stream
1806 bool ImportEMOR(std::istream& input)
1807 {
1808 std::string s;
1809 std::getline(input, s);
1810 // first line should contains the column list
1811 if (s.compare(0, 8, "COLUMNS=") != 0)
1812 {
1813 return false;
1814 };
1815 std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
1816 int indexMaker = -1;
1817 int indexModel = -1;
1818 int indexISO = -1;
1819 int indexRa = -1;
1820 int indexRb = -1;
1821 int indexRc = -1;
1822 int indexRd = -1;
1823 int indexRe = -1;
1824 int indexWeight = -1;
1825 for (size_t i = 0; i < columns.size(); ++i)
1826 {
1827 if (columns[i] == "Maker")
1828 {
1829 indexMaker = i;
1830 };
1831 if (columns[i] == "Model")
1832 {
1833 indexModel = i;
1834 };
1835 if (columns[i] == "ISO")
1836 {
1837 indexISO = i;
1838 };
1839 if (columns[i] == "Ra")
1840 {
1841 indexRa = i;
1842 };
1843 if (columns[i] == "Rb")
1844 {
1845 indexRb = i;
1846 };
1847 if (columns[i] == "Rc")
1848 {
1849 indexRc = i;
1850 };
1851 if (columns[i] == "Rd")
1852 {
1853 indexRd = i;
1854 };
1855 if (columns[i] == "Re")
1856 {
1857 indexRe = i;
1858 };
1859 if (columns[i] == "Weight")
1860 {
1861 indexWeight = i;
1862 };
1863 };
1864 if (indexMaker == -1)
1865 {
1866 std::cerr << "ERROR: Missing column \"Maker\"." << std::endl;
1867 return false;
1868 };
1869 if (indexModel == -1)
1870 {
1871 std::cerr << "ERROR: Missing column \"Model\"." << std::endl;
1872 return false;
1873 };
1874 if (indexISO == -1)
1875 {
1876 std::cerr << "ERROR: Missing column \"ISO\"." << std::endl;
1877 return false;
1878 };
1879 if (indexRa == -1)
1880 {
1881 std::cerr << "ERROR: Missing column \"Ra\"." << std::endl;
1882 return false;
1883 };
1884 if (indexRb == -1)
1885 {
1886 std::cerr << "ERROR: Missing column \"Rb\"." << std::endl;
1887 return false;
1888 };
1889 if (indexRc == -1)
1890 {
1891 std::cerr << "ERROR: Missing column \"Rc\"." << std::endl;
1892 return false;
1893 };
1894 if (indexRd == -1)
1895 {
1896 std::cerr << "ERROR: Missing column \"Rd\"." << std::endl;
1897 return false;
1898 };
1899 if (indexRe == -1)
1900 {
1901 std::cerr << "ERROR: Missing column \"Re\"." << std::endl;
1902 return false;
1903 };
1904 if (indexWeight == -1)
1905 {
1906 std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
1907 return false;
1908 };
1909 if (input.eof())
1910 {
1911 return false;
1912 };
1913 std::getline(input, s);
1914 while (!input.eof())
1915 {
1916 if (s == "ENDTABLE")
1917 {
1918 return true;
1919 }
1920 std::vector<std::string> items = hugin_utils::SplitString(s, ";");
1921 if (items.size() == columns.size())
1922 {
1923 //ignore lines with not matching count of items
1924 double Ra, Rb, Rc, Rd, Re;
1925 int iso, weight;
1933 if (valid)
1934 {
1935 SaveEMoR(items[indexMaker], items[indexModel], iso, Ra, Rb, Rc, Rd, Re, weight);
1936 };
1937 };
1938 std::getline(input, s);
1939 };
1940 return false;
1941 };
1942
1943 std::string m_filename;
1946};
1947
1948double InterpolateValue(double x, double x0, double y0, double x1, double y1)
1949{
1950 if (fabs(x1 - x0) < 1e-4)
1951 {
1952 // prevent division through 0, should normally not happens
1953 return y0;
1954 };
1955 return y0 + (y1 - y0) * (x - x0) / (x1 - x0);
1956};
1957
1958double InterpolateValueTriangle(double x, double y,
1959 double x1, double y1, double z1,
1960 double x2, double y2, double z2,
1961 double x3, double y3, double z3)
1962{
1963 const double a = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
1964 if (fabs(a) < 1e-6)
1965 {
1966 // this should never happens
1967 return z1;
1968 };
1969 return z1 + ((x - x1) * ((z2 - z1) * (y3 - y1) - (y2 - y1) * (z3 - z1)) + (y - y1) * ((x2 - x1) * (z3 - z1) - (z2 - z1) * (x3 - x1))) / a;
1970};
1971
1973{
1974 std::string filename = hugin_utils::GetUserAppDataDir();
1975 if (filename.length() == 0)
1976 {
1977 m_db = NULL;
1978 }
1979 else
1980 {
1981#if _WIN32
1982 filename.append("\\");
1983#else
1984 filename.append("/");
1985#endif
1986 filename.append("camlens.db");
1987 m_db = new LensDB::Database(filename);
1988 if (!m_db)
1989 {
1990 m_db = NULL;
1991 };
1992 };
1993};
1994
1996{
1997 if (m_db)
1998 delete m_db;
1999};
2000
2002{
2003 if(m_instance==NULL)
2004 {
2005 m_instance = new LensDB();
2006 };
2007 return *m_instance;
2008};
2009
2011{
2012 if (m_instance != NULL)
2013 {
2014 delete m_instance;
2015 };
2016 m_instance = NULL;
2017};
2018
2019std::string LensDB::GetDBFilename() const
2020{
2021 if (m_db)
2022 {
2023 return m_db->GetDBFilename();
2024 }
2025 else
2026 {
2027 return std::string();
2028 };
2029};
2030
2031bool LensDB::GetCropFactor(const std::string& maker, const std::string& model, double& cropFactor) const
2032{
2033 if (m_db == NULL)
2034 {
2035 return false;
2036 };
2037 return m_db->GetCropFactor(maker, model, cropFactor);
2038};
2039
2040bool LensDB::GetProjection(const std::string& lens, BaseSrcPanoImage::Projection& projection) const
2041{
2042 if (m_db == NULL)
2043 {
2044 return false;
2045 };
2046 int proj;
2047 if (m_db->GetLensProjection(lens, proj))
2048 {
2049 projection = static_cast<BaseSrcPanoImage::Projection>(proj);
2050 return true;
2051 }
2052 else
2053 {
2054 return false;
2055 };
2056};
2057
2058inline int fsign(double a)
2059{
2060 return (a > 0) ? 1 : ((a < 0) ? -1 : 0);
2061}
2062
2064bool IsFocallengthNearRange(const double focal, const double limit1, const double limit2, const double tol)
2065{
2066 if (fsign(focal - limit1) != fsign(focal - limit2))
2067 {
2068 return true;
2069 };
2070 return fabs(focal - limit1) < tol * focal;
2071}
2072
2073bool LensDB::GetCrop(const std::string& lens, const double focal, const vigra::Size2D& imageSize, vigra::Rect2D& cropRect) const
2074{
2075 if(m_db == NULL)
2076 {
2077 return false;
2078 };
2079 std::vector<Database::CropData> cropData;
2080 if (!m_db->GetLensCrop(lens, focal, imageSize.width() , imageSize.height(), cropData))
2081 {
2082 return false;
2083 };
2084 int left, right, top, bottom;
2085 if (cropData.size() == 1)
2086 {
2087 // only one entry found
2088 // check focal length
2089 if (fabs(cropData[0].focallength - focal) < 0.075f * focal)
2090 {
2091 // focal length matches
2092 left = cropData[0].left;
2093 right = cropData[0].right;
2094 top = cropData[0].top;
2095 bottom = cropData[0].bottom;
2096 }
2097 else
2098 {
2099 // if focal length does not match we ignore crop
2100 return false;
2101 }
2102 }
2103 else
2104 {
2105 if (!IsFocallengthNearRange(focal, cropData[0].focallength, cropData[1].focallength, 0.15f))
2106 {
2107 return false;
2108 };
2109 left = hugin_utils::roundi(InterpolateValue(focal, cropData[0].focallength, cropData[0].left, cropData[1].focallength, cropData[1].left));
2110 right = hugin_utils::roundi(InterpolateValue(focal, cropData[0].focallength, cropData[0].right, cropData[1].focallength, cropData[1].right));
2111 top = hugin_utils::roundi(InterpolateValue(focal, cropData[0].focallength, cropData[0].top, cropData[1].focallength, cropData[1].top));
2112 bottom = hugin_utils::roundi(InterpolateValue(focal, cropData[0].focallength, cropData[0].bottom, cropData[1].focallength, cropData[1].bottom));
2113 };
2114 cropRect.setUpperLeft(vigra::Point2D(left, top));
2115 cropRect.setLowerRight(vigra::Point2D(right, bottom));
2116 return true;
2117};
2118
2119bool LensDB::GetFov(const std::string& lens, const double focal, double& fov) const
2120{
2121 if (m_db == NULL)
2122 {
2123 return false;
2124 };
2125 std::vector<Database::HFOVData> hfovdata;
2126 if (!m_db->GetHFOV(lens, focal, hfovdata))
2127 {
2128 return false;
2129 };
2130 fov = 0;
2131 if (hfovdata.size() == 1)
2132 {
2133 // only one entry found
2134 // check focal length
2135 if (fabs(hfovdata[0].focallength - focal) <= 0.075f * focal)
2136 {
2137 // focal length matches
2138 fov = hfovdata[0].HFOV;
2139 }
2140 else
2141 {
2142 // if focal length does not match we ignore HFOV
2143 return false;
2144 }
2145 }
2146 else
2147 {
2148 if (!IsFocallengthNearRange(focal, hfovdata[0].focallength, hfovdata[1].focallength, 0.15f))
2149 {
2150 // difference to nearest point too big, ignoring
2151 return false;
2152 }
2153 fov = InterpolateValue(focal, hfovdata[0].focallength, hfovdata[0].HFOV, hfovdata[1].focallength, hfovdata[1].HFOV);
2154 if (fov < 0.1)
2155 {
2156 fov = 0;
2157 };
2158 };
2159 return (fov > 0);
2160};
2161
2162bool LensDB::GetDistortion(const std::string& lens, const double focal, std::vector<double>& distortion) const
2163{
2164 distortion.clear();
2165 if (m_db == NULL)
2166 {
2167 return false;
2168 };
2169 std::vector<Database::Distortiondata> distdata;
2170 if (!m_db->GetDistortionData(lens, focal, distdata))
2171 {
2172 return false;
2173 };
2174 if (distdata.size() == 1)
2175 {
2176 // only one entry found
2177 // check focal length
2178 if (fabs(distdata[0].focallength - focal) <= 0.075f * focal)
2179 {
2180 distortion.push_back(distdata[0].a);
2181 distortion.push_back(distdata[0].b);
2182 distortion.push_back(distdata[0].c);
2183 return true;
2184 }
2185 else
2186 {
2187 std::cout << "Invalid focallength" << std::endl;
2188 return false;
2189 };
2190 }
2191 else
2192 {
2193 if (!IsFocallengthNearRange(focal, distdata[0].focallength, distdata[1].focallength, 0.15f))
2194 {
2195 // difference to nearest point too big, ignoring
2196 return false;
2197 }
2198 distortion.push_back(InterpolateValue(focal, distdata[0].focallength, distdata[0].a, distdata[1].focallength, distdata[1].a));
2199 distortion.push_back(InterpolateValue(focal, distdata[0].focallength, distdata[0].b, distdata[1].focallength, distdata[1].b));
2200 distortion.push_back(InterpolateValue(focal, distdata[0].focallength, distdata[0].c, distdata[1].focallength, distdata[1].c));
2201 return true;
2202 };
2203};
2204
2205bool LensDB::GetVignetting(const std::string& lens, const double focal, const double aperture, const double distance, std::vector<double>& vignetting) const
2206{
2207 vignetting.clear();
2208 if (m_db == NULL)
2209 {
2210 return false;
2211 };
2212 std::vector<Database::Vignettingdata> vigdata;
2213 if (!m_db->GetVignettingData(lens, focal, aperture, vigdata))
2214 {
2215 return false;
2216 };
2217 const bool unknownAperture = (fabs(aperture) < 0.001f);
2218 if (vigdata.size() == 1)
2219 {
2220 if ((fabs(vigdata[0].focallength - focal) <= 0.075f * focal) && (unknownAperture || fabs(vigdata[0].aperture - aperture) < 0.3f))
2221 {
2222 vignetting.push_back(1.0);
2223 vignetting.push_back(vigdata[0].Vb);
2224 vignetting.push_back(vigdata[0].Vc);
2225 vignetting.push_back(vigdata[0].Vd);
2226 return true;
2227 }
2228 else
2229 {
2230 return false;
2231 }
2232 }
2233 else
2234 {
2235 if (vigdata.size() == 2)
2236 {
2237 if (fabs(vigdata[0].focallength - vigdata[1].focallength) < 0.001f)
2238 {
2239 // variant a: 2 datasets with same focal length
2240 if (unknownAperture)
2241 {
2242 vignetting.push_back(1.0);
2243 vignetting.push_back(vigdata[0].Vb);
2244 vignetting.push_back(vigdata[0].Vc);
2245 vignetting.push_back(vigdata[0].Vd);
2246 return true;
2247 }
2248 else
2249 {
2250 if (vigdata[0].aperture - 0.3 <= aperture && aperture <= vigdata[1].aperture + 0.3)
2251 {
2252 vignetting.push_back(1.0);
2253 vignetting.push_back(InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vb, vigdata[1].aperture, vigdata[1].Vb));
2254 vignetting.push_back(InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vc, vigdata[1].aperture, vigdata[1].Vc));
2255 vignetting.push_back(InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vd, vigdata[1].aperture, vigdata[1].Vd));
2256 return true;
2257 }
2258 else
2259 {
2260 return false;
2261 };
2262 };
2263 }
2264 else
2265 {
2266 // variant b: 2 datasets from different focal length
2267 if (!IsFocallengthNearRange(focal, vigdata[0].focallength, vigdata[1].focallength, 0.15f))
2268 {
2269 return false;
2270 };
2271 const double interpolatedAperture = InterpolateValue(focal, vigdata[0].focallength, vigdata[0].aperture, vigdata[1].focallength, vigdata[1].aperture);
2272 if (fabs(interpolatedAperture - aperture) < 0.3f || unknownAperture)
2273 {
2274 // return value only, if aperture matches the 2 found values
2275 vignetting.push_back(1.0);
2276 vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vb, vigdata[1].focallength, vigdata[1].Vb));
2277 vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vc, vigdata[1].focallength, vigdata[1].Vc));
2278 vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vd, vigdata[1].focallength, vigdata[1].Vd));
2279 return true;
2280 }
2281 else
2282 {
2283 return false;
2284 };
2285 };
2286 }
2287 else
2288 {
2289 if (vigdata.size() == 3)
2290 {
2291 if (!IsFocallengthNearRange(focal, vigdata[0].focallength, vigdata[2].focallength, 0.15f))
2292 {
2293 return false;
2294 };
2295 vignetting.push_back(1.0);
2296 vignetting.push_back(InterpolateValueTriangle(focal, aperture,
2297 vigdata[0].focallength, vigdata[0].aperture, vigdata[0].Vb,
2298 vigdata[1].focallength, vigdata[1].aperture, vigdata[1].Vb,
2299 vigdata[2].focallength, vigdata[2].aperture, vigdata[2].Vb
2300 ));
2301 vignetting.push_back(InterpolateValueTriangle(focal, aperture,
2302 vigdata[0].focallength, vigdata[0].aperture, vigdata[0].Vc,
2303 vigdata[1].focallength, vigdata[1].aperture, vigdata[1].Vc,
2304 vigdata[2].focallength, vigdata[2].aperture, vigdata[2].Vc
2305 ));
2306 vignetting.push_back(InterpolateValueTriangle(focal, aperture,
2307 vigdata[0].focallength, vigdata[0].aperture, vigdata[0].Vd,
2308 vigdata[1].focallength, vigdata[1].aperture, vigdata[1].Vd,
2309 vigdata[2].focallength, vigdata[2].aperture, vigdata[2].Vd
2310 ));
2311 return true;
2312 }
2313 else
2314 {
2315 // we have now 4 points for interpolation
2316 if (!IsFocallengthNearRange(focal, vigdata[0].focallength, vigdata[2].focallength, 0.15f))
2317 {
2318 return false;
2319 };
2320 if (unknownAperture)
2321 {
2322 // unknown aperture, take smallest aperture
2323 vignetting.push_back(1.0);
2324 vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vb, vigdata[2].focallength, vigdata[2].Vb));
2325 vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vc, vigdata[2].focallength, vigdata[2].Vc));
2326 vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vd, vigdata[2].focallength, vigdata[2].Vd));
2327 return true;
2328 }
2329 else
2330 {
2331 // interpolate for each focal length to desired aperture
2332 double Vb1, Vc1, Vd1, Vb2, Vc2, Vd2;
2333 if (vigdata[0].aperture - 0.3 <= aperture && aperture <= vigdata[1].aperture + 0.3)
2334 {
2335 Vb1 = InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vb, vigdata[1].aperture, vigdata[1].Vb);
2336 Vc1 = InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vc, vigdata[1].aperture, vigdata[1].Vc);
2337 Vd1 = InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vd, vigdata[1].aperture, vigdata[1].Vd);
2338 }
2339 else
2340 {
2341 return false;
2342 };
2343 if (vigdata[2].aperture - 0.3 <= aperture && aperture <= vigdata[3].aperture + 0.3)
2344 {
2345 Vb2 = InterpolateValue(aperture, vigdata[2].aperture, vigdata[2].Vb, vigdata[3].aperture, vigdata[3].Vb);
2346 Vc2 = InterpolateValue(aperture, vigdata[2].aperture, vigdata[2].Vc, vigdata[3].aperture, vigdata[3].Vc);
2347 Vd2 = InterpolateValue(aperture, vigdata[2].aperture, vigdata[2].Vd, vigdata[3].aperture, vigdata[3].Vd);
2348 }
2349 else
2350 {
2351 return false;
2352 };
2353 // now we have 2 values for the same aperture, but different focal length
2354 // interpolate focal length
2355 vignetting.push_back(1.0);
2356 vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, Vb1, vigdata[2].focallength, Vb2));
2357 vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, Vc1, vigdata[2].focallength, Vc2));
2358 vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, Vd1, vigdata[2].focallength, Vd2));
2359 return true;
2360 };
2361 };
2362 };
2363 };
2364};
2365
2366bool LensDB::GetTCA(const std::string& lens, const double focal, std::vector<double>& tca_red, std::vector<double>& tca_blue) const
2367{
2368 tca_red.clear();
2369 tca_blue.clear();
2370 if (m_db == NULL)
2371 {
2372 return false;
2373 };
2374 std::vector<Database::TCAdata> tcadata;
2375 if (!m_db->GetTCAData(lens, focal, tcadata))
2376 {
2377 return false;
2378 };
2379 if (tcadata.size() == 1)
2380 {
2381 // only one entry found
2382 // check focal length
2383 if (fabs(tcadata[0].focallength - focal) <= 0.075f * focal)
2384 {
2385 tca_red.push_back(tcadata[0].ra);
2386 tca_red.push_back(tcadata[0].rb);
2387 tca_red.push_back(tcadata[0].rc);
2388 tca_red.push_back(tcadata[0].rd);
2389 tca_blue.push_back(tcadata[0].ba);
2390 tca_blue.push_back(tcadata[0].bb);
2391 tca_blue.push_back(tcadata[0].bc);
2392 tca_blue.push_back(tcadata[0].bd);
2393 return true;
2394 }
2395 else
2396 {
2397 return false;
2398 };
2399 }
2400 else
2401 {
2402 if (!IsFocallengthNearRange(focal, tcadata[0].focallength, tcadata[1].focallength, 0.15f))
2403 {
2404 // difference to nearest point too big, ignoring
2405 return false;
2406 };
2407 tca_red.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].ra, tcadata[1].focallength, tcadata[1].ra));
2408 tca_red.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].rb, tcadata[1].focallength, tcadata[1].rb));
2409 tca_red.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].rc, tcadata[1].focallength, tcadata[1].rc));
2410 tca_red.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].rd, tcadata[1].focallength, tcadata[1].rd));
2411 tca_blue.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].ba, tcadata[1].focallength, tcadata[1].ba));
2412 tca_blue.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].bb, tcadata[1].focallength, tcadata[1].bb));
2413 tca_blue.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].bc, tcadata[1].focallength, tcadata[1].bc));
2414 tca_blue.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].bd, tcadata[1].focallength, tcadata[1].bd));
2415 return true;
2416 };
2417};
2418
2419bool LensDB::GetLensNames(const bool distortion, const bool vignetting, const bool tca, LensList& lensList) const
2420{
2421 lensList.clear();
2422 if (m_db == NULL)
2423 {
2424 return false;
2425 };
2427};
2428
2429bool LensDB::SaveCameraCrop(const std::string& maker, const std::string& model, const double cropfactor)
2430{
2431 if (m_db == NULL)
2432 {
2433 return false;
2434 };
2435 return m_db->SaveCropFactor(maker, model, cropfactor);
2436};
2437
2438bool LensDB::SaveEMoR(const std::string& maker, const std::string& model, const int iso, const std::vector<float>& emor, const int weight)
2439{
2440 if (m_db == NULL || emor.size() != 5)
2441 {
2442 return false;
2443 };
2444 return m_db->SaveEMoR(maker, model, iso, emor[0], emor[1], emor[2], emor[3], emor[4], weight);
2445};
2446
2447bool LensDB::SaveLensProjection(const std::string& lens, const BaseSrcPanoImage::Projection projection)
2448{
2449 if (m_db == NULL)
2450 {
2451 return false;
2452 };
2453 return m_db->SaveLensProjection(lens, projection);
2454};
2455
2456bool LensDB::SaveLensCrop(const std::string& lens, const double focal, const vigra::Size2D& imageSize, const vigra::Rect2D& cropRect)
2457{
2458 if (m_db == NULL)
2459 {
2460 return false;
2461 };
2462 if (cropRect.isEmpty())
2463 {
2464 return m_db->RemoveLensCrop(lens, focal, imageSize.width(), imageSize.height());
2465 }
2466 else
2467 {
2468 return m_db->SaveLensCrop(lens, focal, imageSize.width(), imageSize.height(), cropRect.left(), cropRect.right(), cropRect.top(), cropRect.bottom());
2469 };
2470};
2471
2472bool LensDB::SaveLensFov(const std::string& lens, const double focal, const double fov, const int weight)
2473{
2474 if (m_db == NULL)
2475 {
2476 return false;
2477 };
2478 return m_db->SaveHFOV(lens, focal, fov, weight);
2479};
2480
2481bool LensDB::SaveDistortion(const std::string& lens, const double focal, const std::vector<double>& distortion, const int weight)
2482{
2483 if (m_db == NULL || distortion.size()!=4)
2484 {
2485 return false;
2486 };
2487 return m_db->SaveDistortion(lens, focal, distortion[0], distortion[1], distortion[2], weight);
2488};
2489
2490bool LensDB::SaveVignetting(const std::string& lens, const double focal, const double aperture, const double distance, const std::vector<double>& vignetting, const int weight)
2491{
2492 if (m_db == NULL || vignetting.size()!=4)
2493 {
2494 return false;
2495 };
2496 return m_db->SaveVignetting(lens, focal, aperture, distance, vignetting[1], vignetting[2], vignetting[3], weight);
2497};
2498
2499bool LensDB::SaveTCA(const std::string& lens, const double focal, const std::vector<double>& tca_red, const std::vector<double>& tca_blue, const int weight)
2500{
2501 if (m_db == NULL || tca_red.size()!=4 || tca_blue.size()!=4)
2502 {
2503 return false;
2504 };
2505 return m_db->SaveTCAData(lens, focal, tca_red[0], tca_red[1], tca_red[2], tca_red[3], tca_blue[0], tca_blue[1], tca_blue[2], tca_blue[3], weight);
2506};
2507
2509{
2510 if (m_db == NULL)
2511 {
2512 return false;
2513 };
2514 return m_db->CleanUp();
2515};
2516
2517bool LensDB::RemoveLens(const std::string& lensname)
2518{
2519 if (m_db == NULL)
2520 {
2521 return false;
2522 };
2523 return m_db->RemoveLens(lensname);
2524};
2525
2526bool LensDB::RemoveCamera(const std::string& maker, const std::string& model)
2527{
2528 if (m_db == NULL)
2529 {
2530 return false;
2531 };
2532 return m_db->RemoveCamera(maker, model);
2533};
2534
2535bool LensDB::ExportToFile(const std::string& filename)
2536{
2537 if (m_db == NULL)
2538 {
2539 return false;
2540 };
2541 return m_db->ExportToFile(filename);
2542};
2543
2544bool LensDB::ImportFromFile(const std::string& filename)
2545{
2546 if (m_db == NULL)
2547 {
2548 return false;
2549 };
2550 return m_db->ImportFromFile(filename);
2551};
2552
2554{
2555 if (pano.getNrOfImages() < 2)
2556 {
2557 // ignore project with only one image
2558 return false;
2559 };
2561 if (lenses.getLenses().getNumberOfParts() == 1)
2562 {
2563 const SrcPanoImage& img0 = pano.getImage(0);
2564 // if the HFOV for a rectilinear lens is too big, ignore this settings
2565 if (img0.getProjection() == BaseSrcPanoImage::RECTILINEAR && img0.getHFOV() > 110)
2566 {
2567 return false;
2568 };
2570 const std::string camMaker = img0.getExifMake();
2571 const std::string camModel = img0.getExifModel();
2572 if (!camMaker.empty() && !camModel.empty())
2573 {
2574 if (img0.getExifCropFactor() < 0.1f)
2575 {
2576 double cropFactor = img0.getCropFactor();
2577 if (cropFactor == 1 && img0.getExifFocalLength() > 0)
2578 {
2579 // a cropfactor of 1 can also mean unknown crop factor
2580 // so recalculate crop factor with HFOV and EXIF focal length
2581 cropFactor = HuginBase::SrcPanoImage::calcCropFactor(img0.getProjection(), img0.getHFOV(), img0.getExifFocalLength(), img0.getSize());
2582 if (std::abs(cropFactor - 1) < 0.1)
2583 {
2584 cropFactor = 1;
2585 };
2586 };
2587 lensDB.SaveCameraCrop(camMaker, camModel, cropFactor);
2588 };
2589 // now check EMoR parameters
2590 const std::vector<float> emor=img0.getEMoRParams();
2591 if (emor.size() == 5)
2592 {
2593 float sum = 0;
2594 for (size_t i = 0; i < 5; ++i)
2595 {
2596 sum += fabs(emor[i]);
2597 };
2598 if (sum>0.001)
2599 {
2600 lensDB.SaveEMoR(camMaker, camModel, img0.getExifISO(), emor);
2601 };
2602 };
2603 };
2604 const std::string lensname = img0.getDBLensName();
2605 const double focal = img0.getExifFocalLength();
2606 if (!lensname.empty() && focal > 0)
2607 {
2608 bool success = lensDB.SaveLensProjection(lensname, img0.getProjection());
2609 if (img0.getCropMode() == BaseSrcPanoImage::NO_CROP)
2610 {
2611 // pass empty Rect2D to remove crop information
2612 success = success | lensDB.SaveLensCrop(lensname, focal, img0.getSize(), vigra::Rect2D(0, 0, 0, 0));
2613 }
2614 else
2615 {
2616 const BaseSrcPanoImage::CropMode cropMode = img0.getCropMode();
2617 const vigra::Rect2D cropRect = img0.getCropRect();
2618 bool sameCrop = true;
2619 for (size_t i = 1; i < pano.getNrOfImages() && sameCrop; ++i)
2620 {
2621 const SrcPanoImage& img = pano.getImage(i);
2622 sameCrop = (img.getCropMode() == cropMode) && (img.getCropRect() == cropRect);
2623 };
2624 if (sameCrop)
2625 {
2626 success = success | lensDB.SaveLensCrop(lensname, focal, img0.getSize(), cropRect);
2627 };
2628 };
2629 double min;
2630 double max;
2631 double mean;
2632 double var;
2633 // update cp errors
2635 if (pano.getNrOfCtrlPoints() > 3 * pano.getNrOfImages() && mean < 15)
2636 {
2637 // save hfov and distortion only if error is small enough
2638 //@TODO add more robust check which takes also distribution of cp into account
2639 // recalculate to default aspect ratio of 3:2
2640 const double newFocallength = SrcPanoImage::calcFocalLength(img0.getProjection(), img0.getHFOV(), img0.getCropFactor(), img0.getSize());
2641 const double newHFOV = SrcPanoImage::calcHFOV(img0.getProjection(), newFocallength, img0.getCropFactor(), vigra::Size2D(3000, 2000));
2642 success = success | lensDB.SaveLensFov(lensname, focal, newHFOV);
2643 const std::vector<double> dist = img0.getRadialDistortion();
2644 if (dist.size() == 4)
2645 {
2646 // check if values are plausible
2647 if (fabs(dist[0]) + fabs(dist[1]) + fabs(dist[2])>0.001 &&
2648 fabs(dist[0] + dist[1] + dist[2]) < 0.1)
2649 {
2650 success = success | lensDB.SaveDistortion(lensname, focal, dist);
2651 };
2652 };
2653 };
2654 // check if aperture matches for all images
2655 bool sameAperture = true;
2656 for (size_t i = 1; i < pano.getNrOfImages() && sameAperture; ++i)
2657 {
2658 sameAperture = fabs(pano.getImage(i).getExifAperture() - img0.getExifAperture()) < 0.05;
2659 }
2660 // save vignetting data only if all images were shoot with same aperture
2661 if (sameAperture)
2662 {
2663 const std::vector<double> vigParam = img0.getRadialVigCorrCoeff();
2664 if (vigParam.size() == 4)
2665 {
2666 // now check, if the vignetting parameter are plausible
2667 const double sum = vigParam[0] + vigParam[1] + vigParam[2] + vigParam[3];
2668 if (sum>0.5 && sum <= 1.01)
2669 {
2670 success = success | lensDB.SaveVignetting(lensname, focal, img0.getExifAperture(), img0.getExifDistance(), vigParam);
2671 };
2672 };
2673 };
2674 return success;
2675 }
2676 else
2677 {
2678 return false;
2679 };
2680 };
2681 return false;
2682};
2683
2684} //namespace LensDB
2685} //namespace HuginBase
class to access Hugins camera and lens database
Somewhere to specify what variables belong to what.
static void calcCtrlPntsErrorStats(const PanoramaData &pano, double &min, double &max, double &mean, double &var, const int &imgNr=-1, const bool onlyActive=false, const bool ignoreLineCp=false)
Make an ImageVariableGroup for lenses and other common concepts.
void OutputSQLToStream(const std::string &sqlstatement, std::ostream &stream)
Definition LensDB.cpp:1049
bool SaveCropFactor(const std::string &maker, const std::string &model, const double cropFactor)
Definition LensDB.cpp:209
bool ImportFromFile(const std::string &filename)
Definition LensDB.cpp:841
bool ImportVignetting(std::istream &input)
Definition LensDB.cpp:1519
bool GetHFOV(const std::string &lens, const double focallength, std::vector< HFOVData > &hfovData) const
Definition LensDB.cpp:303
bool ImportHFOV(std::istream &input)
Definition LensDB.cpp:1203
bool ImportTCA(std::istream &input)
Definition LensDB.cpp:1646
bool ImportEMOR(std::istream &input)
Definition LensDB.cpp:1806
bool RemoveLens(const std::string &lensname)
Definition LensDB.cpp:759
bool ExportToFile(const std::string &filename)
Definition LensDB.cpp:789
bool GetLensNames(const bool distortion, const bool vignetting, const bool tca, LensList &lensList) const
Definition LensDB.cpp:676
bool GetLensProjection(const std::string &lens, int &projection) const
Definition LensDB.cpp:248
bool ImportLensCrop(std::istream &input)
Definition LensDB.cpp:1287
bool ImportProjection(std::istream &input)
Definition LensDB.cpp:1144
bool RemoveLensCrop(const std::string &lens, const double focal, const int width, const int height)
Definition LensDB.cpp:430
std::string GetDBFilename() const
Definition LensDB.cpp:176
bool GetDistortionData(const std::string &lens, const double focallength, std::vector< Distortiondata > &distData) const
Definition LensDB.cpp:455
bool RemoveCameraFromTable(const std::string &table, const std::string &maker, const std::string &model)
Definition LensDB.cpp:1031
Database(const std::string &filename)
Definition LensDB.cpp:77
bool GetTCAData(const std::string &lens, const double focallength, std::vector< TCAdata > &tcaData) const
Definition LensDB.cpp:587
bool GetCropFactor(const std::string &maker, const std::string &model, double &cropFactor) const
Definition LensDB.cpp:182
bool SaveLensProjection(const std::string &lens, const int projection)
Definition LensDB.cpp:270
bool SaveLensCrop(const std::string &lens, const double focal, const int width, const int height, const int left, const int right, const int top, const int bottom)
Definition LensDB.cpp:387
bool ImportCropFactor(std::istream &input)
Definition LensDB.cpp:1075
bool GetLensCrop(const std::string &lens, const double focal, const int width, const int height, std::vector< CropData > &cropData) const
Definition LensDB.cpp:356
bool SaveHFOV(const std::string &lens, const double focallength, const double HFOV, const int weight=10)
Definition LensDB.cpp:329
bool SaveTCAData(const std::string &lens, const double focallength, const double ra, const double rb, const double rc, const double rd, const double ba, const double bb, const double bc, const double bd, const int weight=10)
Definition LensDB.cpp:620
bool RemoveCamera(const std::string &maker, const std::string &model)
Definition LensDB.cpp:776
bool SaveDistortion(const std::string &lens, const double focallength, const double a, const double b, const double c, const int weight=10)
Definition LensDB.cpp:483
bool ImportDistortion(std::istream &input)
Definition LensDB.cpp:1414
bool RemoveLensFromTable(const std::string &table, const std::string &lens)
Definition LensDB.cpp:1014
bool SaveEMoR(const std::string &maker, const std::string &model, const int iso, const double Ra, const double Rb, const double Rc, const double Rd, const double Re, const int weight=10)
Definition LensDB.cpp:650
bool GetVignettingData(const std::string &lens, const double focallength, const double aperture, std::vector< Vignettingdata > &vigData) const
Definition LensDB.cpp:508
bool SaveVignetting(const std::string &lens, const double focallength, const double aperture, const double distance, const double Vb, const double Vc, const double Vd, const int weight=10)
Definition LensDB.cpp:560
main database class
Definition LensDB.h:45
virtual ~LensDB()
destructor
Definition LensDB.cpp:1995
bool CleanUpDatabase()
compress database by remove all entries and insert instead the average values
Definition LensDB.cpp:2508
bool RemoveCamera(const std::string &maker, const std::string &model)
remove all database entry which refers to given camera
Definition LensDB.cpp:2526
bool SaveEMoR(const std::string &maker, const std::string &model, const int iso, const std::vector< float > &emor, const int weight=10)
save the camera with the given EMoR parameters into the database
Definition LensDB.cpp:2438
bool SaveTCA(const std::string &lens, const double focal, const std::vector< double > &tca_red, const std::vector< double > &tca_blue, const int weight=10)
saves the tca distortion parameters of the lens
Definition LensDB.cpp:2499
bool GetLensNames(const bool distortion, const bool vignetting, const bool tca, LensList &lensList) const
return a vector of lenses with selected database entries
Definition LensDB.cpp:2419
static void Clean()
cleanup the static LensDB instance, must be called at the end of the program
Definition LensDB.cpp:2010
bool SaveLensFov(const std::string &lens, const double focal, const double fov, const int weight=10)
saves the field of view of the lens the fov should always calculated for a landscape image with aspec...
Definition LensDB.cpp:2472
bool SaveVignetting(const std::string &lens, const double focal, const double aperture, const double distance, const std::vector< double > &vignetting, const int weight=10)
saves the vignetting parameters of the lens
Definition LensDB.cpp:2490
bool SaveDistortion(const std::string &lens, const double focal, const std::vector< double > &distortion, const int weight=10)
saves the distortion parameters of the lens in the database
Definition LensDB.cpp:2481
bool GetVignetting(const std::string &lens, const double focal, const double aperture, const double distance, std::vector< double > &vignetting) const
returns the vignetting parameters of the lens
Definition LensDB.cpp:2205
bool GetCrop(const std::string &lens, const double focal, const vigra::Size2D &imageSize, vigra::Rect2D &cropRect) const
returns the crop of the lens the information for landscape and portrait images are stored separately
Definition LensDB.cpp:2073
bool GetTCA(const std::string &lens, const double focal, std::vector< double > &tca_red, std::vector< double > &tca_blue) const
returns the tca distortion parameters of the lens
Definition LensDB.cpp:2366
bool GetDistortion(const std::string &lens, const double focal, std::vector< double > &distortion) const
returns the distortion parameters of the lens
Definition LensDB.cpp:2162
bool SaveLensCrop(const std::string &lens, const double focal, const vigra::Size2D &imageSize, const vigra::Rect2D &cropRect)
saves the crop information of the lens in the database the information for landscape and portrait ima...
Definition LensDB.cpp:2456
bool SaveCameraCrop(const std::string &maker, const std::string &model, const double cropfactor)
save the camera with the given cropfactor into the database
Definition LensDB.cpp:2429
static LensDB & GetSingleton()
returns the static LensDB instance
Definition LensDB.cpp:2001
bool GetCropFactor(const std::string &maker, const std::string &model, double &cropFactor) const
returns the crop factor for the given camera (maker/model)
Definition LensDB.cpp:2031
bool ImportFromFile(const std::string &filename)
import data from external file
Definition LensDB.cpp:2544
bool SaveLensProjection(const std::string &lens, const BaseSrcPanoImage::Projection projection)
saves the projection for the lens in the database
Definition LensDB.cpp:2447
std::string GetDBFilename() const
returns the filename of the lens database
Definition LensDB.cpp:2019
bool GetFov(const std::string &lens, const double focal, double &fov) const
returns the field of view of the lens the fov is always returned for a landscape image with aspect ra...
Definition LensDB.cpp:2119
static LensDB * m_instance
Definition LensDB.h:195
bool GetProjection(const std::string &lens, BaseSrcPanoImage::Projection &projection) const
returns the projection of the lens
Definition LensDB.cpp:2040
bool RemoveLens(const std::string &lensname)
remove all database entry which refers to given lens
Definition LensDB.cpp:2517
bool ExportToFile(const std::string &filename)
export database to file
Definition LensDB.cpp:2535
Model for a panorama.
Definition Panorama.h:153
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition Panorama.h:211
std::size_t getNrOfCtrlPoints() const
number of control points
Definition Panorama.h:306
std::size_t getNrOfImages() const
number of images.
Definition Panorama.h:205
All variables of a source image.
static double calcFocalLength(SrcPanoImage::Projection proj, double hfov, double crop, vigra::Size2D imageSize)
calcualte focal length, given crop factor and hfov
static double calcHFOV(SrcPanoImage::Projection proj, double fl, double crop, vigra::Size2D imageSize)
calculate hfov of an image given focal length, image size and crop factor
static double calcCropFactor(SrcPanoImage::Projection proj, double hfov, double focalLength, vigra::Size2D imageSize)
calculate crop factor, given focal length and hfov
double HFOV
double InterpolateValueTriangle(double x, double y, double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3)
Definition LensDB.cpp:1958
std::vector< std::string > LensList
vector storing a list of lens names
Definition LensDB.h:41
bool SaveLensDataFromPano(const HuginBase::Panorama &pano)
routine for automatically saving information from pano into database
Definition LensDB.cpp:2553
int fsign(double a)
Definition LensDB.cpp:2058
double InterpolateValue(double x, double x0, double y0, double x1, double y1)
Definition LensDB.cpp:1948
bool IsFocallengthNearRange(const double focal, const double limit1, const double limit2, const double tol)
check if value is inside limit1...limit2 or it is nearer to limit1 than value*tol
Definition LensDB.cpp:2064
mainly consists of wrapper around the pano tools library, to assist in ressource management and to pr...
Definition wxcms.cpp:39
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
std::string GetUserAppDataDir()
returns the directory for user specific Hugin settings, e.g.
Definition utils.cpp:497
int roundi(T x)
Definition hugin_math.h:73
bool FileExists(const std::string &filename)
checks if file exists
Definition utils.cpp:362
bool stringToDouble(const STR &str_, double &dest)
convert a string to a double, ignore localisation.
Definition utils.h:114
bool stringToInt(const std::string &s, int &val)
convert string to integer value, returns true, if sucessful
Definition utils.cpp:264
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41