当前位置:   article > 正文

视觉SLAM十四讲CH11代码解析及课后习题详解_gen_vocab

gen_vocab

 如果没有安装DBoW3,直接编译会报下面的错误:

  1. fatal error: DBoW3/DBoW3.h: No such file or directory
  2. #include "DBoW3/DBoW3.h"
  3. ^~~~~~~~~~~~~~~
  4. compilation terminated.
  5. CMakeFiles/gen_vocab.dir/build.make:82: recipe for target 'CMakeFiles/gen_vocab.dir/gen_vocab_large.cpp.o' failed
  6. make[2]: *** [CMakeFiles/gen_vocab.dir/gen_vocab_large.cpp.o] Error 1
  7. CMakeFiles/Makefile2:99: recipe for target 'CMakeFiles/gen_vocab.dir/all' failed
  8. make[1]: *** [CMakeFiles/gen_vocab.dir/all] Error 2
  9. Makefile:103: recipe for target 'all' failed
  10. make: *** [all] Error 2

在进行编译程序前,先需要安装DBoW,第二版的安装文件下载链接如下所示:

https://github.com/rmsalinas/DBow3https://github.com/rmsalinas/DBow3下载完成后,安装方法很简单,将文件存放在你想存放的文件夹里面,进入DBoW-master文件夹:

mkdir build
cd build
cmake ..
make -j4
sudo make install

 在编译CH11的时候,出现了下面的错误:

  1. make[2]: *** No rule to make target '/usr/local/lib/libDBoW3.a', needed by 'loop_closure'. Stop.
  2. make[1]: *** [CMakeFiles/Makefile2:80: CMakeFiles/loop_closure.dir/all] Error 2
  3. make: *** [Makefile:84: all] Error 2

问题是找不到libDBoW3.a这个文件,于是我用第一版的里面/home/liqiang/slambook/3rdparty中的DBow3.tar.gz来进行安装,下载链接如下所示:

GitHub - gaoxiang12/slambook

安装方法和上面是一样的。

feature_training.cpp

  1. #include "DBoW3/DBoW3.h"//词袋支持头文件
  2. #include <opencv2/core/core.hpp>//opencv核心模块
  3. #include <opencv2/highgui/highgui.hpp>//gui模块
  4. #include <opencv2/features2d/features2d.hpp>//特征点头文件
  5. #include <iostream>
  6. #include <vector>
  7. #include <string>
  8. using namespace cv;
  9. using namespace std;
  10. /***************************************************
  11. * 本节演示了如何根据data/目录下的十张图训练字典
  12. * ************************************************/
  13. int main( int argc, char** argv )
  14. {
  15. // read the image
  16. cout<<"reading images... "<<endl;//输出reading images...
  17. vector<Mat> images; //图像
  18. for ( int i=0; i<10; i++ )//遍历读取十张图像
  19. {
  20. string path = "./data/"+to_string(i+1)+".png";
  21. images.push_back( imread(path) );
  22. }
  23. // detect ORB features
  24. cout<<"detecting ORB features ... "<<endl;//输出detecting ORB features(正在检测ORB特征) ...
  25. Ptr< Feature2D > detector = ORB::create();
  26. vector<Mat> descriptors;//描述子
  27. for ( Mat& image:images )
  28. {
  29. vector<KeyPoint> keypoints; //关键点
  30. Mat descriptor;//描述子
  31. detector->detectAndCompute( image, Mat(), keypoints, descriptor );//检测和计算
  32. descriptors.push_back( descriptor );
  33. }
  34. // create vocabulary (创建字典)
  35. cout<<"creating vocabulary ... "<<endl;//输出(creating vocabulary ...)创建字典
  36. DBoW3::Vocabulary vocab;//默认构造函数 k=10,d=5
  37. vocab.create( descriptors );
  38. cout<<"vocabulary info: "<<vocab<<endl;//字典信息
  39. vocab.save( "vocabulary.yml.gz" );//保存字典压缩包
  40. cout<<"done"<<endl;//输出done
  41. return 0;
  42. }

CMakeLists.txt

  1. cmake_minimum_required( VERSION 2.8 )
  2. project( loop_closure )
  3. set( CMAKE_BUILD_TYPE "Release" )
  4. set( CMAKE_CXX_FLAGS "-std=c++14 -O3" )
  5. # opencv
  6. find_package( OpenCV 3.1 REQUIRED )
  7. include_directories( ${OpenCV_INCLUDE_DIRS} )
  8. # dbow3
  9. # dbow3 is a simple lib so I assume you installed it in default directory
  10. set( DBoW3_INCLUDE_DIRS "/usr/local/include" )
  11. set( DBoW3_LIBS "/usr/local/lib/libDBoW3.a" )
  12. add_executable( feature_training feature_training.cpp )
  13. target_link_libraries( feature_training ${OpenCV_LIBS} ${DBoW3_LIBS} )
  14. add_executable( loop_closure loop_closure.cpp )
  15. target_link_libraries( loop_closure ${OpenCV_LIBS} ${DBoW3_LIBS} )
  16. add_executable( gen_vocab gen_vocab_large.cpp )
  17. target_link_libraries( gen_vocab ${OpenCV_LIBS} ${DBoW3_LIBS} )

执行结果:

 ./feature_training ../data/
  1. reading images...
  2. detecting ORB features ...
  3. creating vocabulary ...
  4. vocabulary info: Vocabulary: k = 10, L = 5, Weighting = tf-idf, Scoring = L1-norm, Number of words = 0
  5. done

 这里出现了Number of words = 0,明显是错误的,通过检查程序,是读取data文件夹里面的数据路径有点小问题,修改:

在路径里面多加上一个 . 就可以了。

修改程序后执行结果如下所示:

  1. reading images...
  2. detecting ORB features ...
  3. creating vocabulary ...
  4. vocabulary info: Vocabulary: k = 10, L = 5, Weighting = tf-idf, Scoring = L1-norm, Number of words = 4981
  5. done

其中weight是权重, Scoring指的是评分。

loop_closure.cpp

  1. #include "DBoW3/DBoW3.h"//词袋支持头文件
  2. #include <opencv2/core/core.hpp>//opencv核心模块
  3. #include <opencv2/highgui/highgui.hpp>//gui模块
  4. #include <opencv2/features2d/features2d.hpp>//特征点头文件
  5. #include <iostream>
  6. #include <vector>
  7. #include <string>
  8. using namespace cv;
  9. using namespace std;
  10. /***************************************************
  11. * 本节演示了如何根据前面训练的字典计算相似性评分
  12. * ************************************************/
  13. int main(int argc, char **argv) {
  14. // read the images and database(读取图像和数据库)
  15. cout << "reading database" << endl;//输出reading database(读取数据)
  16. DBoW3::Vocabulary vocab("../vocabulary.yml.gz");//vocabulary.yml.gz路径
  17. // DBoW3::Vocabulary vocab("./vocab_larger.yml.gz"); // use large vocab if you want:
  18. if (vocab.empty()) {
  19. cerr << "Vocabulary does not exist." << endl;//输出Vocabulary does not exist
  20. return 1;
  21. }
  22. cout << "reading images... " << endl;//输出reading images...
  23. vector<Mat> images;
  24. for (int i = 0; i < 10; i++) {
  25. string path = "../data/" + to_string(i + 1) + ".png";//图像读取路径
  26. images.push_back(imread(path));
  27. }
  28. // NOTE: in this case we are comparing images with a vocabulary generated by themselves, this may lead to overfit. 这里我们用它们生成的字典比较它们本身的相似性,这可能会产生过拟合
  29. // detect ORB features
  30. cout << "detecting ORB features ... " << endl;//输出detecting ORB features ...(正在检测ORB特征)
  31. Ptr<Feature2D> detector = ORB::create();//默认图像500个特征点
  32. vector<Mat> descriptors;//描述子 将10张图像提取ORB特征并存放在vector容器里
  33. for (Mat &image:images) {
  34. vector<KeyPoint> keypoints;//关键点
  35. Mat descriptor;//描述子
  36. detector->detectAndCompute(image, Mat(), keypoints, descriptor);//检测和计算
  37. descriptors.push_back(descriptor);
  38. }
  39. // we can compare the images directly or we can compare one image to a database
  40. // images :
  41. cout << "comparing images with images " << endl;//输出comparing images with images
  42. for (int i = 0; i < images.size(); i++)
  43. {
  44. DBoW3::BowVector v1;
  45. //descriptors[i]表示图像i中所有的ORB描述子集合,函数transform()计算出用先前字典来描述的单词向量,每个向量中元素的值要么是0,表示图像i中没有这个单词;要么是该单词的权重
  46. //BoW描述向量中含有每个单词的ID和权重,两者构成了整个稀疏的向量
  47. //当比较两个向量时,DBoW3会为我们计算一个分数
  48. vocab.transform(descriptors[i], v1);
  49. for (int j = i; j < images.size(); j++)
  50. {
  51. DBoW3::BowVector v2;
  52. vocab.transform(descriptors[j], v2);
  53. double score = vocab.score(v1, v2);//p296式(11.9)
  54. cout << "image " << i << " vs image " << j << " : " << score << endl;//输出一幅图像与另外一幅图像之间的相似度评分
  55. }
  56. cout << endl;
  57. }
  58. // or with database
  59. //在进行数据库查询时,DBoW对上面的分数进行排序,给出最相似的结果
  60. cout << "comparing images with database " << endl;
  61. DBoW3::Database db(vocab, false, 0);
  62. for (int i = 0; i < descriptors.size(); i++)
  63. db.add(descriptors[i]);
  64. cout << "database info: " << db << endl;//输出database info(数据库信息)为
  65. for (int i = 0; i < descriptors.size(); i++)
  66. {
  67. DBoW3::QueryResults ret;
  68. db.query(descriptors[i], ret, 4); // max result=4
  69. cout << "searching for image " << i << " returns " << ret << endl << endl;
  70. }
  71. cout << "done." << endl;
  72. }

