一、安装DBoW3
git clone https://github.com/rmsalinas/DBow3
mkdir build
cd build
cmake ..
make -j4
sudo make install
二、编译运行过程中出现的问题汇总及解决办法
1.在使用cmake ..时出现CMake Error at CMakeLists.txt:8 (find_package):
Could not find a configuration file for package "OpenCV" that is compatible
with requested version "3.1".的错误,原因在于下载的源代码的CMakeList.txt文件中使用的opencv版本规定了为3.1。解决方法是将opencv后面3.1去掉就可以,具体改好后如下所示:
# opencv
#find_package( OpenCV 3.1 REQUIRED )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
2.使用make时出现make[2]: *** 没有规则可制作目标“/usr/local/lib/libDBoW3.a”,由“feature_training” 需求。 停止。
make[1]: *** [CMakeFiles/Makefile2:76:CMakeFiles/feature_training.dir/all] 错误 2
make: *** [Makefile:84:all] 错误 2的错误。原因在于下载的DBoW3中没有这个文件,就是说/usr/local/lib/libDBoW3.a这个静态库文件不存在。这是由于动态库链接中断造成的,我们在相应的文件目录下看看该文件的状态,但是观察到这个路径下有共享库,因此这个好解决,把其改为共享库:
# dbow3
# dbow3 is a simple lib so I assume you installed it in default directory
set( DBoW3_INCLUDE_DIRS "/usr/local/include" )
# set( DBoW3_LIBS "/usr/local/lib/libDBoW3.a" )
set( DBoW3_LIBS "/usr/local/lib/libDBoW3.so" )
add_executable( feature_training feature_training.cpp )
target_link_libraries( feature_training ${OpenCV_LIBS} ${DBoW3_LIBS} )
3.在执行命令 ./feature_training 时出现reading images...
[ WARN:0@0.067] global /home/l/opencv_build/opencv/modules/imgcodecs/src/loadsave.cpp (244) findDecoder imread_('./data/1.png'): can't open/read file: check file path/integrity错误,具体完整错误如下所示:
原因在于feature_training.cpp源代码中读取图片的路径有问题原读取图片路径如下
string path = "./data/"+to_string(i+1)+".png";
这里需要把data文件路径改为绝对路径就可以,具体做法是找到data文件,在终端打开,使用命令pwd即可打印data文件路径,在我的电脑上改好后为
string path = "/home/l/learn_slam/ch11/data/"+to_string(i+1)+".png";
改好后再次执行就可以成功运行,下面是成功运行的截图
对于loop_closure.cpp和gen_vocab_large.cpp同样需要改对应文件的路径,具体改法同上。在loop_closure.cpp需要改两处,在我的电脑上改好后如下:
int main(int argc, char **argv) {
// read the images and database
cout << "reading database" << endl;
DBoW3::Vocabulary vocab("/home/l/learn_slam/ch11/vocabulary.yml.gz");
// DBoW3::Vocabulary vocab("./vocab_larger.yml.gz"); // use large vocab if you want:
if (vocab.empty()) {
cerr << "Vocabulary does not exist." << endl;
return 1;
}
cout << "reading images... " << endl;
vector<Mat> images;
for (int i = 0; i < 10; i++) {
string path = "/home/l/learn_slam/ch11/data/"+to_string(i+1)+".png";
images.push_back(imread(path));
}
改好后成功运行结果如下图所示(以下是没有增加词典的情况下运行的结果)
4. 在执行./gen_vocab 命令时出现terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid 已放弃 (核心已转储)的问题,具体见下图:
出现这个的问题我查找了一下相关的问题,好像是由于传入一个空指针导致的 ,对比源代码好像是在下面代码出有问题,因为整个文件夹里面没有涉及到文件associate.txt,所以才会出现上述错误。具体修改后的代码如下面第二个所示。这个地方由于自己也是初学,还没弄太明白 ,具体大家可以参考这篇文章http://t.csdn.cn/dmoBc,或者找对于问题。
int main( int argc, char** argv )
{
string dataset_dir = argv[1];
ifstream fin ( dataset_dir+"/associate.txt" );
if ( !fin )
{
cout<<"please generate the associate file called associate.txt!"<<endl;
return 1;
}
vector<string> rgb_files, depth_files;
vector<double> rgb_times, depth_times;
while ( !fin.eof() )
{
string rgb_time, rgb_file, depth_time, depth_file;
fin>>rgb_time>>rgb_file>>depth_time>>depth_file;
rgb_times.push_back ( atof ( rgb_time.c_str() ) );
depth_times.push_back ( atof ( depth_time.c_str() ) );
rgb_files.push_back ( dataset_dir+"/"+rgb_file );
depth_files.push_back ( dataset_dir+"/"+depth_file );
if ( fin.good() == false )
break;
}
fin.close();
#include "DBoW3/DBoW3.h"//词袋支持头文件
#include <opencv2/core/core.hpp>//opencv核心模块
#include <opencv2/highgui/highgui.hpp>//gui模块
#include <opencv2/features2d/features2d.hpp>//特征点头文件
#include <iostream>
#include <vector>
#include <string>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
String directoryPath = "/home/l/learn_slam/ch11/data";//图像路径
vector<String> imagesPath;
glob(directoryPath, imagesPath);
// string dataset_dir = argv[1];
// ifstream fin ( dataset_dir+"/home/liqiang/slambook2/ch11/rgbd_dataset_freiburg1_desk2/rgb" );
// if ( !fin )
// {
// cout<<"please generate the associate file called associate.txt!"<<endl;
// return 1;
// }
// vector<string> rgb_files, depth_files;
// vector<double> rgb_times, depth_times;
// while ( !fin.eof() )
// {
// string rgb_time, rgb_file, depth_time, depth_file;
// fin>>rgb_time>>rgb_file>>depth_time>>depth_file;
// rgb_times.push_back ( atof ( rgb_time.c_str() ) );
// depth_times.push_back ( atof ( depth_time.c_str() ) );
// rgb_files.push_back ( dataset_dir+"/"+rgb_file );
// depth_files.push_back ( dataset_dir+"/"+depth_file );
// if ( fin.good() == false )
// break;
// }
// fin.close();
cout<<"generating features ... "<<endl;//输出generating features (正在检测ORB特征)...
vector<Mat> descriptors;//描述子
Ptr< Feature2D > detector = ORB::create();
int index = 1;
for ( String path : imagesPath )
{
Mat image = imread(path);
vector<KeyPoint> keypoints; //关键点
Mat descriptor;//描述子
detector->detectAndCompute( image, Mat(), keypoints, descriptor );
descriptors.push_back( descriptor );
cout<<"extracting features from image " << index++ <<endl;//输出extracting features from image(从图像中提取特征)
}
cout<<"extract total "<<descriptors.size()*500<<" features."<<endl;
// create vocabulary
cout<<"creating vocabulary, please wait ... "<<endl;//输出creating vocabulary, please wait (创建词典,请稍等)...
DBoW3::Vocabulary vocab;
vocab.create( descriptors );
cout<<"vocabulary info: "<<vocab<<endl;
vocab.save( "vocab_larger.yml.gz" );//保存词典
cout<<"done"<<endl;
return 0;
}
其中传入的图片路径就是data文件下的图片路劲,改为你电脑上图片路径即可,再次执行,即可运行成功,具体如下:
都运行成功后在build文件夹下面会有如下两个字典压缩包,具体如下: