38 #include "util/version.h"
43 typedef Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
45 typedef Eigen::Matrix<uint8_t, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
46 FeatureDescriptorsBlob;
47 typedef Eigen::Matrix<point2D_t, Eigen::Dynamic, 2, Eigen::RowMajor>
50 void SwapFeatureMatchesBlob(FeatureMatchesBlob* matches) {
51 matches->col(0).swap(matches->col(1));
54 FeatureKeypointsBlob FeatureKeypointsToBlob(
const FeatureKeypoints& keypoints) {
56 FeatureKeypointsBlob blob(keypoints.size(), kNumCols);
57 for (
size_t i = 0; i < keypoints.size(); ++i) {
58 blob(i, 0) = keypoints[i].x;
59 blob(i, 1) = keypoints[i].y;
60 blob(i, 2) = keypoints[i].a11;
61 blob(i, 3) = keypoints[i].a12;
62 blob(i, 4) = keypoints[i].a21;
63 blob(i, 5) = keypoints[i].a22;
68 FeatureKeypoints FeatureKeypointsFromBlob(
const FeatureKeypointsBlob& blob) {
70 if (blob.cols() == 2) {
72 keypoints[i] = FeatureKeypoint(blob(i, 0), blob(i, 1));
74 }
else if (blob.cols() == 4) {
77 FeatureKeypoint(blob(i, 0), blob(i, 1), blob(i, 2), blob(i, 3));
79 }
else if (blob.cols() == 6) {
81 keypoints[i] = FeatureKeypoint(blob(i, 0), blob(i, 1), blob(i, 2),
82 blob(i, 3), blob(i, 4), blob(i, 5));
85 LOG(FATAL) <<
"Keypoint format not supported";
90 FeatureMatchesBlob FeatureMatchesToBlob(
const FeatureMatches& matches) {
92 FeatureMatchesBlob blob(matches.size(), kNumCols);
93 for (
size_t i = 0; i < matches.size(); ++i) {
94 blob(i, 0) = matches[i].point2D_idx1;
95 blob(i, 1) = matches[i].point2D_idx2;
100 FeatureMatches FeatureMatchesFromBlob(
const FeatureMatchesBlob& blob) {
101 CHECK_EQ(blob.cols(), 2);
104 matches[i].point2D_idx1 = blob(i, 0);
105 matches[i].point2D_idx2 = blob(i, 1);
110 template <
typename MatrixType>
111 MatrixType ReadStaticMatrixBlob(sqlite3_stmt* sql_stmt,
const int rc,
117 if (rc == SQLITE_ROW) {
118 const size_t num_bytes =
119 static_cast<size_t>(sqlite3_column_bytes(sql_stmt, col));
121 CHECK_EQ(num_bytes, matrix.size() *
sizeof(
typename MatrixType::Scalar));
122 memcpy(
reinterpret_cast<char*
>(matrix.data()),
123 sqlite3_column_blob(sql_stmt, col), num_bytes);
125 matrix = MatrixType::Zero();
128 matrix = MatrixType::Zero();
134 template <
typename MatrixType>
135 MatrixType ReadDynamicMatrixBlob(sqlite3_stmt* sql_stmt,
const int rc,
141 if (rc == SQLITE_ROW) {
143 static_cast<size_t>(sqlite3_column_int64(sql_stmt, col + 0));
145 static_cast<size_t>(sqlite3_column_int64(sql_stmt, col + 1));
149 matrix = MatrixType(rows, cols);
151 const size_t num_bytes =
152 static_cast<size_t>(sqlite3_column_bytes(sql_stmt, col + 2));
153 CHECK_EQ(matrix.size() *
sizeof(
typename MatrixType::Scalar), num_bytes);
155 memcpy(
reinterpret_cast<char*
>(matrix.data()),
156 sqlite3_column_blob(sql_stmt, col + 2), num_bytes);
159 (MatrixType::RowsAtCompileTime == Eigen::Dynamic)
161 : MatrixType::RowsAtCompileTime;
163 (MatrixType::ColsAtCompileTime == Eigen::Dynamic)
165 : MatrixType::ColsAtCompileTime;
166 matrix = MatrixType(rows, cols);
172 template <
typename MatrixType>
173 void WriteStaticMatrixBlob(sqlite3_stmt* sql_stmt,
const MatrixType& matrix,
176 sql_stmt, col,
reinterpret_cast<const char*
>(matrix.data()),
177 static_cast<int>(matrix.size() *
sizeof(
typename MatrixType::Scalar)),
181 template <
typename MatrixType>
182 void WriteDynamicMatrixBlob(sqlite3_stmt* sql_stmt,
const MatrixType& matrix,
184 CHECK_GE(matrix.rows(), 0);
185 CHECK_GE(matrix.cols(), 0);
188 const size_t num_bytes = matrix.size() *
sizeof(
typename MatrixType::Scalar);
189 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt, col + 0, matrix.rows()));
190 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt, col + 1, matrix.cols()));
192 reinterpret_cast<const char*
>(matrix.data()),
193 static_cast<int>(num_bytes), SQLITE_STATIC));
196 Camera ReadCameraRow(sqlite3_stmt* sql_stmt) {
199 camera.SetCameraId(
static_cast<camera_t>(sqlite3_column_int64(sql_stmt, 0)));
200 camera.SetModelId(sqlite3_column_int64(sql_stmt, 1));
201 camera.SetWidth(
static_cast<size_t>(sqlite3_column_int64(sql_stmt, 2)));
202 camera.SetHeight(
static_cast<size_t>(sqlite3_column_int64(sql_stmt, 3)));
204 const size_t num_params_bytes =
205 static_cast<size_t>(sqlite3_column_bytes(sql_stmt, 4));
206 const size_t num_params = num_params_bytes /
sizeof(double);
207 CHECK_EQ(num_params, camera.NumParams());
208 memcpy(camera.ParamsData(), sqlite3_column_blob(sql_stmt, 4),
211 camera.SetPriorFocalLength(sqlite3_column_int64(sql_stmt, 5) != 0);
216 Image ReadImageRow(sqlite3_stmt* sql_stmt) {
219 image.SetImageId(
static_cast<image_t>(sqlite3_column_int64(sql_stmt, 0)));
220 image.SetName(std::string(
221 reinterpret_cast<const char*
>(sqlite3_column_text(sql_stmt, 1))));
222 image.SetCameraId(
static_cast<camera_t>(sqlite3_column_int64(sql_stmt, 2)));
225 for (
size_t i = 0; i < 4; ++i) {
226 if (sqlite3_column_type(sql_stmt, i + 3) != SQLITE_NULL) {
227 image.QvecPrior(i) = sqlite3_column_double(sql_stmt, i + 3);
232 for (
size_t i = 0; i < 3; ++i) {
233 if (sqlite3_column_type(sql_stmt, i + 7) != SQLITE_NULL) {
234 image.TvecPrior(i) = sqlite3_column_double(sql_stmt, i + 7);
244 static_cast<size_t>(std::numeric_limits<int32_t>::max());
246 std::mutex Database::update_schema_mutex_;
262 path.c_str(), &database_,
263 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX,
267 SQLITE3_EXEC(database_,
"PRAGMA synchronous=OFF",
nullptr);
270 SQLITE3_EXEC(database_,
"PRAGMA journal_mode=WAL",
nullptr);
273 SQLITE3_EXEC(database_,
"PRAGMA temp_store=MEMORY",
nullptr);
276 SQLITE3_EXEC(database_,
"PRAGMA foreign_keys=ON",
nullptr);
279 SQLITE3_EXEC(database_,
"PRAGMA auto_vacuum=1",
nullptr);
283 PrepareSQLStatements();
287 if (database_ !=
nullptr) {
288 FinalizeSQLStatements();
290 sqlite3_close_v2(database_);
296 return ExistsRowId(sql_stmt_exists_camera_, camera_id);
300 return ExistsRowId(sql_stmt_exists_image_id_, image_id);
304 return ExistsRowString(sql_stmt_exists_image_name_,
name);
308 return ExistsRowId(sql_stmt_exists_keypoints_, image_id);
312 return ExistsRowId(sql_stmt_exists_descriptors_, image_id);
316 const image_t image_id2)
const {
317 return ExistsRowId(sql_stmt_exists_matches_,
322 const image_t image_id2)
const {
323 return ExistsRowId(sql_stmt_exists_two_view_geometry_,
334 return MaxColumn(
"rows",
"keypoints");
338 return CountRowsForEntry(sql_stmt_num_keypoints_, image_id);
342 return SumColumn(
"rows",
"descriptors");
346 return MaxColumn(
"rows",
"descriptors");
350 return CountRowsForEntry(sql_stmt_num_descriptors_, image_id);
356 return SumColumn(
"rows",
"two_view_geometries");
362 return CountRows(
"two_view_geometries");
366 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_read_camera_, 1, camera_id));
370 const int rc =
SQLITE3_CALL(sqlite3_step(sql_stmt_read_camera_));
371 if (rc == SQLITE_ROW) {
372 camera = ReadCameraRow(sql_stmt_read_camera_);
381 std::vector<Camera> cameras;
383 while (
SQLITE3_CALL(sqlite3_step(sql_stmt_read_cameras_)) == SQLITE_ROW) {
384 cameras.push_back(ReadCameraRow(sql_stmt_read_cameras_));
393 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_read_image_id_, 1, image_id));
397 const int rc =
SQLITE3_CALL(sqlite3_step(sql_stmt_read_image_id_));
398 if (rc == SQLITE_ROW) {
399 image = ReadImageRow(sql_stmt_read_image_id_);
409 static_cast<int>(
name.size()), SQLITE_STATIC));
413 const int rc =
SQLITE3_CALL(sqlite3_step(sql_stmt_read_image_name_));
414 if (rc == SQLITE_ROW) {
415 image = ReadImageRow(sql_stmt_read_image_name_);
424 std::vector<Image> images;
427 while (
SQLITE3_CALL(sqlite3_step(sql_stmt_read_images_)) == SQLITE_ROW) {
428 images.push_back(ReadImageRow(sql_stmt_read_images_));
437 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_read_keypoints_, 1, image_id));
439 const int rc =
SQLITE3_CALL(sqlite3_step(sql_stmt_read_keypoints_));
440 const FeatureKeypointsBlob blob = ReadDynamicMatrixBlob<FeatureKeypointsBlob>(
441 sql_stmt_read_keypoints_, rc, 0);
445 return FeatureKeypointsFromBlob(blob);
449 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_read_descriptors_, 1, image_id));
451 const int rc =
SQLITE3_CALL(sqlite3_step(sql_stmt_read_descriptors_));
453 ReadDynamicMatrixBlob<FeatureDescriptors>(sql_stmt_read_descriptors_, rc,
456 SQLITE3_CALL(sqlite3_reset(sql_stmt_read_descriptors_));
464 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_read_matches_, 1, pair_id));
466 const int rc =
SQLITE3_CALL(sqlite3_step(sql_stmt_read_matches_));
467 FeatureMatchesBlob blob =
468 ReadDynamicMatrixBlob<FeatureMatchesBlob>(sql_stmt_read_matches_, rc, 0);
473 SwapFeatureMatchesBlob(&blob);
476 return FeatureMatchesFromBlob(blob);
481 std::vector<std::pair<image_pair_t, FeatureMatches>> all_matches;
484 while ((rc =
SQLITE3_CALL(sqlite3_step(sql_stmt_read_matches_all_))) ==
487 sqlite3_column_int64(sql_stmt_read_matches_all_, 0));
488 const FeatureMatchesBlob blob = ReadDynamicMatrixBlob<FeatureMatchesBlob>(
489 sql_stmt_read_matches_all_, rc, 1);
490 all_matches.emplace_back(pair_id, FeatureMatchesFromBlob(blob));
493 SQLITE3_CALL(sqlite3_reset(sql_stmt_read_matches_all_));
499 const image_t image_id2)
const {
502 sqlite3_bind_int64(sql_stmt_read_two_view_geometry_, 1, pair_id));
504 const int rc =
SQLITE3_CALL(sqlite3_step(sql_stmt_read_two_view_geometry_));
508 FeatureMatchesBlob blob = ReadDynamicMatrixBlob<FeatureMatchesBlob>(
509 sql_stmt_read_two_view_geometry_, rc, 0);
511 two_view_geometry.
config =
static_cast<int>(
512 sqlite3_column_int64(sql_stmt_read_two_view_geometry_, 3));
514 two_view_geometry.
F = ReadStaticMatrixBlob<Eigen::Matrix3d>(
515 sql_stmt_read_two_view_geometry_, rc, 4);
516 two_view_geometry.
E = ReadStaticMatrixBlob<Eigen::Matrix3d>(
517 sql_stmt_read_two_view_geometry_, rc, 5);
518 two_view_geometry.
H = ReadStaticMatrixBlob<Eigen::Matrix3d>(
519 sql_stmt_read_two_view_geometry_, rc, 6);
520 two_view_geometry.
qvec = ReadStaticMatrixBlob<Eigen::Vector4d>(
521 sql_stmt_read_two_view_geometry_, rc, 7);
522 two_view_geometry.
tvec = ReadStaticMatrixBlob<Eigen::Vector3d>(
523 sql_stmt_read_two_view_geometry_, rc, 8);
525 SQLITE3_CALL(sqlite3_reset(sql_stmt_read_two_view_geometry_));
528 two_view_geometry.
F.transposeInPlace();
529 two_view_geometry.
E.transposeInPlace();
530 two_view_geometry.
H.transposeInPlace();
533 two_view_geometry.
Invert();
536 return two_view_geometry;
540 std::vector<image_pair_t>* image_pair_ids,
541 std::vector<TwoViewGeometry>* two_view_geometries)
const {
544 sql_stmt_read_two_view_geometries_))) == SQLITE_ROW) {
546 sqlite3_column_int64(sql_stmt_read_two_view_geometries_, 0));
547 image_pair_ids->push_back(pair_id);
551 const FeatureMatchesBlob blob = ReadDynamicMatrixBlob<FeatureMatchesBlob>(
552 sql_stmt_read_two_view_geometries_, rc, 1);
555 two_view_geometry.
config =
static_cast<int>(
556 sqlite3_column_int64(sql_stmt_read_two_view_geometries_, 4));
558 two_view_geometry.
F = ReadStaticMatrixBlob<Eigen::Matrix3d>(
559 sql_stmt_read_two_view_geometries_, rc, 5);
560 two_view_geometry.
E = ReadStaticMatrixBlob<Eigen::Matrix3d>(
561 sql_stmt_read_two_view_geometries_, rc, 6);
562 two_view_geometry.
H = ReadStaticMatrixBlob<Eigen::Matrix3d>(
563 sql_stmt_read_two_view_geometries_, rc, 7);
564 two_view_geometry.
qvec = ReadStaticMatrixBlob<Eigen::Vector4d>(
565 sql_stmt_read_two_view_geometries_, rc, 8);
566 two_view_geometry.
tvec = ReadStaticMatrixBlob<Eigen::Vector3d>(
567 sql_stmt_read_two_view_geometries_, rc, 9);
569 two_view_geometry.
F.transposeInPlace();
570 two_view_geometry.
E.transposeInPlace();
571 two_view_geometry.
H.transposeInPlace();
573 two_view_geometries->push_back(two_view_geometry);
576 SQLITE3_CALL(sqlite3_reset(sql_stmt_read_two_view_geometries_));
580 std::vector<std::pair<image_t, image_t>>* image_pairs,
581 std::vector<int>* num_inliers)
const {
583 image_pairs->reserve(num_inlier_matches);
584 num_inliers->reserve(num_inlier_matches);
587 sql_stmt_read_two_view_geometry_num_inliers_)) == SQLITE_ROW) {
591 sqlite3_column_int64(sql_stmt_read_two_view_geometry_num_inliers_, 0));
593 image_pairs->emplace_back(image_id1, image_id2);
595 const int rows =
static_cast<int>(
596 sqlite3_column_int64(sql_stmt_read_two_view_geometry_num_inliers_, 1));
597 num_inliers->push_back(rows);
600 SQLITE3_CALL(sqlite3_reset(sql_stmt_read_two_view_geometry_num_inliers_));
604 const bool use_camera_id)
const {
608 sqlite3_bind_int64(sql_stmt_add_camera_, 1, camera.
CameraId()));
610 SQLITE3_CALL(sqlite3_bind_null(sql_stmt_add_camera_, 1));
614 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_add_camera_, 3,
615 static_cast<sqlite3_int64
>(camera.
Width())));
616 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_add_camera_, 4,
617 static_cast<sqlite3_int64
>(camera.
Height())));
619 const size_t num_params_bytes =
sizeof(double) * camera.
NumParams();
621 static_cast<int>(num_params_bytes),
624 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_add_camera_, 6,
630 return static_cast<camera_t>(sqlite3_last_insert_rowid(database_));
634 const bool use_image_id)
const {
639 SQLITE3_CALL(sqlite3_bind_null(sql_stmt_add_image_, 1));
643 static_cast<int>(
image.Name().size()),
657 sqlite3_bind_double(sql_stmt_add_image_, 10,
image.TvecPrior(2)));
662 return static_cast<image_t>(sqlite3_last_insert_rowid(database_));
667 const FeatureKeypointsBlob blob = FeatureKeypointsToBlob(keypoints);
669 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_write_keypoints_, 1, image_id));
670 WriteDynamicMatrixBlob(sql_stmt_write_keypoints_, blob, 2);
678 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_write_descriptors_, 1, image_id));
679 WriteDynamicMatrixBlob(sql_stmt_write_descriptors_,
descriptors, 2);
681 SQLITE3_CALL(sqlite3_step(sql_stmt_write_descriptors_));
682 SQLITE3_CALL(sqlite3_reset(sql_stmt_write_descriptors_));
688 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_write_matches_, 1, pair_id));
691 FeatureMatchesBlob blob = FeatureMatchesToBlob(matches);
693 SwapFeatureMatchesBlob(&blob);
694 WriteDynamicMatrixBlob(sql_stmt_write_matches_, blob, 2);
696 WriteDynamicMatrixBlob(sql_stmt_write_matches_, blob, 2);
708 sqlite3_bind_int64(sql_stmt_write_two_view_geometry_, 1, pair_id));
713 std::unique_ptr<TwoViewGeometry> swapped_two_view_geometry;
716 *swapped_two_view_geometry = two_view_geometry;
717 swapped_two_view_geometry->
Invert();
718 two_view_geometry_ptr = swapped_two_view_geometry.get();
721 const FeatureMatchesBlob inlier_matches =
723 WriteDynamicMatrixBlob(sql_stmt_write_two_view_geometry_, inlier_matches, 2);
725 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_write_two_view_geometry_, 5,
726 two_view_geometry_ptr->
config));
731 const Eigen::Matrix3d Ft = two_view_geometry_ptr->
F.transpose();
732 const Eigen::Matrix3d Et = two_view_geometry_ptr->
E.transpose();
733 const Eigen::Matrix3d Ht = two_view_geometry_ptr->
H.transpose();
734 const Eigen::Vector4d& qvec = two_view_geometry_ptr->
qvec;
735 const Eigen::Vector3d& tvec = two_view_geometry_ptr->
tvec;
738 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, Ft, 6);
739 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, Et, 7);
740 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, Ht, 8);
741 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, qvec, 9);
742 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, tvec, 10);
744 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_,
745 Eigen::MatrixXd(0, 0), 6);
746 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_,
747 Eigen::MatrixXd(0, 0), 7);
748 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_,
749 Eigen::MatrixXd(0, 0), 8);
750 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_,
751 Eigen::MatrixXd(0, 0), 9);
752 WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_,
753 Eigen::MatrixXd(0, 0), 10);
756 SQLITE3_CALL(sqlite3_step(sql_stmt_write_two_view_geometry_));
757 SQLITE3_CALL(sqlite3_reset(sql_stmt_write_two_view_geometry_));
762 sqlite3_bind_int64(sql_stmt_update_camera_, 1, camera.
ModelId()));
763 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_update_camera_, 2,
764 static_cast<sqlite3_int64
>(camera.
Width())));
765 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_update_camera_, 3,
766 static_cast<sqlite3_int64
>(camera.
Height())));
768 const size_t num_params_bytes =
sizeof(double) * camera.
NumParams();
770 sqlite3_bind_blob(sql_stmt_update_camera_, 4, camera.
ParamsData(),
771 static_cast<int>(num_params_bytes), SQLITE_STATIC));
773 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_update_camera_, 5,
777 sqlite3_bind_int64(sql_stmt_update_camera_, 6, camera.
CameraId()));
785 sqlite3_bind_text(sql_stmt_update_image_, 1,
image.Name().c_str(),
786 static_cast<int>(
image.Name().size()), SQLITE_STATIC));
789 sqlite3_bind_double(sql_stmt_update_image_, 3,
image.QvecPrior(0)));
791 sqlite3_bind_double(sql_stmt_update_image_, 4,
image.QvecPrior(1)));
793 sqlite3_bind_double(sql_stmt_update_image_, 5,
image.QvecPrior(2)));
795 sqlite3_bind_double(sql_stmt_update_image_, 6,
image.QvecPrior(3)));
797 sqlite3_bind_double(sql_stmt_update_image_, 7,
image.TvecPrior(0)));
799 sqlite3_bind_double(sql_stmt_update_image_, 8,
image.TvecPrior(1)));
801 sqlite3_bind_double(sql_stmt_update_image_, 9,
image.TvecPrior(2)));
810 const image_t image_id2)
const {
812 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_delete_matches_, 1,
813 static_cast<sqlite3_int64
>(pair_id)));
819 const image_t image_id2)
const {
821 SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_delete_two_view_geometry_, 1,
822 static_cast<sqlite3_int64
>(pair_id)));
823 SQLITE3_CALL(sqlite3_step(sql_stmt_delete_two_view_geometry_));
824 SQLITE3_CALL(sqlite3_reset(sql_stmt_delete_two_view_geometry_));
847 SQLITE3_CALL(sqlite3_step(sql_stmt_clear_descriptors_));
848 SQLITE3_CALL(sqlite3_reset(sql_stmt_clear_descriptors_));
862 SQLITE3_CALL(sqlite3_step(sql_stmt_clear_two_view_geometries_));
863 SQLITE3_CALL(sqlite3_reset(sql_stmt_clear_two_view_geometries_));
870 std::unordered_map<camera_t, camera_t> new_camera_ids1;
873 new_camera_ids1.emplace(camera.CameraId(), new_camera_id);
876 std::unordered_map<camera_t, camera_t> new_camera_ids2;
879 new_camera_ids2.emplace(camera.CameraId(), new_camera_id);
884 std::unordered_map<image_t, image_t> new_image_ids1;
886 image.SetCameraId(new_camera_ids1.at(
image.CameraId()));
888 <<
"The two databases must not contain images with the same name, but "
889 "the there are images with name "
890 <<
image.Name() <<
" in both databases";
892 new_image_ids1.emplace(
image.ImageId(), new_image_id);
899 std::unordered_map<image_t, image_t> new_image_ids2;
901 image.SetCameraId(new_camera_ids2.at(
image.CameraId()));
903 <<
"The two databases must not contain images with the same name, but "
904 "the there are images with name "
905 <<
image.Name() <<
" in both databases";
907 new_image_ids2.emplace(
image.ImageId(), new_image_id);
920 const image_t new_image_id1 = new_image_ids1.at(image_id1);
921 const image_t new_image_id2 = new_image_ids1.at(image_id2);
923 merged_database->
WriteMatches(new_image_id1, new_image_id2, matches.second);
930 const image_t new_image_id1 = new_image_ids2.at(image_id1);
931 const image_t new_image_id2 = new_image_ids2.at(image_id2);
933 merged_database->
WriteMatches(new_image_id1, new_image_id2, matches.second);
939 std::vector<image_pair_t> image_pair_ids;
940 std::vector<TwoViewGeometry> two_view_geometries;
943 for (
size_t i = 0; i < two_view_geometries.size(); ++i) {
947 const image_t new_image_id1 = new_image_ids1.at(image_id1);
948 const image_t new_image_id2 = new_image_ids1.at(image_id2);
951 two_view_geometries[i]);
956 std::vector<image_pair_t> image_pair_ids;
957 std::vector<TwoViewGeometry> two_view_geometries;
960 for (
size_t i = 0; i < two_view_geometries.size(); ++i) {
964 const image_t new_image_id1 = new_image_ids2.at(image_id1);
965 const image_t new_image_id2 = new_image_ids2.at(image_id2);
968 two_view_geometries[i]);
973 void Database::BeginTransaction()
const {
977 void Database::EndTransaction()
const {
981 void Database::PrepareSQLStatements() {
989 sql =
"SELECT rows FROM keypoints WHERE image_id = ?;";
990 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
991 &sql_stmt_num_keypoints_, 0));
992 sql_stmts_.push_back(sql_stmt_num_keypoints_);
994 sql =
"SELECT rows FROM descriptors WHERE image_id = ?;";
995 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
996 &sql_stmt_num_descriptors_, 0));
997 sql_stmts_.push_back(sql_stmt_num_descriptors_);
1002 sql =
"SELECT 1 FROM cameras WHERE camera_id = ?;";
1003 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1004 &sql_stmt_exists_camera_, 0));
1005 sql_stmts_.push_back(sql_stmt_exists_camera_);
1007 sql =
"SELECT 1 FROM images WHERE image_id = ?;";
1008 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1009 &sql_stmt_exists_image_id_, 0));
1010 sql_stmts_.push_back(sql_stmt_exists_image_id_);
1012 sql =
"SELECT 1 FROM images WHERE name = ?;";
1013 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1014 &sql_stmt_exists_image_name_, 0));
1015 sql_stmts_.push_back(sql_stmt_exists_image_name_);
1017 sql =
"SELECT 1 FROM keypoints WHERE image_id = ?;";
1018 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1019 &sql_stmt_exists_keypoints_, 0));
1020 sql_stmts_.push_back(sql_stmt_exists_keypoints_);
1022 sql =
"SELECT 1 FROM descriptors WHERE image_id = ?;";
1023 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1024 &sql_stmt_exists_descriptors_, 0));
1025 sql_stmts_.push_back(sql_stmt_exists_descriptors_);
1027 sql =
"SELECT 1 FROM matches WHERE pair_id = ?;";
1028 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1029 &sql_stmt_exists_matches_, 0));
1030 sql_stmts_.push_back(sql_stmt_exists_matches_);
1032 sql =
"SELECT 1 FROM two_view_geometries WHERE pair_id = ?;";
1033 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1034 &sql_stmt_exists_two_view_geometry_, 0));
1035 sql_stmts_.push_back(sql_stmt_exists_two_view_geometry_);
1041 "INSERT INTO cameras(camera_id, model, width, height, params, "
1042 "prior_focal_length) VALUES(?, ?, ?, ?, ?, ?);";
1044 sqlite3_prepare_v2(database_, sql.c_str(), -1, &sql_stmt_add_camera_, 0));
1045 sql_stmts_.push_back(sql_stmt_add_camera_);
1048 "INSERT INTO images(image_id, name, camera_id, prior_qw, prior_qx, "
1049 "prior_qy, prior_qz, prior_tx, prior_ty, prior_tz) VALUES(?, ?, ?, ?, ?, "
1052 sqlite3_prepare_v2(database_, sql.c_str(), -1, &sql_stmt_add_image_, 0));
1053 sql_stmts_.push_back(sql_stmt_add_image_);
1059 "UPDATE cameras SET model=?, width=?, height=?, params=?, "
1060 "prior_focal_length=? WHERE camera_id=?;";
1061 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1062 &sql_stmt_update_camera_, 0));
1063 sql_stmts_.push_back(sql_stmt_update_camera_);
1066 "UPDATE images SET name=?, camera_id=?, prior_qw=?, prior_qx=?, "
1067 "prior_qy=?, prior_qz=?, prior_tx=?, prior_ty=?, prior_tz=? WHERE "
1069 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1070 &sql_stmt_update_image_, 0));
1071 sql_stmts_.push_back(sql_stmt_update_image_);
1076 sql =
"SELECT * FROM cameras WHERE camera_id = ?;";
1077 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1078 &sql_stmt_read_camera_, 0));
1079 sql_stmts_.push_back(sql_stmt_read_camera_);
1081 sql =
"SELECT * FROM cameras;";
1082 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1083 &sql_stmt_read_cameras_, 0));
1084 sql_stmts_.push_back(sql_stmt_read_cameras_);
1086 sql =
"SELECT * FROM images WHERE image_id = ?;";
1087 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1088 &sql_stmt_read_image_id_, 0));
1089 sql_stmts_.push_back(sql_stmt_read_image_id_);
1091 sql =
"SELECT * FROM images WHERE name = ?;";
1092 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1093 &sql_stmt_read_image_name_, 0));
1094 sql_stmts_.push_back(sql_stmt_read_image_name_);
1096 sql =
"SELECT * FROM images;";
1097 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1098 &sql_stmt_read_images_, 0));
1099 sql_stmts_.push_back(sql_stmt_read_images_);
1101 sql =
"SELECT rows, cols, data FROM keypoints WHERE image_id = ?;";
1102 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1103 &sql_stmt_read_keypoints_, 0));
1104 sql_stmts_.push_back(sql_stmt_read_keypoints_);
1106 sql =
"SELECT rows, cols, data FROM descriptors WHERE image_id = ?;";
1107 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1108 &sql_stmt_read_descriptors_, 0));
1109 sql_stmts_.push_back(sql_stmt_read_descriptors_);
1111 sql =
"SELECT rows, cols, data FROM matches WHERE pair_id = ?;";
1112 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1113 &sql_stmt_read_matches_, 0));
1114 sql_stmts_.push_back(sql_stmt_read_matches_);
1116 sql =
"SELECT * FROM matches WHERE rows > 0;";
1117 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1118 &sql_stmt_read_matches_all_, 0));
1119 sql_stmts_.push_back(sql_stmt_read_matches_all_);
1122 "SELECT rows, cols, data, config, F, E, H, qvec, tvec FROM "
1123 "two_view_geometries WHERE pair_id = ?;";
1124 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1125 &sql_stmt_read_two_view_geometry_, 0));
1126 sql_stmts_.push_back(sql_stmt_read_two_view_geometry_);
1128 sql =
"SELECT * FROM two_view_geometries WHERE rows > 0;";
1129 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1130 &sql_stmt_read_two_view_geometries_, 0));
1131 sql_stmts_.push_back(sql_stmt_read_two_view_geometries_);
1133 sql =
"SELECT pair_id, rows FROM two_view_geometries WHERE rows > 0;";
1134 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1135 &sql_stmt_read_two_view_geometry_num_inliers_,
1137 sql_stmts_.push_back(sql_stmt_read_two_view_geometry_num_inliers_);
1142 sql =
"INSERT INTO keypoints(image_id, rows, cols, data) VALUES(?, ?, ?, ?);";
1143 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1144 &sql_stmt_write_keypoints_, 0));
1145 sql_stmts_.push_back(sql_stmt_write_keypoints_);
1148 "INSERT INTO descriptors(image_id, rows, cols, data) VALUES(?, ?, ?, ?);";
1149 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1150 &sql_stmt_write_descriptors_, 0));
1151 sql_stmts_.push_back(sql_stmt_write_descriptors_);
1153 sql =
"INSERT INTO matches(pair_id, rows, cols, data) VALUES(?, ?, ?, ?);";
1154 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1155 &sql_stmt_write_matches_, 0));
1156 sql_stmts_.push_back(sql_stmt_write_matches_);
1159 "INSERT INTO two_view_geometries(pair_id, rows, cols, data, config, F, "
1160 "E, H, qvec, tvec) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
1161 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1162 &sql_stmt_write_two_view_geometry_, 0));
1163 sql_stmts_.push_back(sql_stmt_write_two_view_geometry_);
1168 sql =
"DELETE FROM matches WHERE pair_id = ?;";
1169 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1170 &sql_stmt_delete_matches_, 0));
1171 sql_stmts_.push_back(sql_stmt_delete_matches_);
1173 sql =
"DELETE FROM two_view_geometries WHERE pair_id = ?;";
1174 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1175 &sql_stmt_delete_two_view_geometry_, 0));
1176 sql_stmts_.push_back(sql_stmt_delete_two_view_geometry_);
1181 sql =
"DELETE FROM cameras;";
1182 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1183 &sql_stmt_clear_cameras_, 0));
1184 sql_stmts_.push_back(sql_stmt_clear_cameras_);
1186 sql =
"DELETE FROM images;";
1187 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1188 &sql_stmt_clear_images_, 0));
1189 sql_stmts_.push_back(sql_stmt_clear_images_);
1191 sql =
"DELETE FROM descriptors;";
1192 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1193 &sql_stmt_clear_descriptors_, 0));
1194 sql_stmts_.push_back(sql_stmt_clear_descriptors_);
1196 sql =
"DELETE FROM keypoints;";
1197 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1198 &sql_stmt_clear_keypoints_, 0));
1199 sql_stmts_.push_back(sql_stmt_clear_keypoints_);
1201 sql =
"DELETE FROM matches;";
1202 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1203 &sql_stmt_clear_matches_, 0));
1204 sql_stmts_.push_back(sql_stmt_clear_matches_);
1206 sql =
"DELETE FROM two_view_geometries;";
1207 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1,
1208 &sql_stmt_clear_two_view_geometries_, 0));
1209 sql_stmts_.push_back(sql_stmt_clear_two_view_geometries_);
1212 void Database::FinalizeSQLStatements() {
1213 for (
const auto& sql_stmt : sql_stmts_) {
1218 void Database::CreateTables()
const {
1219 CreateCameraTable();
1221 CreateKeypointsTable();
1222 CreateDescriptorsTable();
1223 CreateMatchesTable();
1224 CreateTwoViewGeometriesTable();
1227 void Database::CreateCameraTable()
const {
1228 const std::string sql =
1229 "CREATE TABLE IF NOT EXISTS cameras"
1230 " (camera_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
1231 " model INTEGER NOT NULL,"
1232 " width INTEGER NOT NULL,"
1233 " height INTEGER NOT NULL,"
1235 " prior_focal_length INTEGER NOT NULL);";
1240 void Database::CreateImageTable()
const {
1242 "CREATE TABLE IF NOT EXISTS images"
1243 " (image_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
1244 " name TEXT NOT NULL UNIQUE,"
1245 " camera_id INTEGER NOT NULL,"
1253 "CONSTRAINT image_id_check CHECK(image_id >= 0 and image_id < %d),"
1254 "FOREIGN KEY(camera_id) REFERENCES cameras(camera_id));"
1255 "CREATE UNIQUE INDEX IF NOT EXISTS index_name ON images(name);",
1261 void Database::CreateKeypointsTable()
const {
1262 const std::string sql =
1263 "CREATE TABLE IF NOT EXISTS keypoints"
1264 " (image_id INTEGER PRIMARY KEY NOT NULL,"
1265 " rows INTEGER NOT NULL,"
1266 " cols INTEGER NOT NULL,"
1268 "FOREIGN KEY(image_id) REFERENCES images(image_id) ON DELETE CASCADE);";
1273 void Database::CreateDescriptorsTable()
const {
1274 const std::string sql =
1275 "CREATE TABLE IF NOT EXISTS descriptors"
1276 " (image_id INTEGER PRIMARY KEY NOT NULL,"
1277 " rows INTEGER NOT NULL,"
1278 " cols INTEGER NOT NULL,"
1280 "FOREIGN KEY(image_id) REFERENCES images(image_id) ON DELETE CASCADE);";
1285 void Database::CreateMatchesTable()
const {
1286 const std::string sql =
1287 "CREATE TABLE IF NOT EXISTS matches"
1288 " (pair_id INTEGER PRIMARY KEY NOT NULL,"
1289 " rows INTEGER NOT NULL,"
1290 " cols INTEGER NOT NULL,"
1296 void Database::CreateTwoViewGeometriesTable()
const {
1297 if (ExistsTable(
"inlier_matches")) {
1299 "ALTER TABLE inlier_matches RENAME TO two_view_geometries;",
1302 const std::string sql =
1303 "CREATE TABLE IF NOT EXISTS two_view_geometries"
1304 " (pair_id INTEGER PRIMARY KEY NOT NULL,"
1305 " rows INTEGER NOT NULL,"
1306 " cols INTEGER NOT NULL,"
1308 " config INTEGER NOT NULL,"
1318 void Database::UpdateSchema()
const {
1319 if (!ExistsColumn(
"two_view_geometries",
"F")) {
1321 "ALTER TABLE two_view_geometries ADD COLUMN F BLOB;",
nullptr);
1324 if (!ExistsColumn(
"two_view_geometries",
"E")) {
1326 "ALTER TABLE two_view_geometries ADD COLUMN E BLOB;",
nullptr);
1329 if (!ExistsColumn(
"two_view_geometries",
"H")) {
1331 "ALTER TABLE two_view_geometries ADD COLUMN H BLOB;",
nullptr);
1334 if (!ExistsColumn(
"two_view_geometries",
"qvec")) {
1336 "ALTER TABLE two_view_geometries ADD COLUMN qvec BLOB;",
1340 if (!ExistsColumn(
"two_view_geometries",
"tvec")) {
1342 "ALTER TABLE two_view_geometries ADD COLUMN tvec BLOB;",
1347 std::unique_lock<std::mutex> lock(update_schema_mutex_);
1348 const std::string update_user_version_sql =
1349 StringPrintf(
"PRAGMA user_version = %d;", COLMAP_VERSION_NUMBER);
1350 SQLITE3_EXEC(database_, update_user_version_sql.c_str(),
nullptr);
1353 bool Database::ExistsTable(
const std::string& table_name)
const {
1354 const std::string sql =
1355 "SELECT name FROM sqlite_master WHERE type='table' AND name = ?;";
1357 sqlite3_stmt* sql_stmt;
1358 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1, &sql_stmt, 0));
1360 SQLITE3_CALL(sqlite3_bind_text(sql_stmt, 1, table_name.c_str(),
1361 static_cast<int>(table_name.size()),
1364 const bool exists =
SQLITE3_CALL(sqlite3_step(sql_stmt)) == SQLITE_ROW;
1371 bool Database::ExistsColumn(
const std::string& table_name,
1372 const std::string& column_name)
const {
1373 const std::string sql =
1374 StringPrintf(
"PRAGMA table_info(%s);", table_name.c_str());
1376 sqlite3_stmt* sql_stmt;
1377 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1, &sql_stmt, 0));
1379 bool exists_column =
false;
1380 while (
SQLITE3_CALL(sqlite3_step(sql_stmt)) == SQLITE_ROW) {
1381 const std::string
result =
1382 reinterpret_cast<const char*
>(sqlite3_column_text(sql_stmt, 1));
1383 if (column_name ==
result) {
1384 exists_column =
true;
1391 return exists_column;
1394 bool Database::ExistsRowId(sqlite3_stmt* sql_stmt,
1395 const sqlite3_int64 row_id)
const {
1397 sqlite3_bind_int64(sql_stmt, 1,
static_cast<sqlite3_int64
>(row_id)));
1399 const bool exists =
SQLITE3_CALL(sqlite3_step(sql_stmt)) == SQLITE_ROW;
1406 bool Database::ExistsRowString(sqlite3_stmt* sql_stmt,
1407 const std::string& row_entry)
const {
1408 SQLITE3_CALL(sqlite3_bind_text(sql_stmt, 1, row_entry.c_str(),
1409 static_cast<int>(row_entry.size()),
1412 const bool exists =
SQLITE3_CALL(sqlite3_step(sql_stmt)) == SQLITE_ROW;
1419 size_t Database::CountRows(
const std::string& table)
const {
1420 const std::string sql =
1421 StringPrintf(
"SELECT COUNT(*) FROM %s;", table.c_str());
1423 sqlite3_stmt* sql_stmt;
1424 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1, &sql_stmt, 0));
1428 if (rc == SQLITE_ROW) {
1429 count =
static_cast<size_t>(sqlite3_column_int64(sql_stmt, 0));
1437 size_t Database::CountRowsForEntry(sqlite3_stmt* sql_stmt,
1438 const sqlite3_int64 row_id)
const {
1443 if (rc == SQLITE_ROW) {
1444 count =
static_cast<size_t>(sqlite3_column_int64(sql_stmt, 0));
1452 size_t Database::SumColumn(
const std::string& column,
1453 const std::string& table)
const {
1454 const std::string sql =
1455 StringPrintf(
"SELECT SUM(%s) FROM %s;", column.c_str(), table.c_str());
1457 sqlite3_stmt* sql_stmt;
1458 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1, &sql_stmt, 0));
1462 if (rc == SQLITE_ROW) {
1463 sum =
static_cast<size_t>(sqlite3_column_int64(sql_stmt, 0));
1471 size_t Database::MaxColumn(
const std::string& column,
1472 const std::string& table)
const {
1473 const std::string sql =
1474 StringPrintf(
"SELECT MAX(%s) FROM %s;", column.c_str(), table.c_str());
1476 sqlite3_stmt* sql_stmt;
1477 SQLITE3_CALL(sqlite3_prepare_v2(database_, sql.c_str(), -1, &sql_stmt, 0));
1481 if (rc == SQLITE_ROW) {
1482 max =
static_cast<size_t>(sqlite3_column_int64(sql_stmt, 0));
1491 : database_(database), database_lock_(database->transaction_mutex_) {
1492 CHECK_NOTNULL(database_);
1493 database_->BeginTransaction();
std::shared_ptr< core::Tensor > image
camera_t CameraId() const
bool HasPriorFocalLength() const
const double * ParamsData() const
DatabaseTransaction(Database *database)
void ClearCameras() const
void WriteDescriptors(const image_t image_id, const FeatureDescriptors &descriptors) const
size_t NumMatches() const
static const size_t kMaxNumImages
FeatureDescriptors ReadDescriptors(const image_t image_id) const
void ClearDescriptors() const
static void Merge(const Database &database1, const Database &database2, Database *merged_database)
size_t NumMatchedImagePairs() const
void ReadTwoViewGeometryNumInliers(std::vector< std::pair< image_t, image_t >> *image_pairs, std::vector< int > *num_inliers) const
size_t MaxNumDescriptors() const
void ClearAllTables() const
FeatureMatches ReadMatches(const image_t image_id1, const image_t image_id2) const
bool ExistsImage(const image_t image_id) const
void DeleteInlierMatches(const image_t image_id1, const image_t image_id2) const
void WriteMatches(const image_t image_id1, const image_t image_id2, const FeatureMatches &matches) const
bool ExistsMatches(const image_t image_id1, const image_t image_id2) const
FeatureKeypoints ReadKeypoints(const image_t image_id) const
size_t NumInlierMatches() const
void ClearKeypoints() const
size_t NumDescriptors() const
size_t NumKeypoints() const
void WriteTwoViewGeometry(const image_t image_id1, const image_t image_id2, const TwoViewGeometry &two_view_geometry) const
size_t NumVerifiedImagePairs() const
void WriteKeypoints(const image_t image_id, const FeatureKeypoints &keypoints) const
std::vector< std::pair< image_pair_t, FeatureMatches > > ReadAllMatches() const
static image_pair_t ImagePairToPairId(const image_t image_id1, const image_t image_id2)
bool ExistsKeypoints(const image_t image_id) const
size_t NumKeypointsForImage(const image_t image_id) const
bool ExistsInlierMatches(const image_t image_id1, const image_t image_id2) const
std::vector< Camera > ReadAllCameras() const
bool ExistsCamera(const camera_t camera_id) const
void DeleteMatches(const image_t image_id1, const image_t image_id2) const
size_t NumDescriptorsForImage(const image_t image_id) const
void ReadTwoViewGeometries(std::vector< image_pair_t > *image_pair_ids, std::vector< TwoViewGeometry > *two_view_geometries) const
void Open(const std::string &path)
void ClearTwoViewGeometries() const
static bool SwapImagePair(const image_t image_id1, const image_t image_id2)
void ClearMatches() const
bool ExistsDescriptors(const image_t image_id) const
bool ExistsImageWithName(std::string name) const
void UpdateCamera(const Camera &camera) const
Image ReadImageWithName(const std::string &name) const
size_t MaxNumKeypoints() const
TwoViewGeometry ReadTwoViewGeometry(const image_t image_id1, const image_t image_id2) const
static void PairIdToImagePair(const image_pair_t pair_id, image_t *image_id1, image_t *image_id2)
Camera ReadCamera(const camera_t camera_id) const
void UpdateImage(const Image &image) const
image_t WriteImage(const Image &image, const bool use_image_id=false) const
size_t NumCameras() const
std::vector< Image > ReadAllImages() const
camera_t WriteCamera(const Camera &camera, const bool use_camera_id=false) const
Image ReadImage(const image_t image_id) const
static const std::string path
Eigen::Matrix< uint8_t, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > FeatureDescriptors
std::vector< FeatureKeypoint > FeatureKeypoints
std::string StringPrintf(const char *format,...)
std::vector< FeatureMatch > FeatureMatches
Eigen::MatrixXd::Index Index
#define SQLITE3_EXEC(database, sql, callback)
#define SQLITE3_CALL(func)
FeatureMatches inlier_matches