CMakeLists.txt

和上面一样的。

执行结果:

在Ubuntu20.04执行的时候:

  1. reading database
  2. reading images...
  3. detecting ORB features ...
  4. comparing images with images
  5. image 0 vs image 0 : 1
  6. image 0 vs image 1 : 0.0322942
  7. image 0 vs image 2 : 0.0348326
  8. image 0 vs image 3 : 0.0292106
  9. image 0 vs image 4 : 0.0307606
  10. image 0 vs image 5 : 0.0386504
  11. image 0 vs image 6 : 0.0267389
  12. image 0 vs image 7 : 0.0254779
  13. image 0 vs image 8 : 0.041301
  14. image 0 vs image 9 : 0.0501515
  15. image 1 vs image 1 : 1
  16. image 1 vs image 2 : 0.041587
  17. image 1 vs image 3 : 0.034046
  18. image 1 vs image 4 : 0.0318553
  19. image 1 vs image 5 : 0.0354084
  20. image 1 vs image 6 : 0.0221539
  21. image 1 vs image 7 : 0.0296462
  22. image 1 vs image 8 : 0.0397894
  23. image 1 vs image 9 : 0.0306703
  24. image 2 vs image 2 : 1
  25. image 2 vs image 3 : 0.0322172
  26. image 2 vs image 4 : 0.0371113
  27. image 2 vs image 5 : 0.0338423
  28. image 2 vs image 6 : 0.0360772
  29. image 2 vs image 7 : 0.044198
  30. image 2 vs image 8 : 0.0354693
  31. image 2 vs image 9 : 0.0351865
  32. image 3 vs image 3 : 1
  33. image 3 vs image 4 : 0.0278296
  34. image 3 vs image 5 : 0.0338019
  35. image 3 vs image 6 : 0.0349277
  36. image 3 vs image 7 : 0.0294855
  37. image 3 vs image 8 : 0.0299692
  38. image 3 vs image 9 : 0.0469051
  39. image 4 vs image 4 : 1
  40. image 4 vs image 5 : 0.0630388
  41. image 4 vs image 6 : 0.0355424
  42. image 4 vs image 7 : 0.0294301
  43. image 4 vs image 8 : 0.0295447
  44. image 4 vs image 9 : 0.026492
  45. image 5 vs image 5 : 1
  46. image 5 vs image 6 : 0.0365682
  47. image 5 vs image 7 : 0.0275375
  48. image 5 vs image 8 : 0.0309867
  49. image 5 vs image 9 : 0.0337013
  50. image 6 vs image 6 : 1
  51. image 6 vs image 7 : 0.0297398
  52. image 6 vs image 8 : 0.0345615
  53. image 6 vs image 9 : 0.0337139
  54. image 7 vs image 7 : 1
  55. image 7 vs image 8 : 0.0182667
  56. image 7 vs image 9 : 0.0225071
  57. image 8 vs image 8 : 1
  58. image 8 vs image 9 : 0.0432488
  59. image 9 vs image 9 : 1

 出现了下面的这个报错,也不知道是为什么,换了台电脑,Ubuntu18.04就可以了,完全一样的代码(暂时未想明白)

  1. comparing images with database
  2. terminate called after throwing an instance of 'std::length_error'
  3. what(): cannot create std::vector larger than max_size()
  4. Aborted (core dumped)

 下面是Ubuntu18.04上得出的结果:

./loop_closure 
  1. reading database
  2. reading images...
  3. detecting ORB features ...
  4. comparing images with images
  5. image 0 vs image 0 : 1
  6. image 0 vs image 1 : 0.0322942
  7. image 0 vs image 2 : 0.0348326
  8. image 0 vs image 3 : 0.0292106
  9. image 0 vs image 4 : 0.0307606
  10. image 0 vs image 5 : 0.0386504
  11. image 0 vs image 6 : 0.0267389
  12. image 0 vs image 7 : 0.0254779
  13. image 0 vs image 8 : 0.041301
  14. image 0 vs image 9 : 0.0501515
  15. image 1 vs image 1 : 1
  16. image 1 vs image 2 : 0.041587
  17. image 1 vs image 3 : 0.034046
  18. image 1 vs image 4 : 0.0318553
  19. image 1 vs image 5 : 0.0354084
  20. image 1 vs image 6 : 0.0221539
  21. image 1 vs image 7 : 0.0296462
  22. image 1 vs image 8 : 0.0397894
  23. image 1 vs image 9 : 0.0306703
  24. image 2 vs image 2 : 1
  25. image 2 vs image 3 : 0.0322172
  26. image 2 vs image 4 : 0.0371113
  27. image 2 vs image 5 : 0.0338423
  28. image 2 vs image 6 : 0.0360772
  29. image 2 vs image 7 : 0.044198
  30. image 2 vs image 8 : 0.0354693
  31. image 2 vs image 9 : 0.0351865
  32. image 3 vs image 3 : 1
  33. image 3 vs image 4 : 0.0278296
  34. image 3 vs image 5 : 0.0338019
  35. image 3 vs image 6 : 0.0349277
  36. image 3 vs image 7 : 0.0294855
  37. image 3 vs image 8 : 0.0299692
  38. image 3 vs image 9 : 0.0469051
  39. image 4 vs image 4 : 1
  40. image 4 vs image 5 : 0.0630388
  41. image 4 vs image 6 : 0.0355424
  42. image 4 vs image 7 : 0.0294301
  43. image 4 vs image 8 : 0.0295447
  44. image 4 vs image 9 : 0.026492
  45. image 5 vs image 5 : 1
  46. image 5 vs image 6 : 0.0365682
  47. image 5 vs image 7 : 0.0275375
  48. image 5 vs image 8 : 0.0309867
  49. image 5 vs image 9 : 0.0337013
  50. image 6 vs image 6 : 1
  51. image 6 vs image 7 : 0.0297398
  52. image 6 vs image 8 : 0.0345615
  53. image 6 vs image 9 : 0.0337139
  54. image 7 vs image 7 : 1
  55. image 7 vs image 8 : 0.0182667
  56. image 7 vs image 9 : 0.0225071
  57. image 8 vs image 8 : 1
  58. image 8 vs image 9 : 0.0432488
  59. image 9 vs image 9 : 1
  60. comparing images with database
  61. database info: Database: Entries = 10, Using direct index = no. Vocabulary: k = 10, L = 5, Weighting = tf-idf, Scoring = L1-norm, Number of words = 4983
  62. searching for image 0 returns 4 results:
  63. <EntryId: 0, Score: 1>
  64. <EntryId: 9, Score: 0.0501515>
  65. <EntryId: 8, Score: 0.041301>
  66. <EntryId: 5, Score: 0.0386504>
  67. searching for image 1 returns 4 results:
  68. <EntryId: 1, Score: 1>
  69. <EntryId: 2, Score: 0.041587>
  70. <EntryId: 8, Score: 0.0397894>
  71. <EntryId: 5, Score: 0.0354084>
  72. searching for image 2 returns 4 results:
  73. <EntryId: 2, Score: 1>
  74. <EntryId: 7, Score: 0.044198>
  75. <EntryId: 1, Score: 0.041587>
  76. <EntryId: 4, Score: 0.0371113>
  77. searching for image 3 returns 4 results:
  78. <EntryId: 3, Score: 1>
  79. <EntryId: 9, Score: 0.0469051>
  80. <EntryId: 6, Score: 0.0349277>
  81. <EntryId: 1, Score: 0.034046>
  82. searching for image 4 returns 4 results:
  83. <EntryId: 4, Score: 1>
  84. <EntryId: 5, Score: 0.0630388>
  85. <EntryId: 2, Score: 0.0371113>
  86. <EntryId: 6, Score: 0.0355424>
  87. searching for image 5 returns 4 results:
  88. <EntryId: 5, Score: 1>
  89. <EntryId: 4, Score: 0.0630388>
  90. <EntryId: 0, Score: 0.0386504>
  91. <EntryId: 6, Score: 0.0365682>
  92. searching for image 6 returns 4 results:
  93. <EntryId: 6, Score: 1>
  94. <EntryId: 5, Score: 0.0365682>
  95. <EntryId: 2, Score: 0.0360772>
  96. <EntryId: 4, Score: 0.0355424>
  97. searching for image 7 returns 4 results:
  98. <EntryId: 7, Score: 1>
  99. <EntryId: 2, Score: 0.044198>
  100. <EntryId: 6, Score: 0.0297398>
  101. <EntryId: 1, Score: 0.0296462>
  102. searching for image 8 returns 4 results:
  103. <EntryId: 8, Score: 1>
  104. <EntryId: 9, Score: 0.0432488>
  105. <EntryId: 0, Score: 0.041301>
  106. <EntryId: 1, Score: 0.0397894>
  107. searching for image 9 returns 4 results:
  108. <EntryId: 9, Score: 1>
  109. <EntryId: 0, Score: 0.0501515>
  110. <EntryId: 3, Score: 0.0469051>
  111. <EntryId: 8, Score: 0.0432488>
  112. done.

