| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifndef COLMAP_SRC_BASE_DATABASE_H_ |
| #define COLMAP_SRC_BASE_DATABASE_H_ |
|
|
| #include <mutex> |
| #include <unordered_map> |
| #include <vector> |
|
|
| #include <Eigen/Core> |
|
|
| #include "SQLite/sqlite3.h" |
| #include "base/camera.h" |
| #include "base/image.h" |
| #include "estimators/two_view_geometry.h" |
| #include "feature/types.h" |
| #include "util/types.h" |
|
|
| namespace colmap { |
|
|
| |
| |
| |
| |
| |
| class Database { |
| public: |
| const static int kSchemaVersion = 1; |
|
|
| |
| |
| |
| |
| const static size_t kMaxNumImages; |
|
|
| Database(); |
| explicit Database(const std::string& path); |
| ~Database(); |
|
|
| |
| |
| void Open(const std::string& path); |
| void Close(); |
|
|
| |
| |
| bool ExistsCamera(const camera_t camera_id) const; |
| bool ExistsImage(const image_t image_id) const; |
| bool ExistsImageWithName(std::string name) const; |
| bool ExistsKeypoints(const image_t image_id) const; |
| bool ExistsDescriptors(const image_t image_id) const; |
| bool ExistsMatches(const image_t image_id1, const image_t image_id2) const; |
| bool ExistsInlierMatches(const image_t image_id1, |
| const image_t image_id2) const; |
|
|
| |
| size_t NumCameras() const; |
|
|
| |
| size_t NumImages() const; |
|
|
| |
| size_t NumKeypoints() const; |
|
|
| |
| size_t MaxNumKeypoints() const; |
|
|
| |
| size_t NumKeypointsForImage(const image_t image_id) const; |
|
|
| |
| |
| size_t NumDescriptors() const; |
|
|
| |
| size_t MaxNumDescriptors() const; |
|
|
| |
| size_t NumDescriptorsForImage(const image_t image_id) const; |
|
|
| |
| size_t NumMatches() const; |
|
|
| |
| |
| size_t NumInlierMatches() const; |
|
|
| |
| size_t NumMatchedImagePairs() const; |
|
|
| |
| size_t NumVerifiedImagePairs() const; |
|
|
| |
| |
| |
| |
| inline static image_pair_t ImagePairToPairId(const image_t image_id1, |
| const image_t image_id2); |
|
|
| inline static void PairIdToImagePair(const image_pair_t pair_id, |
| image_t* image_id1, image_t* image_id2); |
|
|
| |
| |
| |
| inline static bool SwapImagePair(const image_t image_id1, |
| const image_t image_id2); |
|
|
| |
| |
| |
| Camera ReadCamera(const camera_t camera_id) const; |
| std::vector<Camera> ReadAllCameras() const; |
|
|
| Image ReadImage(const image_t image_id) const; |
| Image ReadImageWithName(const std::string& name) const; |
| std::vector<Image> ReadAllImages() const; |
|
|
| FeatureKeypoints ReadKeypoints(const image_t image_id) const; |
| FeatureDescriptors ReadDescriptors(const image_t image_id) const; |
|
|
| FeatureMatches ReadMatches(const image_t image_id1, |
| const image_t image_id2) const; |
| std::vector<std::pair<image_pair_t, FeatureMatches>> ReadAllMatches() const; |
|
|
| TwoViewGeometry ReadTwoViewGeometry(const image_t image_id1, |
| const image_t image_id2) const; |
| void ReadTwoViewGeometries( |
| std::vector<image_pair_t>* image_pair_ids, |
| std::vector<TwoViewGeometry>* two_view_geometries) const; |
|
|
| |
| |
| void ReadTwoViewGeometryNumInliers( |
| std::vector<std::pair<image_t, image_t>>* image_pairs, |
| std::vector<int>* num_inliers) const; |
|
|
| |
| |
| camera_t WriteCamera(const Camera& camera, |
| const bool use_camera_id = false) const; |
|
|
| |
| |
| image_t WriteImage(const Image& image, const bool use_image_id = false) const; |
|
|
| |
| |
| |
| void WriteKeypoints(const image_t image_id, |
| const FeatureKeypoints& keypoints) const; |
| void WriteDescriptors(const image_t image_id, |
| const FeatureDescriptors& descriptors) const; |
| void WriteMatches(const image_t image_id1, const image_t image_id2, |
| const FeatureMatches& matches) const; |
| void WriteTwoViewGeometry(const image_t image_id1, const image_t image_id2, |
| const TwoViewGeometry& two_view_geometry) const; |
|
|
| |
| |
| void UpdateCamera(const Camera& camera) const; |
|
|
| |
| |
| void UpdateImage(const Image& image) const; |
|
|
| |
| void DeleteMatches(const image_t image_id1, const image_t image_id2) const; |
|
|
| |
| void DeleteInlierMatches(const image_t image_id1, |
| const image_t image_id2) const; |
|
|
| |
| void ClearAllTables() const; |
|
|
| |
| void ClearCameras() const; |
|
|
| |
| void ClearImages() const; |
|
|
| |
| void ClearDescriptors() const; |
|
|
| |
| void ClearKeypoints() const; |
|
|
| |
| void ClearMatches() const; |
|
|
| |
| void ClearTwoViewGeometries() const; |
|
|
| |
| static void Merge(const Database& database1, const Database& database2, |
| Database* merged_database); |
|
|
| private: |
| friend class DatabaseTransaction; |
|
|
| |
| |
| |
| |
| |
| void BeginTransaction() const; |
| void EndTransaction() const; |
|
|
| |
| |
| void PrepareSQLStatements(); |
| void FinalizeSQLStatements(); |
|
|
| |
| void CreateTables() const; |
| void CreateCameraTable() const; |
| void CreateImageTable() const; |
| void CreateKeypointsTable() const; |
| void CreateDescriptorsTable() const; |
| void CreateMatchesTable() const; |
| void CreateTwoViewGeometriesTable() const; |
|
|
| void UpdateSchema() const; |
|
|
| bool ExistsTable(const std::string& table_name) const; |
| bool ExistsColumn(const std::string& table_name, |
| const std::string& column_name) const; |
|
|
| bool ExistsRowId(sqlite3_stmt* sql_stmt, const sqlite3_int64 row_id) const; |
| bool ExistsRowString(sqlite3_stmt* sql_stmt, |
| const std::string& row_entry) const; |
|
|
| size_t CountRows(const std::string& table) const; |
| size_t CountRowsForEntry(sqlite3_stmt* sql_stmt, |
| const sqlite3_int64 row_id) const; |
| size_t SumColumn(const std::string& column, const std::string& table) const; |
| size_t MaxColumn(const std::string& column, const std::string& table) const; |
|
|
| sqlite3* database_ = nullptr; |
|
|
| |
| |
| mutable bool database_cleared_ = false; |
|
|
| |
| |
| |
| |
| |
| static std::mutex update_schema_mutex_; |
|
|
| |
| std::mutex transaction_mutex_; |
|
|
| |
| std::vector<sqlite3_stmt*> sql_stmts_; |
|
|
| |
| sqlite3_stmt* sql_stmt_num_keypoints_ = nullptr; |
| sqlite3_stmt* sql_stmt_num_descriptors_ = nullptr; |
|
|
| |
| sqlite3_stmt* sql_stmt_exists_camera_ = nullptr; |
| sqlite3_stmt* sql_stmt_exists_image_id_ = nullptr; |
| sqlite3_stmt* sql_stmt_exists_image_name_ = nullptr; |
| sqlite3_stmt* sql_stmt_exists_keypoints_ = nullptr; |
| sqlite3_stmt* sql_stmt_exists_descriptors_ = nullptr; |
| sqlite3_stmt* sql_stmt_exists_matches_ = nullptr; |
| sqlite3_stmt* sql_stmt_exists_two_view_geometry_ = nullptr; |
|
|
| |
| sqlite3_stmt* sql_stmt_add_camera_ = nullptr; |
| sqlite3_stmt* sql_stmt_add_image_ = nullptr; |
|
|
| |
| sqlite3_stmt* sql_stmt_update_camera_ = nullptr; |
| sqlite3_stmt* sql_stmt_update_image_ = nullptr; |
|
|
| |
| sqlite3_stmt* sql_stmt_read_camera_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_cameras_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_image_id_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_image_name_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_images_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_keypoints_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_descriptors_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_matches_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_matches_all_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_two_view_geometry_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_two_view_geometries_ = nullptr; |
| sqlite3_stmt* sql_stmt_read_two_view_geometry_num_inliers_ = nullptr; |
|
|
| |
| sqlite3_stmt* sql_stmt_write_keypoints_ = nullptr; |
| sqlite3_stmt* sql_stmt_write_descriptors_ = nullptr; |
| sqlite3_stmt* sql_stmt_write_matches_ = nullptr; |
| sqlite3_stmt* sql_stmt_write_two_view_geometry_ = nullptr; |
|
|
| |
| sqlite3_stmt* sql_stmt_delete_matches_ = nullptr; |
| sqlite3_stmt* sql_stmt_delete_two_view_geometry_ = nullptr; |
|
|
| |
| sqlite3_stmt* sql_stmt_clear_cameras_ = nullptr; |
| sqlite3_stmt* sql_stmt_clear_images_ = nullptr; |
| sqlite3_stmt* sql_stmt_clear_descriptors_ = nullptr; |
| sqlite3_stmt* sql_stmt_clear_keypoints_ = nullptr; |
| sqlite3_stmt* sql_stmt_clear_matches_ = nullptr; |
| sqlite3_stmt* sql_stmt_clear_two_view_geometries_ = nullptr; |
| }; |
|
|
| |
| |
| |
| class DatabaseTransaction { |
| public: |
| explicit DatabaseTransaction(Database* database); |
| ~DatabaseTransaction(); |
|
|
| private: |
| NON_COPYABLE(DatabaseTransaction) |
| NON_MOVABLE(DatabaseTransaction) |
| Database* database_; |
| std::unique_lock<std::mutex> database_lock_; |
| }; |
|
|
| |
| |
| |
|
|
| image_pair_t Database::ImagePairToPairId(const image_t image_id1, |
| const image_t image_id2) { |
| CHECK_GE(image_id1, 0); |
| CHECK_GE(image_id2, 0); |
| CHECK_LT(image_id1, kMaxNumImages); |
| CHECK_LT(image_id2, kMaxNumImages); |
| if (SwapImagePair(image_id1, image_id2)) { |
| return static_cast<image_pair_t>(kMaxNumImages) * image_id2 + image_id1; |
| } else { |
| return static_cast<image_pair_t>(kMaxNumImages) * image_id1 + image_id2; |
| } |
| } |
|
|
| void Database::PairIdToImagePair(const image_pair_t pair_id, image_t* image_id1, |
| image_t* image_id2) { |
| *image_id2 = static_cast<image_t>(pair_id % kMaxNumImages); |
| *image_id1 = static_cast<image_t>((pair_id - *image_id2) / kMaxNumImages); |
| CHECK_GE(*image_id1, 0); |
| CHECK_GE(*image_id2, 0); |
| CHECK_LT(*image_id1, kMaxNumImages); |
| CHECK_LT(*image_id2, kMaxNumImages); |
| } |
|
|
| |
| |
| |
| bool Database::SwapImagePair(const image_t image_id1, const image_t image_id2) { |
| return image_id1 > image_id2; |
| } |
|
|
| } |
|
|
| #endif |
|
|