基于下载的DBoW3源码DBow3-master\DBow3-master\utils路径下的demo_general.cpp修改
需要调用的库:https://blog.csdn.net/Z5122/article/details/83998692
/**
* Date: 2016
* Author: Rafael Muñoz Salinas
* Description: demo application of DBoW3
* License: see the LICENSE.txt file
*/
#include <iostream>
#include <io.h>
#include <vector>
// DBoW3
#include "DBoW3.h"
// OpenCV
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>
#include <opencv2/xfeatures2d.hpp>
#include "DescManip.h"
using namespace DBoW3;
using namespace std;
void getFiles(string path, vector<string>& files)
{
long long hFile = 0;
struct _finddata_t fileinfo;
string p;
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
getFiles(p.assign(path).append("\\").append(fileinfo.name), files);
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));
}
}while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
std::vector<string> path_to_images;
string path = "设置数据集路径";
vector< cv::Mat > loadFeatures(std::vector<string> path_to_images, string descriptor = "") throw (std::exception) {
cv::Ptr<cv::Feature2D> fdetector;
if (descriptor == "orb")
fdetector = cv::ORB::create();
else if (descriptor == "brisk")
fdetector = cv::BRISK::create();
else if (descriptor == "surf") fdetector = cv::xfeatures2d::SURF::create(1000);
else throw std::runtime_error("Invalid descriptor");
assert(!descriptor.empty());
vector<cv::Mat> features;
cout << "Extracting features..." << endl;
for (size_t i = 0; i < path_to_images.size(); ++i)
{
vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
cout << "reading image: " << path_to_images[i] << endl;
cv::Mat image = cv::imread(path_to_images[i], 0);
if (image.empty())throw std::runtime_error("Could not open image" + path_to_images[i]);
cout << "extracting features" << endl;
fdetector->detectAndCompute(image, cv::Mat(), keypoints, descriptors);
features.push_back(descriptors);
cout << "done detecting features" << endl;
}
return features;
}
void testVocCreation(const vector<cv::Mat> &features)
{
// 设置词汇树参数
const int k = 9;
const int L = 3;
const WeightingType weight = TF_IDF;
const ScoringType score = L1_NORM;
DBoW3::Vocabulary voc(k, L, weight, score);
cout << "Creating a small " << k << "^" << L << " vocabulary..." << endl;
voc.create(features);
cout << "... done!" << endl;
cout << "Vocabulary information: " << endl
<< voc << endl << endl;
cout << "Matching images against themselves (0 low, 1 high): " << endl;
BowVector v1, v2;
for (size_t i = 0; i < features.size(); i++)
{
voc.transform(features[i], v1);
for (size_t j = 0; j < features.size(); j++)
{
voc.transform(features[j], v2);
double score = voc.score(v1, v2);
cout << "Image " << i << " vs Image " << j << ": " << score << endl;
}
}
// save the vocabulary to disk
cout << endl << "Saving vocabulary..." << endl;
voc.save("设置保存small_voc.yml.gz的路径");
cout << "Done" << endl;
}
void testDatabase(const vector<cv::Mat > &features)
{
cout << "Creating a small database..." << endl;
Vocabulary voc("设置加载small_voc.yml.gz的路径");
Database db(voc, false, 0);
for (size_t i = 0; i < features.size(); i++)
db.add(features[i]);
cout << "... done!" << endl;
cout << "Database information: " << endl << db << endl;
cout << "Querying the database: " << endl;
QueryResults ret;
for (size_t i = 0; i < features.size(); i++)
{
db.query(features[i], ret, 4);
cout << "Searching for Image " << i << ". " << ret << endl;
}
cout << endl;
cout << "Saving database..." << endl;
db.save("设置保存small_db.yml.gz的路径");
cout << "... done!" << endl;
cout << "Retrieving database once again..." << endl;
Database db2("C:\\Users\\sggzg\\Desktop\\small_db.yml.gz");
cout << "... done! This is: " << endl << db2 << endl;
}
int main(int argc, char **argv)
{
string descriptor = "surf";
getFiles(path, path_to_images);
vector<cv::Mat> features = loadFeatures(path_to_images, descriptor);
testVocCreation(features);
testDatabase(features);
return 0;
}
训练之后可以生成small_voc.yml和small_db.yml两个压缩包