gen_vocab_large.cpp

书上的代码执行时,会报下面的错误,代码里面所描述的txt文件在文件夹下面也没有,具体是什么地方有问题也不太清楚。

  1. terminate called after throwing an instance of 'std::logic_error'
  2. what(): basic_string::_M_construct null not valid
  3. Aborted (core dumped)

对代码进行一点修改:

  1. #include "DBoW3/DBoW3.h"//词袋支持头文件
  2. #include <opencv2/core/core.hpp>//opencv核心模块
  3. #include <opencv2/highgui/highgui.hpp>//gui模块
  4. #include <opencv2/features2d/features2d.hpp>//特征点头文件
  5. #include <iostream>
  6. #include <vector>
  7. #include <string>
  8. using namespace cv;
  9. using namespace std;
  10. int main( int argc, char** argv )
  11. {
  12. String directoryPath = "/home/liqiang/slambook2/ch11/rgbd_dataset_freiburg1_desk2/rgb";//图像路径
  13. vector<String> imagesPath;
  14. glob(directoryPath, imagesPath);
  15. // string dataset_dir = argv[1];
  16. // ifstream fin ( dataset_dir+"/home/liqiang/slambook2/ch11/rgbd_dataset_freiburg1_desk2/rgb" );
  17. // if ( !fin )
  18. // {
  19. // cout<<"please generate the associate file called associate.txt!"<<endl;
  20. // return 1;
  21. // }
  22. // vector<string> rgb_files, depth_files;
  23. // vector<double> rgb_times, depth_times;
  24. // while ( !fin.eof() )
  25. // {
  26. // string rgb_time, rgb_file, depth_time, depth_file;
  27. // fin>>rgb_time>>rgb_file>>depth_time>>depth_file;
  28. // rgb_times.push_back ( atof ( rgb_time.c_str() ) );
  29. // depth_times.push_back ( atof ( depth_time.c_str() ) );
  30. // rgb_files.push_back ( dataset_dir+"/"+rgb_file );
  31. // depth_files.push_back ( dataset_dir+"/"+depth_file );
  32. // if ( fin.good() == false )
  33. // break;
  34. // }
  35. // fin.close();
  36. cout<<"generating features ... "<<endl;//输出generating features (正在检测ORB特征)...
  37. vector<Mat> descriptors;//描述子
  38. Ptr< Feature2D > detector = ORB::create();
  39. int index = 1;
  40. for ( String path : imagesPath )
  41. {
  42. Mat image = imread(path);
  43. vector<KeyPoint> keypoints; //关键点
  44. Mat descriptor;//描述子
  45. detector->detectAndCompute( image, Mat(), keypoints, descriptor );
  46. descriptors.push_back( descriptor );
  47. cout<<"extracting features from image " << index++ <<endl;//输出extracting features from image(从图像中提取特征)
  48. }
  49. cout<<"extract total "<<descriptors.size()*500<<" features."<<endl;
  50. // create vocabulary
  51. cout<<"creating vocabulary, please wait ... "<<endl;//输出creating vocabulary, please wait (创建词典,请稍等)...
  52. DBoW3::Vocabulary vocab;
  53. vocab.create( descriptors );
  54. cout<<"vocabulary info: "<<vocab<<endl;
  55. vocab.save( "vocab_larger.yml.gz" );//保存词典
  56. cout<<"done"<<endl;
  57. return 0;
  58. }

 其中,图像路径那里需要下载数据集,下载地址如下:

Computer Vision Group - Dataset Download

CMakeLists.txt

和上面一样。

执行结果:

  1. ./gen_vocab
  2. generating features ...
  3. extracting features from image 1
  4. extracting features from image 2
  5. extracting features from image 3
  6. extracting features from image 4
  7. extracting features from image 5
  8. extracting features from image 6
  9. extracting features from image 7
  10. extracting features from image 8
  11. extracting features from image 9
  12. extracting features from image 10
  13. .....
  14. extracting features from image 634
  15. extracting features from image 635
  16. extracting features from image 636
  17. extracting features from image 637
  18. extracting features from image 638
  19. extracting features from image 639
  20. extracting features from image 640
  21. extract total 320000 features.
  22. creating vocabulary, please wait ...
  23. vocabulary info: Vocabulary: k = 10, L = 5, Weighting = tf-idf, Scoring = L1-norm, Number of words = 89315
  24. done

执行完毕后,会在build文件夹下面生成一个vocab_larger.yml.gz,然后可以使用这个词典再执行loop_closure.cpp,只需要将loop_closure.cpp内容中词典内容修改一下就ok了。

 再次执行loop_closure.cpp,得到的执行结果如下所示:

  1. reading database
  2. reading images...
  3. detecting ORB features ...
  4. comparing images with images
  5. image 0 vs image 0 : 1
  6. image 0 vs image 1 : 0.00401522
  7. image 0 vs image 2 : 0.00575911
  8. image 0 vs image 3 : 0.0057625
  9. image 0 vs image 4 : 0.00516026
  10. image 0 vs image 5 : 0.00289918
  11. image 0 vs image 6 : 0.00280098
  12. image 0 vs image 7 : 0.00329088
  13. image 0 vs image 8 : 0.00869696
  14. image 0 vs image 9 : 0.0304572
  15. image 1 vs image 1 : 1
  16. image 1 vs image 2 : 0.0241793
  17. image 1 vs image 3 : 0.00553848
  18. image 1 vs image 4 : 0.00522892
  19. image 1 vs image 5 : 0.00702649
  20. image 1 vs image 6 : 0.00331991
  21. image 1 vs image 7 : 0.0035423
  22. image 1 vs image 8 : 0.00950168
  23. image 1 vs image 9 : 0.00598861
  24. image 2 vs image 2 : 1
  25. image 2 vs image 3 : 0.00634031
  26. image 2 vs image 4 : 0.00541992
  27. image 2 vs image 5 : 0.0149133
  28. image 2 vs image 6 : 0.00789202
  29. image 2 vs image 7 : 0.00498983
  30. image 2 vs image 8 : 0.00329779
  31. image 2 vs image 9 : 0.00490939
  32. image 3 vs image 3 : 1
  33. image 3 vs image 4 : 0.00195016
  34. image 3 vs image 5 : 0.0150889
  35. image 3 vs image 6 : 0.0073025
  36. image 3 vs image 7 : 0.00476159
  37. image 3 vs image 8 : 0.0110854
  38. image 3 vs image 9 : 0.00516915
  39. image 4 vs image 4 : 1
  40. image 4 vs image 5 : 0.0105219
  41. image 4 vs image 6 : 0.00596558
  42. image 4 vs image 7 : 0.00467202
  43. image 4 vs image 8 : -0
  44. image 4 vs image 9 : 0.00676682
  45. image 5 vs image 5 : 1
  46. image 5 vs image 6 : 0.0015908
  47. image 5 vs image 7 : 0.00508986
  48. image 5 vs image 8 : 0.00442575
  49. image 5 vs image 9 : 0.00177321
  50. image 6 vs image 6 : 1
  51. image 6 vs image 7 : 0.00579406
  52. image 6 vs image 8 : 0.0069873
  53. image 6 vs image 9 : 0.00166793
  54. image 7 vs image 7 : 1
  55. image 7 vs image 8 : 0.00720273
  56. image 7 vs image 9 : 0.00174475
  57. image 8 vs image 8 : 1
  58. image 8 vs image 9 : 0.00937256
  59. image 9 vs image 9 : 1
  60. comparing images with database
  61. database info: Database: Entries = 10, Using direct index = no. Vocabulary: k = 10, L = 5, Weighting = tf-idf, Scoring = L1-norm, Number of words = 99566
  62. searching for image 0 returns 4 results:
  63. <EntryId: 0, Score: 1>
  64. <EntryId: 9, Score: 0.0304572>
  65. <EntryId: 8, Score: 0.00869696>
  66. <EntryId: 3, Score: 0.0057625>
  67. searching for image 1 returns 4 results:
  68. <EntryId: 1, Score: 1>
  69. <EntryId: 2, Score: 0.0241793>
  70. <EntryId: 8, Score: 0.00950168>
  71. <EntryId: 5, Score: 0.00702649>
  72. searching for image 2 returns 4 results:
  73. <EntryId: 2, Score: 1>
  74. <EntryId: 1, Score: 0.0241793>
  75. <EntryId: 5, Score: 0.0149133>
  76. <EntryId: 6, Score: 0.00789202>
  77. searching for image 3 returns 4 results:
  78. <EntryId: 3, Score: 1>
  79. <EntryId: 5, Score: 0.0150889>
  80. <EntryId: 8, Score: 0.0110854>
  81. <EntryId: 6, Score: 0.0073025>
  82. searching for image 4 returns 4 results:
  83. <EntryId: 4, Score: 1>
  84. <EntryId: 5, Score: 0.0105219>
  85. <EntryId: 9, Score: 0.00676682>
  86. <EntryId: 6, Score: 0.00596558>
  87. searching for image 5 returns 4 results:
  88. <EntryId: 5, Score: 1>
  89. <EntryId: 3, Score: 0.0150889>
  90. <EntryId: 2, Score: 0.0149133>
  91. <EntryId: 4, Score: 0.0105219>
  92. searching for image 6 returns 4 results:
  93. <EntryId: 6, Score: 1>
  94. <EntryId: 2, Score: 0.00789202>
  95. <EntryId: 3, Score: 0.0073025>
  96. <EntryId: 8, Score: 0.0069873>
  97. searching for image 7 returns 4 results:
  98. <EntryId: 7, Score: 1>
  99. <EntryId: 8, Score: 0.00720273>
  100. <EntryId: 6, Score: 0.00579406>
  101. <EntryId: 5, Score: 0.00508986>
  102. searching for image 8 returns 4 results:
  103. <EntryId: 8, Score: 1>
  104. <EntryId: 3, Score: 0.0110854>
  105. <EntryId: 1, Score: 0.00950168>
  106. <EntryId: 9, Score: 0.00937256>
  107. searching for image 9 returns 4 results:
  108. <EntryId: 9, Score: 1>
  109. <EntryId: 0, Score: 0.0304572>
  110. <EntryId: 8, Score: 0.00937256>
  111. <EntryId: 4, Score: 0.00676682>
  112. done.

 课后习题

