### DBoW2 Installation Instructions Source: https://github.com/dorian3d/dbow2/blob/master/CMakeLists.txt Defines the installation targets for the DBoW2 library, headers, and CMake configuration files. Ensures the library and its components are correctly placed for use in other projects. ```cmake install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) if(BUILD_DBoW2) install(DIRECTORY include/DBoW2 DESTINATION ${CMAKE_INSTALL_PREFIX}/include) endif() install(FILES "${CMAKE_CURRENT_BINARY_DIR}/DBoW2Config.cmake" DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}) install(FILES "${PROJECT_BINARY_DIR}/DBoW2Config.cmake" DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/DBoW2/) install(DIRECTORY ${DEPENDENCY_INSTALL_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX} OPTIONAL) ``` -------------------------------- ### DBoW2 CMake Project Setup Source: https://github.com/dorian3d/dbow2/blob/master/CMakeLists.txt Configures the CMake version, project name, and build type. Sets compiler warnings based on the compiler used. ```cmake cmake_minimum_required(VERSION 3.0) project(DBoW2) include(ExternalProject) option(BUILD_DBoW2 "Build DBoW2" ON) option(BUILD_Demo "Build demo application" ON) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() if(MSVC) add_compile_options(/W4) else() add_compile_options(-Wall -Wextra -Wpedantic) endif() ``` -------------------------------- ### Work with BRIEF Descriptors Source: https://context7.com/dorian3d/dbow2/llms.txt Illustrates how to use DBoW2 with BRIEF descriptors, including creating a `BriefVocabulary`, training it with BRIEF descriptors, and setting up a `BriefDatabase`. Note that BRIEF descriptors are represented as `boost::dynamic_bitset<>`. ```cpp #include "DBoW2.h" #include using namespace DBoW2; using namespace std; // Note: BRIEF descriptors are represented as boost::dynamic_bitset typedef boost::dynamic_bitset<> BriefDescriptor; int main() { // Create BRIEF vocabulary const int k = 9; const int L = 3; BriefVocabulary voc(k, L, TF_IDF, L1_NORM); // Training features for BRIEF vector> features; // ... extract BRIEF descriptors from training images ... // Each BriefDescriptor is a boost::dynamic_bitset<> // Create vocabulary voc.create(features); // Save/load vocabulary voc.save("brief_vocabulary.yml.gz"); // Create BRIEF database BriefVocabulary loadedVoc("brief_vocabulary.yml.gz"); BriefDatabase db(loadedVoc, false, 0); // Add images and query as with ORB // ... similar API to OrbDatabase ... return 0; } ``` -------------------------------- ### Create and Populate Image Database Source: https://context7.com/dorian3d/dbow2/llms.txt Loads a vocabulary, creates an OrbDatabase with optional direct index, extracts ORB features from images, and adds them to the database. The database is then saved. ```cpp #include "DBoW2.h" #include #include using namespace DBoW2; using namespace std; int main() { // Load vocabulary OrbVocabulary voc("vocabulary.yml.gz"); // Create database with vocabulary // use_di = true: use direct index for feature retrieval // di_levels = 2: levels up for direct index node grouping bool use_di = true; int di_levels = 2; OrbDatabase db(voc, use_di, di_levels); // Extract features and add images to database cv::Ptr orb = cv::ORB::create(); vector imagePaths = {"image0.png", "image1.png", "image2.png", "image3.png"}; for (const auto& path : imagePaths) { cv::Mat image = cv::imread(path, cv::IMREAD_GRAYSCALE); vector keypoints; cv::Mat descriptors; orb->detectAndCompute(image, cv::Mat(), keypoints, descriptors); vector features; for (int i = 0; i < descriptors.rows; ++i) { features.push_back(descriptors.row(i)); } // Add image to database, returns entry ID EntryId entryId = db.add(features); cout << "Added image " << path << " with entry ID: " << entryId << endl; } cout << "Database contains " << db.size() << " images" cout << db << endl; // Save database (includes vocabulary) db.save("database.yml.gz"); return 0; } // Output: // Added image image0.png with entry ID: 0 // Added image image1.png with entry ID: 1 // Added image image2.png with entry ID: 2 // Added image image3.png with entry ID: 3 // Database contains 4 images // Database: Entries = 4, Using direct index = yes, Direct index levels = 2. Vocabulary: k = 10, L = 5, ... ``` -------------------------------- ### Configure Weighting and Scoring Methods Source: https://context7.com/dorian3d/dbow2/llms.txt Shows how to configure different weighting types (e.g., TF_IDF, TF) and scoring methods (e.g., L1_NORM, CHI_SQUARE) for the vocabulary. These can be set at construction or modified before training. ```cpp #include "DBoW2.h" using namespace DBoW2; int main() { // Weighting types: // TF_IDF - Term Frequency-Inverse Document Frequency (default, recommended) // TF - Term Frequency only // IDF - Inverse Document Frequency only // BINARY - Binary weighting (word present or not) // Scoring types: // L1_NORM - L1 norm (Manhattan distance) - default, fast // L2_NORM - L2 norm (Euclidean distance) // CHI_SQUARE - Chi-square distance // KL - Kullback-Leibler divergence // BHATTACHARYYA - Bhattacharyya coefficient // DOT_PRODUCT - Dot product // Create vocabulary with specific weighting and scoring const int k = 10; const int L = 5; // Option 1: Set at construction OrbVocabulary voc1(k, L, TF_IDF, L1_NORM); // Option 2: Change after construction (before training) OrbVocabulary voc2(k, L); voc2.setWeightingType(TF_IDF); voc2.setScoringType(BHATTACHARYYA); // Create with all options OrbVocabulary voc3; vector> features; // training features // ... load features ... voc3.create(features, k, L, TF_IDF, CHI_SQUARE); // Query current settings cout << "Weighting: " << voc3.getWeightingType() << endl; // 0=TF_IDF cout << "Scoring: " << voc3.getScoringType() << endl; // 2=CHI_SQUARE return 0; } ``` -------------------------------- ### DBoW2 Library and Demo Build Configuration Source: https://github.com/dorian3d/dbow2/blob/master/CMakeLists.txt Defines source files, dependencies, and build targets for the DBoW2 library and its demo application. Links against OpenCV and sets C++ standard. ```cmake set(HDRS include/DBoW2/BowVector.h include/DBoW2/FBrief.h include/DBoW2/QueryResults.h include/DBoW2/TemplatedDatabase.h include/DBoW2/FORB.h include/DBoW2/DBoW2.h include/DBoW2/FClass.h include/DBoW2/FeatureVector.h include/DBoW2/ScoringObject.h include/DBoW2/TemplatedVocabulary.h) set(SRCS src/BowVector.cpp src/FBrief.cpp src/FORB.cpp src/FeatureVector.cpp src/QueryResults.cpp src/ScoringObject.cpp) set(DEPENDENCY_DIR ${CMAKE_CURRENT_BINARY_DIR}/dependencies) set(DEPENDENCY_INSTALL_DIR ${DEPENDENCY_DIR}/install) find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) if(BUILD_DBoW2) set(LIB_SHARED "SHARED") if(WIN32) set(LIB_SHARED "STATIC") endif(WIN32) add_library(${PROJECT_NAME} ${LIB_SHARED} ${SRCS}) target_include_directories(${PROJECT_NAME} PUBLIC include/DBoW2/ include/) target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS}) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11) endif(BUILD_DBoW2) if(BUILD_Demo) add_executable(demo demo/demo.cpp) target_link_libraries(demo ${PROJECT_NAME} ${OpenCV_LIBS}) set_target_properties(demo PROPERTIES CXX_STANDARD 11) file(COPY demo/images DESTINATION ${CMAKE_BINARY_DIR}/) endif(BUILD_Demo) ``` -------------------------------- ### Load DBoW2 Vocabulary from File Source: https://context7.com/dorian3d/dbow2/llms.txt This snippet shows how to load a pre-trained DBoW2 vocabulary from a YAML file, which can be optionally gzip-compressed. It also demonstrates how to access and print various properties of the loaded vocabulary, such as its branching factor, depth levels, and scoring type. ```cpp #include "DBoW2.h" using namespace DBoW2; int main() { // Load vocabulary from file (supports .yml, .yaml, .yml.gz, .yaml.gz) OrbVocabulary voc("vocabulary.yml.gz"); // Check vocabulary properties cout << "Branching factor (k): " << voc.getBranchingFactor() << endl; cout << "Depth levels (L): " << voc.getDepthLevels() << endl; cout << "Number of words: " << voc.size() << endl; cout << "Effective levels: " << voc.getEffectiveLevels() << endl; cout << "Weighting type: " << voc.getWeightingType() << endl; cout << "Scoring type: " << voc.getScoringType() << endl; // Alternatively, create empty vocabulary and load OrbVocabulary voc2; voc2.load("vocabulary.yml.gz"); return 0; } ``` -------------------------------- ### Create DBoW2 Vocabulary with ORB Features Source: https://context7.com/dorian3d/dbow2/llms.txt This snippet demonstrates how to extract ORB features from a set of training images and use them to create a new DBoW2 vocabulary. It specifies the vocabulary's branching factor (k), depth levels (L), weighting scheme (TF_IDF), and scoring method (L1_NORM). The created vocabulary is then saved to a YAML file, optionally compressed with gzip. ```cpp #include "DBoW2.h" #include #include #include using namespace DBoW2; using namespace std; // Extract ORB features from training images vector> extractFeatures(const vector& imagePaths) { vector> features; cv::Ptr orb = cv::ORB::create(); for (const auto& path : imagePaths) { cv::Mat image = cv::imread(path, cv::IMREAD_GRAYSCALE); vector keypoints; cv::Mat descriptors; orb->detectAndCompute(image, cv::Mat(), keypoints, descriptors); // Convert descriptors to vector of single-row Mat vector imageFeatures; for (int i = 0; i < descriptors.rows; ++i) { imageFeatures.push_back(descriptors.row(i)); } features.push_back(imageFeatures); } return features; } int main() { // Load training features vector imagePaths = {"image0.png", "image1.png", "image2.png", "image3.png"}; vector> features = extractFeatures(imagePaths); // Create vocabulary with parameters: // k = 10 (branching factor) // L = 5 (depth levels) // weighting = TF_IDF // scoring = L1_NORM const int k = 10; const int L = 5; OrbVocabulary voc(k, L, TF_IDF, L1_NORM); // Train vocabulary from features voc.create(features); cout << "Vocabulary created with " << voc.size() << " words" << endl; cout << voc << endl; // Save vocabulary to file (use .gz for compression) voc.save("vocabulary.yml.gz"); return 0; } ``` -------------------------------- ### Retrieve Features from Direct Index Source: https://context7.com/dorian3d/dbow2/llms.txt Demonstrates how to retrieve feature vectors for a specific database entry when the direct index is enabled. Ensure the database is initialized with `use_di=true`. ```cpp #include "DBoW2.h" #include using namespace DBoW2; using namespace std; int main() { // Create database with direct index enabled OrbVocabulary voc("vocabulary.yml.gz"); OrbDatabase db(voc, true, 2); // use_di=true, di_levels=2 // Add images to database... // (code to extract features and add to database) // Check if direct index is being used if (db.usingDirectIndex()) { cout << "Direct index levels: " << db.getDirectIndexLevels() << endl; // Retrieve feature vector for a specific entry EntryId entryId = 0; const FeatureVector& fv = db.retrieveFeatures(entryId); // FeatureVector is a map> // where the vector contains feature indices cout << "Entry " << entryId << " has features at " << fv.size() << " nodes" << endl; for (const auto& pair : fv) { NodeId nodeId = pair.first; const vector& featureIndices = pair.second; cout << " Node " << nodeId << ": " << featureIndices.size() << " features" << endl; } } return 0; } // Output: // Direct index levels: 2 // Entry 0 has features at 45 nodes // Node 12: 3 features // Node 45: 5 features // Node 78: 2 features // ... ``` -------------------------------- ### Query Image Database for Similar Images Source: https://context7.com/dorian3d/dbow2/llms.txt Loads a previously saved database, extracts features from a query image, and searches the database for similar images using feature vectors or BowVectors. Results are printed with scores. ```cpp #include "DBoW2.h" #include #include using namespace DBoW2; using namespace std; int main() { // Load database (includes vocabulary) OrbDatabase db("database.yml.gz"); cout << "Loaded database with " << db.size() << " images" // Extract features from query image cv::Ptr orb = cv::ORB::create(); cv::Mat queryImage = cv::imread("query.png", cv::IMREAD_GRAYSCALE); vector keypoints; cv::Mat descriptors; orb->detectAndCompute(queryImage, cv::Mat(), keypoints, descriptors); vector queryFeatures; for (int i = 0; i < descriptors.rows; ++i) { queryFeatures.push_back(descriptors.row(i)); } // Query database QueryResults results; int max_results = 4; // return top 4 matches int max_id = -1; // search all entries (-1 = no limit) db.query(queryFeatures, results, max_results, max_id); // Process results cout << "Query results (Entry ID, Score):" for (const auto& result : results) { cout << " Image " << result.Id << ": score = " << result.Score << endl; } // Query with BowVector directly BowVector queryVec; db.getVocabulary()->transform(queryFeatures, queryVec); QueryResults results2; db.query(queryVec, results2, max_results, max_id); return 0; } // Output: // Loaded database with 4 images // Query results (Entry ID, Score): // Image 2: score = 0.892 // Image 1: score = 0.456 // Image 3: score = 0.312 // Image 0: score = 0.234 ``` -------------------------------- ### Complete Loop Detection Pipeline in C++ Source: https://context7.com/dorian3d/dbow2/llms.txt This C++ code implements a complete loop detection pipeline for visual SLAM. It includes feature extraction, adding images to a database, and detecting loops with a score threshold. Geometric verification can be performed using direct index features. ```cpp #include "DBoW2.h" #include #include #include #include using namespace DBoW2; using namespace std; class LoopDetector { private: OrbVocabulary voc; OrbDatabase db; cv::Ptr orb; double scoreThreshold; public: LoopDetector(const string& vocPath, double threshold = 0.3) : voc(vocPath), db(voc, true, 2), // use direct index orb(cv::ORB::create()), scoreThreshold(threshold) {} // Extract features from image vector extractFeatures(const cv::Mat& image) { vector keypoints; cv::Mat descriptors; orb->detectAndCompute(image, cv::Mat(), keypoints, descriptors); vector features; for (int i = 0; i < descriptors.rows; ++i) { features.push_back(descriptors.row(i)); } return features; } // Add new image and check for loop closure pair addAndDetect(const cv::Mat& image, int minGap = 10) { vector features = extractFeatures(image); // Add to database BowVector bowVec; FeatureVector featVec; EntryId newId = db.add(features, &bowVec, &featVec); // Query database (exclude recent images) QueryResults results; int maxId = (newId > minGap) ? newId - minGap : -1; if (maxId > 0) { db.query(bowVec, results, 1, maxId); if (!results.empty() && results[0].Score > scoreThreshold) { cout << "Loop detected! Image " << newId << " matches image " << results[0].Id << " (score: " << results[0].Score << ")" << endl; return {true, results[0].Id}; } } return {false, 0}; } // Get features for geometric verification const FeatureVector& getFeatures(EntryId id) { return db.retrieveFeatures(id); } // Save database for later use void save(const string& filename) { db.save(filename); } }; int main() { // Initialize loop detector LoopDetector detector("vocabulary.yml.gz", 0.3); // Process video frames vector framePaths; // ... load frame paths ... for (size_t i = 0; i < framePaths.size(); ++i) { cv::Mat frame = cv::imread(framePaths[i], cv::IMREAD_GRAYSCALE); auto [loopFound, matchId] = detector.addAndDetect(frame); if (loopFound) { // Perform geometric verification using direct index const FeatureVector& currentFV = detector.getFeatures(i); const FeatureVector& matchFV = detector.getFeatures(matchId); // ... geometric verification code ... } } // Save database detector.save("loop_database.yml.gz"); return 0; } ``` ```text Loop detected! Image 156 matches image 23 (score: 0.712) Loop detected! Image 312 matches image 156 (score: 0.645) ... ``` -------------------------------- ### DBoW2 CMake Configuration File Generation Source: https://github.com/dorian3d/dbow2/blob/master/CMakeLists.txt Generates the DBoW2Config.cmake file, which is essential for integrating DBoW2 into other CMake projects. This file is placed in the build directory. ```cmake configure_file(src/DBoW2.cmake.in "${PROJECT_BINARY_DIR}/DBoW2Config.cmake" @ONLY) ``` -------------------------------- ### Transform Features to Bag-of-Words Vector Source: https://context7.com/dorian3d/dbow2/llms.txt Converts image features into a sparse bag-of-words vector. Requires a loaded vocabulary and computed image descriptors. The `transform` method can also populate a `FeatureVector` for direct index usage. ```cpp #include "DBoW2.h" #include #include using namespace DBoW2; using namespace std; int main() { // Load vocabulary OrbVocabulary voc("vocabulary.yml.gz"); // Extract features from an image cv::Ptr orb = cv::ORB::create(); cv::Mat image = cv::imread("query_image.png", cv::IMREAD_GRAYSCALE); vector keypoints; cv::Mat descriptors; orb->detectAndCompute(image, cv::Mat(), keypoints, descriptors); // Convert to vector of single descriptors vector features; for (int i = 0; i < descriptors.rows; ++i) { features.push_back(descriptors.row(i)); } // Transform features to bag-of-words vector BowVector bowVector; voc.transform(features, bowVector); // BowVector is a map cout << "Bag-of-words vector has " << bowVector.size() << " non-zero words" << endl; cout << "First 5 word-weight pairs:" << endl; int count = 0; for (const auto& pair : bowVector) { cout << " Word " << pair.first << ": " << pair.second << endl; if (++count >= 5) break; } // Transform with feature vector (for direct index usage) BowVector bowVec2; FeatureVector featureVec; int levelsup = 2; // levels to go up from leaves for node grouping voc.transform(features, bowVec2, featureVec, levelsup); return 0; } // Output: // Bag-of-words vector has 156 non-zero words // First 5 word-weight pairs: // Word 42: 0.0234 // Word 156: 0.0189 // Word 287: 0.0412 // Word 512: 0.0156 // Word 623: 0.0278 ``` -------------------------------- ### Define Templated Vocabulary and Database Classes Source: https://github.com/dorian3d/dbow2/blob/master/README.md The core classes TemplatedVocabulary and TemplatedDatabase require a descriptor type and a feature manipulation class. ```C++ template class TemplatedVocabulary { ... }; template class TemplatedDatabase { ... }; ``` -------------------------------- ### Cite DBoW2 in Academic Work Source: https://github.com/dorian3d/dbow2/blob/master/README.md Use this BibTeX entry to cite the DBoW2 library in academic publications. ```BibTeX @ARTICLE{GalvezTRO12, author={G\'alvez-L\'opez, Dorian and Tard\'os, J. D.}, journal={IEEE Transactions on Robotics}, title={Bags of Binary Words for Fast Place Recognition in Image Sequences}, year={2012}, month={October}, volume={28}, number={5}, pages={1188--1197}, doi={10.1109/TRO.2012.2197158}, ISSN={1552-3098} } ``` -------------------------------- ### Compute Image Similarity Scores Source: https://context7.com/dorian3d/dbow2/llms.txt Calculates the similarity between two bag-of-words vectors using the vocabulary's `score` method. Scores are normalized to [0..1], with 1 indicating identical images. This is useful for comparing multiple images. ```cpp #include "DBoW2.h" #include #include using namespace DBoW2; using namespace std; int main() { // Load vocabulary OrbVocabulary voc("vocabulary.yml.gz"); // Extract features from multiple images cv::Ptr orb = cv::ORB::create(); vector imagePaths = {"image0.png", "image1.png", "image2.png", "image3.png"}; vector bowVectors; for (const auto& path : imagePaths) { cv::Mat image = cv::imread(path, cv::IMREAD_GRAYSCALE); vector keypoints; cv::Mat descriptors; orb->detectAndCompute(image, cv::Mat(), keypoints, descriptors); vector features; for (int i = 0; i < descriptors.rows; ++i) { features.push_back(descriptors.row(i)); } BowVector v; voc.transform(features, v); bowVectors.push_back(v); } // Compare all image pairs cout << "Image similarity matrix (0=different, 1=identical):" << endl; for (size_t i = 0; i < bowVectors.size(); ++i) { for (size_t j = 0; j < bowVectors.size(); ++j) { double score = voc.score(bowVectors[i], bowVectors[j]); cout << fixed << setprecision(3) << score << " "; } cout << endl; } return 0; } // Output: // Image similarity matrix (0=different, 1=identical): // 1.000 0.234 0.187 0.156 // 0.234 1.000 0.312 0.201 // 0.187 0.312 1.000 0.245 // 0.156 0.201 0.245 1.000 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.