内容
本篇博客介绍代码使用,下篇博客介绍论文原理。
介绍
SeqSLAM 是2012年两位澳大利亚的IEEE fellow提出来的,Michael J. Milford, Member, IEEE, Gordon. F. Wyeth, Member, IEEE。是当时第一个在极端环境变化下还能实现的基于视觉的定位系统,“this is the first time vision-based localization has been demonstrated across extreme environmental change.”
其代码地址在github上可以找到:
c++版本: https://github.com/subokita/OpenSeqSLAM (年代久远,需要修改)
MATLAB版本: https://github.com/OpenSLAM-org/openslam_openseqslam (无需修改)
1.代码使用
CMakeLists.txt
project(OPENSEQSLAM)
cmake_minimum_required(VERSION 2.8.0)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS -std=c++11)
find_package(OpenCV 2.4.0 REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(OpenSeqSLAM)
add_executable(OpenSeqSLAM OpenSeqSLAM/main.cpp OpenSeqSLAM/OpenSeqSLAM.cpp)
target_link_libraries(OpenSeqSLAM ${OpenCV_LIBS})
本文同时利用C++版本和MATLAB版本做了实验,因为c++代码年代过于久远,且代码主要借助了opencv来实现。如果我们的电脑opencv版本在2.4.9及以上时,需要对代码进行修改。
修改的地方为:main.cpp 55行附近出现的cvFontQt以及 addText这里
修改后的代码为:
1.主要是将cvFontQt去掉,以及将addText换成putText函数
2.对照MATLAB代码,MATLAB结果比较好,而C++ Matching的结果index 总是相差一位,需要修改一下index,使其正确。
3.更改阈值,使其和MATLAB一致,并在图上写出score。score越低,说明差异越小。
// CvFont font = fontQt("Helvetica", 20.0, CV_RGB(255, 0, 0) );
namedWindow("");
moveWindow("", 0, 0);
char temp[100];
char score[100];
float threshold = 0.9; //这里参照MATLAB版本代码 更改为0.9,原为0.99,太高了.正是利用这个阈值做出了 Precision-Recall曲线
float * index_ptr = matches.ptr<float>(0);
float * score_ptr = matches.ptr<float>(1);
for( int x = 0; x < spring.size(); x++ ) {
int index = static_cast<int>(index_ptr[x]);
/* Append the images together */
Mat appended( 32, 64 * 2, CV_8UC3, Scalar(0) );
spring[x].copyTo( Mat(appended, Rect(0, 0, 64, 32) ));
if( score_ptr[x] < threshold )
winter[index+1].copyTo( Mat(appended, Rect(64, 0, 64, 32) ));
resize(appended, appended, Size(), 8.0, 8.0 );
sprintf( temp, "Spring [%03d]", x );
// addText( appended, temp, Point( 10, 20 ), font );
putText(appended, temp, Point(10,20), FONT_HERSHEY_DUPLEX, 1, cv::Scalar(255,0,0));
/* The lower the score, the lower the differences between images */
if( score_ptr[x] < threshold )
sprintf( temp, "Winter [%03d]", index+1 );
else
sprintf( temp, "Winter [None]" );
sprintf(score, "score : %.3lf", score_ptr[x]);
// addText( appended, temp, Point( 522, 20 ), font );
putText(appended, temp, Point(520,20), FONT_HERSHEY_DUPLEX, 1, cv::Scalar(255,0,0));
putText(appended, score, Point(520,60), FONT_HERSHEY_DUPLEX, 1, cv::Scalar(255,0,0));
imshow( "", appended );
waitKey();
}
2.实验效果(在score阈值为0.9时,正确率为61%)
- 数据集
数据集采集自法国某一地区,是4个不同季节但地点相同的图像。正确的算法应该从一个季节找到另一个季节中与之地点相同的图像编号。 - 实验结果
左侧图为待匹配图,右侧图为找到的匹配图,但是从结果可以看到虽然图像编号很相近,但是地方却不相同,正确的结果应该是spring后面的编号和winter后面的编号一致。
3.论文解释
- 初始化
- diff_matrix
- findMatches
见《SeqSLAM: Visual Route-Based Navigation for Sunny Summer Days and Stormy Winter Nights》论文及代码解读(二)