1. 请书写计算PR 曲线的小程序。用MATLAB 或Python 可能更加简便一些,因为它们擅长作图。

进行测试前需要安装scikit-learn以及matplotlib:

安装scikit-learn:Installing scikit-learn — scikit-learn 1.0.1 documentation

pip3 install -U scikit-learn

matplotlib:

 pip install matplotlib

 下面的代码转载于:三分钟带你理解ROC曲线和PR曲线_Guo_Python的博客-CSDN博客_roc曲线和pr曲线

 pr.py:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from sklearn.metrics import precision_recall_curve,roc_curve
  4. def draw_pr(confidence_scores, data_labels):
  5. plt.figure()
  6. plt.title('PR Curve')
  7. plt.xlabel('Recall')
  8. plt.ylabel('Precision')
  9. plt.grid()
  10. #精确率,召回率,阈值
  11. precision,recall,thresholds = precision_recall_curve(data_labels,confidence_scores)
  12. from sklearn.metrics import average_precision_score
  13. AP = average_precision_score(data_labels, confidence_scores) # 计算AP
  14. plt.plot(recall, precision, label = 'pr_curve(AP=%0.2f)' % AP)
  15. plt.legend()
  16. plt.show()
  17. def draw_roc(confidence_scores, data_labels):
  18. #真正率,假正率
  19. fpr, tpr, thresholds = roc_curve(data_labels, confidence_scores)
  20. plt.figure()
  21. plt.grid()
  22. plt.title('Roc Curve')
  23. plt.xlabel('FPR')
  24. plt.ylabel('TPR')
  25. from sklearn.metrics import auc
  26. auc=auc(fpr, tpr) #AUC计算
  27. plt.plot(fpr,tpr,label = 'roc_curve(AUC=%0.2f)' % auc)
  28. plt.legend()
  29. plt.show()
  30. if __name__ == '__main__':
  31. # 正样本的置信度,即模型识别成1的概率
  32. confidence_scores = np.array([0.9, 0.78, 0.6, 0.46, 0.4, 0.37, 0.2, 0.16])
  33. # 真实标签
  34. data_labels = np.array([1,1,0,1,0,0,1,1])
  35. draw_pr(confidence_scores, data_labels)
  36. draw_roc(confidence_scores, data_labels)

 在Ubuntu下面执行时候,我把python文件放在ch11文件夹下面:

python pr.py

执行结果:

转载于:
Roc曲线和PR曲线的理解与简单的代码实现_JMU-HZH的博客-CSDN博客_pr曲线实现
 

 pr1.py:

  1. import matplotlib
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from sklearn.metrics import precision_recall_curve,roc_curve
  5. plt.figure()
  6. plt.title('PR Curve')
  7. plt.xlabel('Recall')
  8. plt.ylabel('Precision')
  9. plt.grid()
  10. #只是理解两种曲线的含义,所以数据简单的构造
  11. confidence_scores = np.array([0.9,0.46,0.78,0.37,0.6,0.4,0.2,0.16])
  12. confidence_scores=sorted(confidence_scores,reverse=True)#置信度从大到小排列
  13. print(confidence_scores)
  14. data_labels = np.array([1,1,0,1,0,0 ,1,1])#置信度所对应的标签
  15. #精确率,召回率,阈值
  16. precision,recall,thresholds = precision_recall_curve(data_labels,confidence_scores)
  17. print(precision)
  18. print(recall)
  19. print(thresholds)
  20. plt.plot(recall,precision)
  21. plt.show()
  22. #真正率,假正率
  23. fpr, tpr, thresholds = roc_curve(data_labels, confidence_scores)
  24. #print(fpr)
  25. #print(tpr)
  26. plt.figure()
  27. plt.grid()
  28. plt.title('Roc Curve')
  29. plt.xlabel('FPR')
  30. plt.ylabel('TPR')
  31. from sklearn.metrics import auc
  32. auc=auc(fpr, tpr)#AUC计算
  33. plt.plot(fpr,tpr,label='roc_curve(AUC=%0.2f)'%auc)
  34. plt.legend()
  35. plt.show()

 执行结果:

python pr1.py 
  1. [0.9, 0.78, 0.6, 0.46, 0.4, 0.37, 0.2, 0.16]
  2. [0.625 0.57142857 0.5 0.6 0.75 0.66666667
  3. 1. 1. 1. ]
  4. [1. 0.8 0.6 0.6 0.6 0.4 0.4 0.2 0. ]
  5. [0.16 0.2 0.37 0.4 0.46 0.6 0.78 0.9 ]

 

2. 验证回环检测算法,需要有人工标记回环的数据集,例如[103]。然而人工标记回环是很不方便的,我们会考虑根据标准轨迹计算回环。即,如果轨迹中有两个帧的位姿非常相近,就认为它们是回环。请你根据TUM 数据集给出的标准轨迹,计算出一个数据集中的回环。这些回环的图像真的相似吗?

转载于:视觉SLAM十四讲(第二版)第11讲习题解答 - 知乎

  1. #include <pangolin/pangolin.h>
  2. #include <Eigen/Core>
  3. #include <Eigen/Geometry>
  4. #include <unistd.h>
  5. using namespace std;
  6. using namespace Eigen;
  7. // path to groundtruth file
  8. string groundtruth_file = "/home/liqiang/slambook2/ch11/rgbd_dataset_freiburg2_rpy/groundtruth.txt";
  9. // 设置检测的间隔,使得检测具有稀疏性的同时覆盖整个环境
  10. int delta = 50;
  11. // 齐次变换矩阵差的范数
  12. // 小于该值时认为位姿非常接近
  13. double threshold = 0.4;
  14. int main(int argc, char **argv) {
  15. vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses;
  16. vector<string> times;
  17. ifstream fin(groundtruth_file);
  18. if (!fin) {
  19. cout << "cannot find trajectory file at " << groundtruth_file << endl;
  20. return 1;
  21. }
  22. int num = 0;
  23. while (!fin.eof())
  24. {
  25. string time_s;
  26. double tx, ty, tz, qx, qy, qz, qw;
  27. fin >> time_s >> tx >> ty >> tz >> qx >> qy >> qz >> qw;
  28. Isometry3d Twr(Quaterniond(qw, qx, qy, qz));
  29. Twr.pretranslate(Vector3d(tx, ty, tz));
  30. // 相当于从第150个位姿开始,这是因为标准轨迹的记录早于照片拍摄(前120个位姿均无对应照片)
  31. if (num > 120 && num % delta == 0){
  32. times.push_back(time_s);
  33. poses.push_back(Twr);
  34. }
  35. num++;
  36. }
  37. cout << "read total " << num << " pose entries" << endl;
  38. cout << "selected total " << poses.size() << " pose entries" << endl;
  39. //设置检测到回环后重新开始检测图片间隔数量
  40. cout << "**************************************************" << endl;
  41. cout << "Detection Start!!!" << endl;
  42. cout << "**************************************************" << endl;
  43. for (size_t i = 0 ; i < poses.size() - delta; i += delta){
  44. for (size_t j = i + delta ; j < poses.size() ; j++){
  45. Matrix4d Error = (poses[i].inverse() * poses[j]).matrix() - Matrix4d::Identity();
  46. if (Error.norm() < threshold){
  47. cout << "第" << i << "张照片与第" << j << "张照片构成回环" << endl;
  48. cout << "位姿误差为" << Error.norm() << endl;
  49. cout << "第" << i << "张照片的时间戳为" << endl << times[i] << endl;
  50. cout << "第" << j << "张照片的时间戳为" << endl << times[j] << endl;
  51. cout << "**************************************************" << endl;
  52. break;
  53. }
  54. }
  55. }
  56. cout << "Detection Finish!!!" << endl;
  57. cout << "**************************************************" << endl;
  58. return 0;
  59. }

我试了一下这个代码,没跑通,报错提示killed,我也没搞懂是什么意思,有可能内存不够或者计算量太大,有想试试的去跑一跑。


3. 学习DBoW3 或DBoW2 库,自己寻找几张图片,看能否从中正确检测出回环。

我所使用的数据集是:Computer Vision Group - Dataset Download

 然后在ch11下面建立一个新的文件夹data1,挑选了21张图片放进去。

然后修改图像路径:

gen_vocab_large3.cpp

  1. #include "DBoW3/DBoW3.h"//词袋支持头文件
  2. #include <opencv2/core/core.hpp>//opencv核心模块
  3. #include <opencv2/highgui/highgui.hpp>//gui模块
  4. #include <opencv2/features2d/features2d.hpp>//特征点头文件
  5. #include <iostream>
  6. #include <vector>
  7. #include <string>
  8. using namespace cv;
  9. using namespace std;
  10. int main( int argc, char** argv )
  11. {
  12. String directoryPath = "/home/liqiang/slambook2/ch11/data1";//图像路径
  13. vector<String> imagesPath;
  14. glob(directoryPath, imagesPath);
  15. // string dataset_dir = argv[1];
  16. // ifstream fin ( dataset_dir+"/home/liqiang/slambook2/ch11/rgbd_dataset_freiburg1_desk2/rgb" );
  17. // if ( !fin )
  18. // {
  19. // cout<<"please generate the associate file called associate.txt!"<<endl;
  20. // return 1;
  21. // }
  22. // vector<string> rgb_files, depth_files;
  23. // vector<double> rgb_times, depth_times;
  24. // while ( !fin.eof() )
  25. // {
  26. // string rgb_time, rgb_file, depth_time, depth_file;
  27. // fin>>rgb_time>>rgb_file>>depth_time>>depth_file;
  28. // rgb_times.push_back ( atof ( rgb_time.c_str() ) );
  29. // depth_times.push_back ( atof ( depth_time.c_str() ) );
  30. // rgb_files.push_back ( dataset_dir+"/"+rgb_file );
  31. // depth_files.push_back ( dataset_dir+"/"+depth_file );
  32. // if ( fin.good() == false )
  33. // break;
  34. // }
  35. // fin.close();
  36. cout<<"generating features ... "<<endl;//输出generating features (正在检测ORB特征)...
  37. vector<Mat> descriptors;//描述子
  38. Ptr< Feature2D > detector = ORB::create();
  39. int index = 1;
  40. for ( String path : imagesPath )
  41. {
  42. Mat image = imread(path);
  43. vector<KeyPoint> keypoints; //关键点
  44. Mat descriptor;//描述子
  45. detector->detectAndCompute( image, Mat(), keypoints, descriptor );
  46. descriptors.push_back( descriptor );
  47. cout<<"extracting features from image " << index++ <<endl;//输出extracting features from image(从图像中提取特征)
  48. }
  49. cout<<"extract total "<<descriptors.size()*500<<" features."<<endl;
  50. // create vocabulary
  51. cout<<"creating vocabulary, please wait ... "<<endl;//输出creating vocabulary, please wait (创建词典,请稍等)...
  52. DBoW3::Vocabulary vocab;
  53. vocab.create( descriptors );
  54. cout<<"vocabulary info: "<<vocab<<endl;
  55. vocab.save( "vocab_larger3.yml.gz" );//保存词典
  56. cout<<"done"<<endl;
  57. return 0;
  58. }

CMakeLists.txt 

  1. cmake_minimum_required( VERSION 2.8 )
  2. project( loop_closure )
  3. set( CMAKE_BUILD_TYPE "Release" )
  4. set( CMAKE_CXX_FLAGS "-std=c++14 -O3" )
  5. # opencv
  6. find_package( OpenCV 3.1 REQUIRED )
  7. include_directories( ${OpenCV_INCLUDE_DIRS} )
  8. # 添加Pangolin依赖
  9. find_package( Pangolin )
  10. include_directories( ${Pangolin_INCLUDE_DIRS} )
  11. # 添加Eigen头文件
  12. include_directories("/usr/include/eigen3")
  13. add_executable( 2 2.cpp )
  14. target_link_libraries( 2 ${OpenCV_LIBS} ${DBoW3_LIBS} ${Pangolin_LIBRARIES} )
  15. # dbow3
  16. # dbow3 is a simple lib so I assume you installed it in default directory
  17. set( DBoW3_INCLUDE_DIRS "/usr/local/include" )
  18. set( DBoW3_LIBS "/usr/local/lib/libDBoW3.a" )
  19. add_executable( feature_training feature_training.cpp )
  20. target_link_libraries( feature_training ${OpenCV_LIBS} ${DBoW3_LIBS} )
  21. add_executable( loop_closure loop_closure.cpp )
  22. target_link_libraries( loop_closure ${OpenCV_LIBS} ${DBoW3_LIBS} )
  23. add_executable( loop_closure1 loop_closure1.cpp )
  24. target_link_libraries( loop_closure1 ${OpenCV_LIBS} ${DBoW3_LIBS} )
  25. add_executable( loop_closure3 loop_closure3.cpp )
  26. target_link_libraries( loop_closure3 ${OpenCV_LIBS} ${DBoW3_LIBS} )
  27. add_executable( gen_vocab gen_vocab_large.cpp )
  28. target_link_libraries( gen_vocab ${OpenCV_LIBS} ${DBoW3_LIBS} )
  29. add_executable( gen_vocab1 gen_vocab_large1.cpp )
  30. target_link_libraries( gen_vocab1 ${OpenCV_LIBS} ${DBoW3_LIBS} )
  31. add_executable( gen_vocab2 gen_vocab_large2.cpp )
  32. target_link_libraries( gen_vocab2 ${OpenCV_LIBS} ${DBoW3_LIBS} )
  33. add_executable( gen_vocab3 gen_vocab_large3.cpp )
  34. target_link_libraries( gen_vocab3 ${OpenCV_LIBS} ${DBoW3_LIBS} )

 执行结果:

./gen_vocab3
  1. generating features ...
  2. extracting features from image 1
  3. extracting features from image 2
  4. extracting features from image 3
  5. extracting features from image 4
  6. extracting features from image 5
  7. extracting features from image 6
  8. extracting features from image 7
  9. extracting features from image 8
  10. extracting features from image 9
  11. extracting features from image 10
  12. extracting features from image 11
  13. extracting features from image 12
  14. extracting features from image 13
  15. extracting features from image 14
  16. extracting features from image 15
  17. extracting features from image 16
  18. extracting features from image 17
  19. extracting features from image 18
  20. extracting features from image 19
  21. extracting features from image 20
  22. extracting features from image 21
  23. extract total 10500 features.
  24. creating vocabulary, please wait ...
  25. vocabulary info: Vocabulary: k = 10, L = 5, Weighting = tf-idf, Scoring = L1-norm, Number of words = 10381
  26. done

 执行完毕后会在build文件夹里生成一个vocab_larger3.yml.gz压缩包,最后将该压缩包放在ch11下面,执行loop_closure3。

 修改下面两个地方:

loop_closure3.cpp

  1. #include "DBoW3/DBoW3.h"//词袋支持头文件
  2. #include <opencv2/core/core.hpp>//opencv核心模块
  3. #include <opencv2/highgui/highgui.hpp>//gui模块
  4. #include <opencv2/features2d/features2d.hpp>//特征点头文件
  5. #include <iostream>
  6. #include <vector>
  7. #include <string>
  8. using namespace cv;
  9. using namespace std;
  10. /***************************************************
  11. * 本节演示了如何根据前面训练的字典计算相似性评分
  12. * ************************************************/
  13. int main(int argc, char **argv) {
  14. // read the images and database(读取图像和数据库)
  15. cout << "reading database" << endl;//输出reading database(读取数据)
  16. DBoW3::Vocabulary vocab("../vocab_larger3.yml.gz");//vocabulary.yml.gz路径
  17. // DBoW3::Vocabulary vocab("./vocab_larger.yml.gz"); // use large vocab if you want:
  18. if (vocab.empty()) {
  19. cerr << "Vocabulary does not exist." << endl;//输出Vocabulary does not exist
  20. return 1;
  21. }
  22. cout << "reading images... " << endl;//输出reading images...
  23. vector<Mat> images;
  24. for (int i = 0; i < 21; i++) {
  25. string path = "../data1/" + to_string(i + 1) + ".png";//图像读取路径
  26. images.push_back(imread(path));
  27. }
  28. // NOTE: in this case we are comparing images with a vocabulary generated by themselves, this may lead to overfit. 这里我们用它们生成的字典比较它们本身的相似性,这可能会产生过拟合
  29. // detect ORB features
  30. cout << "detecting ORB features ... " << endl;//输出detecting ORB features ...(正在检测ORB特征)
  31. Ptr<Feature2D> detector = ORB::create();//默认图像500个特征点
  32. vector<Mat> descriptors;//描述子 将10张图像提取ORB特征并存放在vector容器里
  33. for (Mat &image:images) {
  34. vector<KeyPoint> keypoints;//关键点
  35. Mat descriptor;//描述子
  36. detector->detectAndCompute(image, Mat(), keypoints, descriptor);//检测和计算
  37. descriptors.push_back(descriptor);
  38. }
  39. // we can compare the images directly or we can compare one image to a database
  40. // images :
  41. cout << "comparing images with images " << endl;//输出comparing images with images
  42. for (int i = 0; i < images.size(); i++)
  43. {
  44. DBoW3::BowVector v1;
  45. //descriptors[i]表示图像i中所有的ORB描述子集合,函数transform()计算出用先前字典来描述的单词向量,每个向量中元素的值要么是0,表示图像i中没有这个单词;要么是该单词的权重
  46. //BoW描述向量中含有每个单词的ID和权重,两者构成了整个稀疏的向量
  47. //当比较两个向量时,DBoW3会为我们计算一个分数
  48. vocab.transform(descriptors[i], v1);
  49. for (int j = i; j < images.size(); j++)
  50. {
  51. DBoW3::BowVector v2;
  52. vocab.transform(descriptors[j], v2);
  53. double score = vocab.score(v1, v2);//p296式(11.9)
  54. cout << "image " << i << " vs image " << j << " : " << score << endl;//输出一幅图像与另外一幅图像之间的相似度评分
  55. }
  56. cout << endl;
  57. }
  58. // or with database
  59. //在进行数据库查询时,DBoW对上面的分数进行排序,给出最相似的结果
  60. cout << "comparing images with database " << endl;
  61. DBoW3::Database db(vocab, false, 0);
  62. for (int i = 0; i < descriptors.size(); i++)
  63. db.add(descriptors[i]);
  64. cout << "database info: " << db << endl;//输出database info(数据库信息)为
  65. for (int i = 0; i < descriptors.size(); i++)
  66. {
  67. DBoW3::QueryResults ret;
  68. db.query(descriptors[i], ret, 4); // max result=4
  69. cout << "searching for image " << i << " returns " << ret << endl << endl;
  70. }
  71. cout << "done." << endl;
  72. }

CMakeLists.txt  

参考上面的,上面的CMakeLists.txt 已经添加了相关的cpp执行文件。

./loop_closure3
  1. reading database
  2. reading images...
  3. detecting ORB features ...
  4. comparing images with images
  5. image 0 vs image 0 : 1
  6. image 0 vs image 1 : 0.0179514
  7. image 0 vs image 2 : 0.0257712
  8. image 0 vs image 3 : 0.0248006
  9. image 0 vs image 4 : 0.0215647
  10. image 0 vs image 5 : 0.00544075
  11. image 0 vs image 6 : 0.0224883
  12. image 0 vs image 7 : 0.0172719
  13. image 0 vs image 8 : 0.0177548
  14. image 0 vs image 9 : 0.0362582
  15. image 0 vs image 10 : 0.0162675
  16. image 0 vs image 11 : 0.0222014
  17. image 0 vs image 12 : 0.0204588
  18. image 0 vs image 13 : 0.0170047
  19. image 0 vs image 14 : 0.0165957
  20. image 0 vs image 15 : 0.0241384
  21. image 0 vs image 16 : 0.0131228
  22. image 0 vs image 17 : 0.0231237
  23. image 0 vs image 18 : 0.0126125
  24. image 0 vs image 19 : 0.0264222
  25. image 0 vs image 20 : 0.0319604
  26. image 1 vs image 1 : 1
  27. image 1 vs image 2 : 0.0225294
  28. image 1 vs image 3 : 0.0291438
  29. image 1 vs image 4 : 0.024401
  30. image 1 vs image 5 : 0.0427242
  31. image 1 vs image 6 : 0.00947695
  32. image 1 vs image 7 : 0.0336035
  33. image 1 vs image 8 : 0.0554665
  34. image 1 vs image 9 : 0.0313537
  35. image 1 vs image 10 : 0.0127257
  36. image 1 vs image 11 : 0.0170929
  37. image 1 vs image 12 : 0.024939
  38. image 1 vs image 13 : 0.0188714
  39. image 1 vs image 14 : 0.0191085
  40. image 1 vs image 15 : 0.0482948
  41. image 1 vs image 16 : 0.0242885
  42. image 1 vs image 17 : 0.0134153
  43. image 1 vs image 18 : 0.017274
  44. image 1 vs image 19 : 0.0283448
  45. image 1 vs image 20 : 0.00922942
  46. image 2 vs image 2 : 1
  47. image 2 vs image 3 : 0.0159252
  48. image 2 vs image 4 : 0.0253237
  49. image 2 vs image 5 : 0.0118317
  50. image 2 vs image 6 : 0.0571594
  51. image 2 vs image 7 : 0.0189714
  52. image 2 vs image 8 : 0.0155815
  53. image 2 vs image 9 : 0.0195412
  54. image 2 vs image 10 : 0.0184117
  55. image 2 vs image 11 : 0.0152941
  56. image 2 vs image 12 : 0.0178018
  57. image 2 vs image 13 : 0.0233106
  58. image 2 vs image 14 : 0.0168851
  59. image 2 vs image 15 : 0.0137194
  60. image 2 vs image 16 : 0.0498792
  61. image 2 vs image 17 : 0.0240186
  62. image 2 vs image 18 : 0.0219548
  63. image 2 vs image 19 : 0.0209176
  64. image 2 vs image 20 : 0.0140803
  65. image 3 vs image 3 : 1
  66. image 3 vs image 4 : 0.0234056
  67. image 3 vs image 5 : 0.0284397
  68. image 3 vs image 6 : 0.02011
  69. image 3 vs image 7 : 0.0216389
  70. image 3 vs image 8 : 0.0176086
  71. image 3 vs image 9 : 0.0155744
  72. image 3 vs image 10 : 0.0170962
  73. image 3 vs image 11 : 0.0225567
  74. image 3 vs image 12 : 0.0234662
  75. image 3 vs image 13 : 0.0182703
  76. image 3 vs image 14 : 0.01482
  77. image 3 vs image 15 : 0.020363
  78. image 3 vs image 16 : 0.0176234
  79. image 3 vs image 17 : 0.0233771
  80. image 3 vs image 18 : 0.0155559
  81. image 3 vs image 19 : 0.016011
  82. image 3 vs image 20 : 0.0177395
  83. image 4 vs image 4 : 1
  84. image 4 vs image 5 : 0.0119718
  85. image 4 vs image 6 : 0.0274229
  86. image 4 vs image 7 : 0.0149015
  87. image 4 vs image 8 : 0.0252062
  88. image 4 vs image 9 : 0.0127473
  89. image 4 vs image 10 : 0.0123496
  90. image 4 vs image 11 : 0.0234471
  91. image 4 vs image 12 : 0.0255185
  92. image 4 vs image 13 : 0.018047
  93. image 4 vs image 14 : 0.0397562
  94. image 4 vs image 15 : 0.0105365
  95. image 4 vs image 16 : 0.0148716
  96. image 4 vs image 17 : 0.0347258
  97. image 4 vs image 18 : 0.0131217
  98. image 4 vs image 19 : 0.0191835
  99. image 4 vs image 20 : 0.0211236
  100. image 5 vs image 5 : 1
  101. image 5 vs image 6 : 0.0141552
  102. image 5 vs image 7 : 0.0205087
  103. image 5 vs image 8 : 0.023158
  104. image 5 vs image 9 : 0.0193337
  105. image 5 vs image 10 : 0.0187104
  106. image 5 vs image 11 : 0.025994
  107. image 5 vs image 12 : 0.0196689
  108. image 5 vs image 13 : 0.0257136
  109. image 5 vs image 14 : 0.0124622
  110. image 5 vs image 15 : 0.0692064
  111. image 5 vs image 16 : 0.0210536
  112. image 5 vs image 17 : 0.0252288
  113. image 5 vs image 18 : 0.0119623
  114. image 5 vs image 19 : 0.0251428
  115. image 5 vs image 20 : 0.0231639
  116. image 6 vs image 6 : 1
  117. image 6 vs image 7 : 0.0176295
  118. image 6 vs image 8 : 0.0157532
  119. image 6 vs image 9 : 0.0177508
  120. image 6 vs image 10 : 0.0141089
  121. image 6 vs image 11 : 0.0116931
  122. image 6 vs image 12 : 0.0177043
  123. image 6 vs image 13 : 0.0113189
  124. image 6 vs image 14 : 0.0165114
  125. image 6 vs image 15 : 0.0238359
  126. image 6 vs image 16 : 0.0286878
  127. image 6 vs image 17 : 0.0242205
  128. image 6 vs image 18 : 0.0238473
  129. image 6 vs image 19 : 0.0183829
  130. image 6 vs image 20 : 0.0160894
  131. image 7 vs image 7 : 1
  132. image 7 vs image 8 : 0.0484327
  133. image 7 vs image 9 : 0.0799389
  134. image 7 vs image 10 : 0.0140699
  135. image 7 vs image 11 : 0.0353015
  136. image 7 vs image 12 : 0.0162742
  137. image 7 vs image 13 : 0.0123849
  138. image 7 vs image 14 : 0.0155762
  139. image 7 vs image 15 : 0.0236286
  140. image 7 vs image 16 : 0.021078
  141. image 7 vs image 17 : 0.00994403
  142. image 7 vs image 18 : 0.0104469
  143. image 7 vs image 19 : 0.00981495
  144. image 7 vs image 20 : 0.0793399
  145. image 8 vs image 8 : 1
  146. image 8 vs image 9 : 0.0242055
  147. image 8 vs image 10 : 0.0144976
  148. image 8 vs image 11 : 0.0289231
  149. image 8 vs image 12 : 0.0134452
  150. image 8 vs image 13 : 0.0107451
  151. image 8 vs image 14 : 0.013121
  152. image 8 vs image 15 : 0.0440592
  153. image 8 vs image 16 : 0.023649
  154. image 8 vs image 17 : 0.0226309
  155. image 8 vs image 18 : 0.0167086
  156. image 8 vs image 19 : 0.0163815
  157. image 8 vs image 20 : 0.019543
  158. image 9 vs image 9 : 1
  159. image 9 vs image 10 : 0.0196453
  160. image 9 vs image 11 : 0.0360537
  161. image 9 vs image 12 : 0.0216228
  162. image 9 vs image 13 : 0.00905572
  163. image 9 vs image 14 : 0.0117925
  164. image 9 vs image 15 : 0.0203327
  165. image 9 vs image 16 : 0.0124184
  166. image 9 vs image 17 : 0.014915
  167. image 9 vs image 18 : 0.0190471
  168. image 9 vs image 19 : 0.0135781
  169. image 9 vs image 20 : 0.136697
  170. image 10 vs image 10 : 1
  171. image 10 vs image 11 : 0.0150776
  172. image 10 vs image 12 : 0.0147019
  173. image 10 vs image 13 : 0.0437288
  174. image 10 vs image 14 : 0.0212159
  175. image 10 vs image 15 : 0.0175276
  176. image 10 vs image 16 : 0.0244171
  177. image 10 vs image 17 : 0.0173673
  178. image 10 vs image 18 : 0.0180583
  179. image 10 vs image 19 : 0.0198632
  180. image 10 vs image 20 : 0.0186188
  181. image 11 vs image 11 : 1
  182. image 11 vs image 12 : 0.0145951
  183. image 11 vs image 13 : 0.00686832
  184. image 11 vs image 14 : 0.0105737
  185. image 11 vs image 15 : 0.0193443
  186. image 11 vs image 16 : 0.0145832
  187. image 11 vs image 17 : 0.0164647
  188. image 11 vs image 18 : 0.0173467
  189. image 11 vs image 19 : 0.0160974
  190. image 11 vs image 20 : 0.0500313
  191. image 12 vs image 12 : 1
  192. image 12 vs image 13 : 0.00650131
  193. image 12 vs image 14 : 0.0809155
  194. image 12 vs image 15 : 0.0164976
  195. image 12 vs image 16 : 0.0315461
  196. image 12 vs image 17 : 0.0174517
  197. image 12 vs image 18 : 0.029972
  198. image 12 vs image 19 : 0.0157822
  199. image 12 vs image 20 : 0.0115077
  200. image 13 vs image 13 : 1
  201. image 13 vs image 14 : 0.0190167
  202. image 13 vs image 15 : 0.0269287
  203. image 13 vs image 16 : 0.0171848
  204. image 13 vs image 17 : 0.0151769
  205. image 13 vs image 18 : 0.0242274
  206. image 13 vs image 19 : 0.00725557
  207. image 13 vs image 20 : 0.00889539
  208. image 14 vs image 14 : 1
  209. image 14 vs image 15 : 0.0181876
  210. image 14 vs image 16 : 0.03296
  211. image 14 vs image 17 : 0.0200591
  212. image 14 vs image 18 : 0.0362168
  213. image 14 vs image 19 : 0.0128257
  214. image 14 vs image 20 : 0.0160966
  215. image 15 vs image 15 : 1
  216. image 15 vs image 16 : 0.0233746
  217. image 15 vs image 17 : 0.0147329
  218. image 15 vs image 18 : 0.0240136
  219. image 15 vs image 19 : 0.0301395
  220. image 15 vs image 20 : 0.0211014
  221. image 16 vs image 16 : 1
  222. image 16 vs image 17 : 0.0128384
  223. image 16 vs image 18 : 0.0139085
  224. image 16 vs image 19 : 0.0200746
  225. image 16 vs image 20 : 0.0090532
  226. image 17 vs image 17 : 1
  227. image 17 vs image 18 : 0.018697
  228. image 17 vs image 19 : 0.017062
  229. image 17 vs image 20 : 0.0147481
  230. image 18 vs image 18 : 1
  231. image 18 vs image 19 : 0.0196678
  232. image 18 vs image 20 : 0.0187427
  233. image 19 vs image 19 : 1
  234. image 19 vs image 20 : 0.0131965
  235. image 20 vs image 20 : 1
  236. comparing images with database
  237. database info: Database: Entries = 21, Using direct index = no. Vocabulary: k = 10, L = 5, Weighting = tf-idf, Scoring = L1-norm, Number of words = 10381
  238. searching for image 0 returns 4 results:
  239. <EntryId: 0, Score: 1>
  240. <EntryId: 9, Score: 0.0362582>
  241. <EntryId: 20, Score: 0.0319604>
  242. <EntryId: 19, Score: 0.0264222>
  243. searching for image 1 returns 4 results:
  244. <EntryId: 1, Score: 1>
  245. <EntryId: 8, Score: 0.0554665>
  246. <EntryId: 15, Score: 0.0482948>
  247. <EntryId: 5, Score: 0.0427242>
  248. searching for image 2 returns 4 results:
  249. <EntryId: 2, Score: 1>
  250. <EntryId: 6, Score: 0.0571594>
  251. <EntryId: 16, Score: 0.0498792>
  252. <EntryId: 0, Score: 0.0257712>
  253. searching for image 3 returns 4 results:
  254. <EntryId: 3, Score: 1>
  255. <EntryId: 1, Score: 0.0291438>
  256. <EntryId: 5, Score: 0.0284397>
  257. <EntryId: 0, Score: 0.0248006>
  258. searching for image 4 returns 4 results:
  259. <EntryId: 4, Score: 1>
  260. <EntryId: 14, Score: 0.0397562>
  261. <EntryId: 17, Score: 0.0347258>
  262. <EntryId: 6, Score: 0.0274229>
  263. searching for image 5 returns 4 results:
  264. <EntryId: 5, Score: 1>
  265. <EntryId: 15, Score: 0.0692064>
  266. <EntryId: 1, Score: 0.0427242>
  267. <EntryId: 3, Score: 0.0284397>
  268. searching for image 6 returns 4 results:
  269. <EntryId: 6, Score: 1>
  270. <EntryId: 2, Score: 0.0571594>
  271. <EntryId: 16, Score: 0.0286878>
  272. <EntryId: 4, Score: 0.0274229>
  273. searching for image 7 returns 4 results:
  274. <EntryId: 7, Score: 1>
  275. <EntryId: 9, Score: 0.0799389>
  276. <EntryId: 20, Score: 0.0793399>
  277. <EntryId: 8, Score: 0.0484327>
  278. searching for image 8 returns 4 results:
  279. <EntryId: 8, Score: 1>
  280. <EntryId: 1, Score: 0.0554665>
  281. <EntryId: 7, Score: 0.0484327>
  282. <EntryId: 15, Score: 0.0440592>
  283. searching for image 9 returns 4 results:
  284. <EntryId: 9, Score: 1>
  285. <EntryId: 20, Score: 0.136697>
  286. <EntryId: 7, Score: 0.0799389>
  287. <EntryId: 0, Score: 0.0362582>
  288. searching for image 10 returns 4 results:
  289. <EntryId: 10, Score: 1>
  290. <EntryId: 13, Score: 0.0437288>
  291. <EntryId: 16, Score: 0.0244171>
  292. <EntryId: 14, Score: 0.0212159>
  293. searching for image 11 returns 4 results:
  294. <EntryId: 11, Score: 1>
  295. <EntryId: 20, Score: 0.0500313>
  296. <EntryId: 9, Score: 0.0360537>
  297. <EntryId: 7, Score: 0.0353015>
  298. searching for image 12 returns 4 results:
  299. <EntryId: 12, Score: 1>
  300. <EntryId: 14, Score: 0.0809155>
  301. <EntryId: 16, Score: 0.0315461>
  302. <EntryId: 18, Score: 0.029972>
  303. searching for image 13 returns 4 results:
  304. <EntryId: 13, Score: 1>
  305. <EntryId: 10, Score: 0.0437288>
  306. <EntryId: 15, Score: 0.0269287>
  307. <EntryId: 5, Score: 0.0257136>
  308. searching for image 14 returns 4 results:
  309. <EntryId: 14, Score: 1>
  310. <EntryId: 12, Score: 0.0809155>
  311. <EntryId: 4, Score: 0.0397562>
  312. <EntryId: 18, Score: 0.0362168>
  313. searching for image 15 returns 4 results:
  314. <EntryId: 15, Score: 1>
  315. <EntryId: 5, Score: 0.0692064>
  316. <EntryId: 1, Score: 0.0482948>
  317. <EntryId: 8, Score: 0.0440592>
  318. searching for image 16 returns 4 results:
  319. <EntryId: 16, Score: 1>
  320. <EntryId: 2, Score: 0.0498792>
  321. <EntryId: 14, Score: 0.03296>
  322. <EntryId: 12, Score: 0.0315461>
  323. searching for image 17 returns 4 results:
  324. <EntryId: 17, Score: 1>
  325. <EntryId: 4, Score: 0.0347258>
  326. <EntryId: 5, Score: 0.0252288>
  327. <EntryId: 6, Score: 0.0242205>
  328. searching for image 18 returns 4 results:
  329. <EntryId: 18, Score: 1>
  330. <EntryId: 14, Score: 0.0362168>
  331. <EntryId: 12, Score: 0.029972>
  332. <EntryId: 13, Score: 0.0242274>
  333. searching for image 19 returns 4 results:
  334. <EntryId: 19, Score: 1>
  335. <EntryId: 15, Score: 0.0301395>
  336. <EntryId: 1, Score: 0.0283448>
  337. <EntryId: 0, Score: 0.0264222>
  338. searching for image 20 returns 4 results:
  339. <EntryId: 20, Score: 1>
  340. <EntryId: 9, Score: 0.136697>
  341. <EntryId: 7, Score: 0.0793399>
  342. <EntryId: 11, Score: 0.0500313>
  343. done.

挑出几个 匹配分数较高的

(注意执行程序里的图片序号和data1文件夹下面的不一样:9对应的是png里面10,20对应的是21,这里学过c++基本语法的大家应该都能够理解)

第一组:构成回环

 

                                  10.png                                                            21.png

第二组:构成回环

 

                                15.png                                                            13.png

第三组:构成回环

                      8.png                                            10.png

第四组:构成回环

 

                     3.png                                        7.png

总结:由于我图片是随便选择的,基本上匹配分数高的都构成回环,但是有时候会出现检测错误的,如果电脑性能较好,可以试试整个数据集,或者从里面选出较多的图像来进行回环检测。


4. 调研相似性评分的常用度量方式,哪些比较常用?

具体的常用度量方法请参考下面的文章:

机器学习中的相似性度量 - 知乎描述样本之间相似度的方法有很多种,一般来说常用的有相关系数和欧式距离。本文对机器学习中常用的相似性度量方法进行了总结。 在做分类时,常常需要估算不同样本之间的相似性度量(Similarity Measurement),这…https://zhuanlan.zhihu.com/p/55493039数据科学中常见的9种距离度量方法,内含欧氏距离、切比雪夫距离等 - 知乎在数据挖掘中,我们经常需要计算样本之间的相似度,通常的做法是计算样本之间的距离。在本文中,数据科学家 Maarten Grootendorst 向我们介绍了 9 种距离度量方法,其中包括欧氏距离、余弦相似度等。选自towardsda…https://zhuanlan.zhihu.com/p/350744027

(1)欧式距离

matlab程序如下:

转载于:【数据挖掘】MATLAB实现欧氏距离计算_小羊咩咩的博客-CSDN博客_matlab计算欧式距离

  1. % 方法1
  2. function dist = dist_E(x,y)
  3. dist = [];
  4. if(length(x)~=length(y))
  5. disp('length of input vectors must agree') % disp函数会直接将内容输出在Matlab命令窗口中
  6. else
  7. z =(x-y).*(x-y);
  8. dist = sqrt(sum(z));
  9. end
  10. end
  1. % 方法2:公式法
  2. function dist = dist_E(x,y)
  3. [m,n] = size(x);
  4. dist = 0;
  5. for i=1:max(m,n)
  6. dist = dist+(x(i)-y(i))^2;
  7. end
  8. dist = sqrt(dist);
  9. end
  1. % 方法3:采用pdist函数
  2. function dist = dist_E(x,y)
  3. dist = [x;y];
  4. dist = pdist(dist); % 计算各行向量之间的欧式距离
  5. end

 在命令行输入:

  1. x=[1,3,0,2]; 
  2. y=[2,3,2,0];  
  3. dist=dist_E(x,y)​​​​​​​

按回车键,然后就可以算出两个向量之间的欧氏距离。

(2)曼哈顿距离

  1. import numpy as np
  2. a=[8,2]
  3. b=[5,10]
  4. a_np = np.array(a)
  5. b_np = np.array(b)
  6. dist3 = np.sum(np.abs(a_np-b_np))
  7. print(f"Manhattan Distance = {dist3}\n")
python manhatta.py 
Manhattan Distance = 11

以下代码转载于:[369]python各类距离公式实现_周小董-CSDN博客_python 欧氏距离

(3)切比雪夫距离 

  1. # -*- coding: utf-8 -*-
  2. from numpy import *
  3. vector1 = mat([1,2,3])
  4. vector2 = mat([4,7,5])
  5. print (abs(vector1-vector2).max())
  6. import numpy as np
  7. x=np.random.random(10)
  8. y=np.random.random(10)
  9. #方法一:根据公式求解
  10. d1=np.max(np.abs(x-y))
  11. print('d1:',d1)
  12. #方法二:根据scipy库求解
  13. from scipy.spatial.distance import pdist
  14. X=np.vstack([x,y])
  15. d2=pdist(X,'chebyshev')[0]
  16. print('d2:',d2)
python Chebyshev.py 
  1. 5
  2. d1: 0.7956039912699736
  3. d2: 0.7956039912699736

(3)汉明距离

  1. # -*- coding: utf-8 -*-
  2. from numpy import *
  3. matV = mat([[1,1,0,1,0,1,0,0,1],[0,1,1,0,0,0,1,1,1]])
  4. smstr = nonzero(matV[0]-matV[1])
  5. print(shape(smstr[0])[0])
  6. import numpy as np
  7. from scipy.spatial.distance import pdist
  8. x=np.random.random(10)>0.5
  9. y=np.random.random(10)>0.5
  10. x=np.asarray(x,np.int32)
  11. y=np.asarray(y,np.int32)
  12. #方法一:根据公式求解
  13. d1=np.mean(x!=y)
  14. print('d1:', d1)
  15. #方法二:根据scipy库求解
  16. X=np.vstack([x,y])
  17. d2=pdist(X,'hamming')[0]
  18. print('d2:', d2)
 python hamming.py 
  1. 6
  2. d1: 0.4
  3. d2: 0.4

(4)标准化欧氏距离

  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. x=np.random.random(10)
  4. y=np.random.random(10)
  5. X=np.vstack([x,y])
  6. #方法一:根据公式求解
  7. sk=np.var(X,axis=0,ddof=1)
  8. d1=np.sqrt(((x - y) ** 2 /sk).sum())
  9. print('d1:',d1)
  10. #方法二:根据scipy库求解
  11. from scipy.spatial.distance import pdist
  12. d2=pdist(X,'seuclidean')[0]
  13. print('d2:',d2)
python Standardized_Euclidean.py 
  1. d1: 4.47213595499958
  2. d2: 4.47213595499958

(5)夹角余弦

  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. from scipy.spatial.distance import pdist
  4. '''
  5. x: [0.05627679 0.80556938 0.48002662 0.24378563 0.75763754 0.15353348
  6. 0.54491664 0.1775408 0.50011986 0.55041845]
  7. y: [0.50068882 0.12200178 0.79041352 0.07332715 0.017892 0.57880032
  8. 0.56707591 0.48390753 0.631051 0.20035466]
  9. '''
  10. x = np.random.random(10)
  11. y = np.random.random(10)
  12. # solution1
  13. dist1 = 1 - np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))
  14. # solution2
  15. dist2 = pdist(np.vstack([x, y]), 'cosine')[0]
  16. print('x', x)
  17. print('y', y)
  18. print('dist1:', dist1)
  19. print('dist2:', dist2)
python Cosine.py 
  1. x [0.59758063 0.40859383 0.98186786 0.01670254 0.33830128 0.06095993
  2. 0.80674537 0.90611795 0.08119071 0.24229608]
  3. y [0.43176033 0.2846342 0.41233185 0.37309159 0.24177945 0.68055469
  4. 0.36115457 0.3278653 0.57811011 0.13355709]
  5. dist1: 0.31572330152121986
  6. dist2: 0.31572330152121975

(6)杰卡德距离&杰卡德相似系数

  1. # -*- coding: utf-8 -*-
  2. from numpy import *
  3. from scipy.spatial.distance import pdist # 导入scipy距离公式
  4. matV = mat([[1,1,0,1,0,1,0,0,1],[0,1,1,0,0,0,1,1,1]])
  5. print ("dist.jaccard:", pdist(matV,'jaccard'))
  6. import numpy as np
  7. from scipy.spatial.distance import pdist
  8. x = np.random.random(10) > 0.5
  9. y = np.random.random(10) > 0.5
  10. x = np.asarray(x, np.int32)
  11. y = np.asarray(y, np.int32)
  12. # 方法一:根据公式求解
  13. up = np.double(np.bitwise_and((x != y), np.bitwise_or(x != 0, y != 0)).sum())
  14. down = np.double(np.bitwise_or(x != 0, y != 0).sum())
  15. d1 = (up / down)
  16. print('d1:', d1)
  17. # 方法二:根据scipy库求解
  18. X = np.vstack([x, y])
  19. d2 = pdist(X, 'jaccard')[0]
  20. print('d2:', d2)
python Jaccard.py 
  1. dist.jaccard: [0.75]
  2. d1: 1.0
  3. d2: 1.0

(7)相关系数&相关距离

  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. x=np.random.random(10)
  4. y=np.random.random(10)
  5. #方法一:根据公式求解
  6. x_=x-np.mean(x)
  7. y_=y-np.mean(y)
  8. d1=np.dot(x_,y_)/(np.linalg.norm(x_)*np.linalg.norm(y_))
  9. print('d1:', d1)
  10. #方法二:根据numpy库求解
  11. X=np.vstack([x,y])
  12. d2=np.corrcoef(X)[0][1]
  13. print('d2:', d2)
python correlation.py 
  1. d1: 0.2479989126873464
  2. d2: 0.24799891268734642

5. Chow-Liu 树是什么原理?它是如何被用于构建字典和回环检测的?

参考下面这篇文章:毕业论文整理(二):用依赖树近似离散概率分布 | 文章 | BEWINDOWEB

6. 阅读[118],除了词袋模型,还有哪些用于回环检测的方法?

参考下面两篇文章:

视觉SLAM十四讲(第二版)第11讲习题解答 - 知乎

​综述 | SLAM回环检测方法

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/325238
推荐阅读
相关标签
  

闽ICP备14008679号