├── CMakeLists.txt
├── LICENSE
├── README.md
├── include
└── htmap
│ ├── HTMap.h
│ ├── bayes
│ └── BayesFilter.h
│ ├── imgdesc
│ ├── GlobalDescriptor.h
│ ├── KeypointDescriptor.h
│ ├── KeypointDetector.h
│ └── ldb.h
│ ├── lc
│ └── LoopCloser.h
│ ├── map
│ ├── HighLevelMap.h
│ └── Location.h
│ └── util
│ ├── Image.h
│ ├── Params.h
│ ├── Statistics.h
│ └── Util.h
├── launch
└── htmap.launch
├── matlab
├── PR.m
├── PR_curve.m
├── PR_curves.m
├── computeDistance.m
├── computeGPSDist.m
├── computeTotalDistanceGPS.m
├── generateGroundTruth.m
├── get_files.m
├── gtruths
│ ├── groundtruth_CC.mat
│ ├── groundtruth_KITTI00.mat
│ ├── groundtruth_KITTI05.mat
│ ├── groundtruth_KITTI06.mat
│ ├── groundtruth_NC.mat
│ └── groundtruth_StLucia.mat
├── haversine.m
├── load_loops_data.m
├── plot_path.m
├── plot_times.m
├── plot_times_bars.m
├── plot_topmap.m
└── sparsity.m
├── package.xml
├── ros
├── README.md
└── ros.def
└── src
├── HTMap.cpp
├── bayes
└── BayesFilter.cpp
├── imgdesc
├── GlobalDescriptor.cpp
├── KeypointDescriptor.cpp
├── KeypointDetector.cpp
└── ldb.cpp
├── lc
└── LoopCloser.cpp
├── map
├── HighLevelMap.cpp
└── Location.cpp
├── nodes
└── HTMap_node.cpp
└── util
├── Params.cpp
├── Statistics.cpp
└── Util.cpp
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(htmap)
3 |
4 | # Catkin dependencies
5 | find_package(catkin REQUIRED COMPONENTS
6 | roscpp
7 | std_msgs
8 | sensor_msgs
9 | image_transport
10 | cv_bridge
11 | geometry_msgs
12 | obindex
13 | )
14 |
15 | # System dependencies
16 | find_package(OpenCV REQUIRED)
17 | find_package(Boost REQUIRED COMPONENTS system filesystem)
18 | find_package(OpenMP REQUIRED)
19 | if(OPENMP_FOUND)
20 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
21 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
22 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
23 | endif()
24 |
25 | # Defining the package
26 | catkin_package(
27 | INCLUDE_DIRS include
28 | LIBRARIES keypoint_description_htmap #htmap
29 | CATKIN_DEPENDS
30 | roscpp
31 | std_msgs
32 | sensor_msgs
33 | image_transport
34 | cv_bridge
35 | geometry_msgs
36 | obindex
37 | DEPENDS OpenCV Boost
38 | )
39 |
40 | ###########
41 | ## Build ##
42 | ###########
43 |
44 | # Including directories.
45 | include_directories(
46 | include
47 | ${catkin_INCLUDE_DIRS}
48 | ${OpenCV_INCLUDE_DIRS}
49 | ${Boost_INCLUDE_DIRS})
50 |
51 | # Description Library
52 | add_library(description_htmap
53 | src/imgdesc/KeypointDetector.cpp
54 | src/imgdesc/KeypointDescriptor.cpp
55 | src/imgdesc/GlobalDescriptor.cpp
56 | src/imgdesc/ldb.cpp)
57 | target_link_libraries(description_htmap ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})
58 |
59 | # HTMap Library
60 | set(HTMAP_SRCS
61 | src/bayes/BayesFilter.cpp
62 | src/util/Params.cpp
63 | src/util/Statistics.cpp
64 | src/util/Util.cpp
65 | src/map/Location.cpp
66 | src/map/HighLevelMap.cpp
67 | src/lc/LoopCloser.cpp
68 | src/HTMap.cpp
69 | )
70 | add_library(htmap ${HTMAP_SRCS})
71 | target_link_libraries(htmap description_htmap ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${Boost_LIBRARIES})
72 |
73 | # HTMap Node
74 | add_executable(htmap_node src/nodes/HTMap_node.cpp)
75 | target_link_libraries(htmap_node htmap)
76 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HTMap: Hierarchical Topological Mapping
2 |
3 | HTMap is an appearance-based approach for topological mapping based on a hierarchical decomposition of the environment. In HTMap, images with similar visual properties are grouped together in nodes, which are represented by means of an average global descriptor (PHOG) and an index of binary features based on an incremental bag-of-binary-words approach ([OBIndex](http://github.com/emiliofidalgo/obindex)). Each image is represented by means of a global descriptor and a set of local features, and this information is used in a two-level loop closure approach, where, first, global descriptors are employed to obtain the most likely nodes of the map and then binary image features are used to retrieve the most likely images inside these nodes. This hierarchical scheme allows us to reduce the search space when recognizing places, maintaining high accuracy when creating a map. The algorithm can be used to detect loop closures in a unknown environment, without the need of a training stage, as it is usual in BoW schemes.
4 |
5 | This repository contains the code used in our IEEE-TRO [publication](http://ieeexplore.ieee.org/document/7938750/) called *Hierarchical Place Recognition for Topological Mapping*, but adapted to be used with OpenCV 3.x. Given the differentes between OpenCV versions, it might be difficult to reproduce *exactly* the same results of our paper. This code has been released for illustration purposes.
6 |
7 | HTMap is released as a ROS package, and relies on [OpenCV 3.x](http://opencv.org), [OBIndex](http://github.com/emiliofidalgo/obindex) and [Boost](http://www.boost.org) libraries. Note that HTMap is research code. The authors are not responsible for any errors it may contain. **Use it at your own risk!**
8 |
9 | # Conditions of use
10 |
11 | HTMap is distributed under the terms of the [GPL3 License](http://github.com/emiliofidalgo/htmap/blob/master/LICENSE).
12 |
13 | # Related publication
14 |
15 | The details of the algorithm are explained in the [following publication](http://ieeexplore.ieee.org/document/7938750/):
16 |
17 | **Hierarchical Place Recognition for Topological Mapping**
18 | Emilio Garcia-Fidalgo and Alberto Ortiz
19 | IEEE Transactions on Robotics, Vol. 33, No. 5, Pgs. 1061-1074 (Oct. 2017)
20 |
21 | If you use this code, please cite:
22 | ```
23 | @article{Garcia-Fidalgo2017,
24 | author={Emilio Garcia-Fidalgo and Alberto Ortiz},
25 | journal={IEEE Transactions on Robotics},
26 | title={Hierarchical Place Recognition for Topological Mapping},
27 | year={2017},
28 | volume={33},
29 | number={5},
30 | pages={1061-1074},
31 | doi={10.1109/TRO.2017.2704598},
32 | month={Oct}
33 | }
34 | ```
35 |
36 | # Singularity Container
37 |
38 | Find the Singularity image definition files and instructions provided in [ros](ros) folder
39 |
40 | # Installation
41 |
42 | 1. First of all, you need to install [OBIndex](http://github.com/emiliofidalgo/obindex) dependencies:
43 | ```
44 | sudo apt-get install libflann-dev libboost-system-dev libboost-filesystem-dev
45 | ```
46 |
47 | 2. Clone OBIndex in your workspace and change the current branch to *kinetic*:
48 | ```
49 | cd ~/your_workspace/src
50 | git clone http://github.com/emiliofidalgo/obindex.git
51 | cd obindex
52 | git checkout kinetic
53 | ```
54 |
55 | 3. Clone HTMap in your workspace:
56 | ```
57 | cd ~/your_workspace/src
58 | git clone http://github.com/emiliofidalgo/htmap.git
59 | ```
60 |
61 | 4. Compile the packages using, as usual, the `catkin_make` command:
62 | ```
63 | cd ..
64 | catkin_make -DCMAKE_BUILD_TYPE=Release
65 | ```
66 |
67 | 5. As a final step, HTMap requires a writable directory where it stores results and serializes some data. Therefore, we recommend to create one for this purpose at this point:
68 | ```
69 | mkdir -p ~/Desktop/htmap
70 | ```
71 |
72 | # Usage
73 |
74 | - To run HTMap, use the provided launch file:
75 | ```
76 | roslaunch htmap htmap.launch image_dir:="/image/dir" working_dir:="~/Desktop/htmap"
77 | ```
78 | where *image_dir* is a directory containing the sequence of images to be processed and *working_dir* is the directory where the algorithm will store their results and serialization data. This might be the directory we created during the installation procedure.
79 |
80 | There exist several execution parameters that can be configured when running HTMap. See next section for a description of each of them.
81 |
82 | - During the execution, screen will show information about the algorithm, indicating when a loop closure is found.
83 |
84 | - After a succesful execution, HTMap generates, as output, several text files. These files are stored in the *working_dir/results* directory. To speed up the mapping process, some of them are empty, since the corresponding parts of the code are commented. They can be uncommented if needed. The most important files are:
85 |
86 | - *htmap_loops_ninliers.txt*, which is a binary matrix where entry (*i, j*) is 1 if image *i* and image *j* can be considered as the same place, and 0 otherwise. Therefore, the *i-th* row represents the possible loop closures for image *i*. The name *ninliers* refers to the value of the parameter used as the minimum number of inliers to accept a loop. See the paper for further details.
87 |
88 | - *htmap_img2loc_ninliers.txt*, where each line contains the identifier of each image and the location to which that image was assigned during the process.
89 |
90 | - We provide several Matlab scripts to process the resulting files. Along with these scripts, we also provide ground truth files for the datasets used in the paper. If you want to use your own dataset, you should generate your own ground truth file using the same format.
91 |
92 | - In order to obtain a precision / recall value, open Matlab and select the provided *matlab* directory as your working directory. Next, use the following sequence of commands, adapting, of course, the paths (*CC* stands for the *City Centre* dataset):
93 | ```
94 | loop_file = '~/Desktop/htmap/results/htmap_loops_20.txt';
95 | gt_file = 'gtruths/groundtruth_CC.mat';
96 | PR(loop_file, gt_file, true);
97 | ```
98 |
99 | - You can also generate a precision / recall curve after obtaining a set of precision / recall values. In our original paper, these curves were generated modifying the minimum number of inliers to accept a loop. To do that:
100 | - Set the parameter *batch* to *true*.
101 | - Set the parameter *inliers_begin* to the number of inliers that you want to use at the first execution of HTMap.
102 | - Set the parameter *inliers_end* to the number of inliers where the process will stop.
103 | - Set the parameter *inliers_step* to the number of inliers to increment between each execution of HTMap.
104 |
105 |
106 | - Running HTMap under these conditions will execute the algorithm several times modifying the number of inliers and storing the corresponding files in the *results* directory. The precision / recall curve can be obtained using the following sequence of commands, adapting, again, the paths (*CC* stands for the *City Centre* dataset):
107 | ```
108 | res_dir = '~/Desktop/htmap/results/';
109 | gt_file = 'gtruths/groundtruth_CC.mat';
110 | PR_curve(res_dir, gt_file, true);
111 | ```
112 |
113 | - Contact the authors for more information about the other figures in the article.
114 |
115 | # Parameters
116 |
117 | - `image_dir`: Directory where the input images are stored. The images should be named consecutively using the same number of digits. For instance: *image00001.jpg*, *image00002.jpg*, and so on.
118 |
119 | - `working_dir`: Directory where HTMap operates and where the final results will be stored. **This directory should be writable!**.
120 |
121 | - `detector`: Local feature detector method. Options: *FAST*, *BRISK*, *SIFT*, *SURF*, *ORB* and *STAR*. Default: *FAST*.
122 |
123 | - `max_total_kps`: Number of features to find in each input image. Default: *1000*.
124 |
125 | - `descriptor`: Local feature descriptor method. Options: *FREAK*, *BRIEF*, *BRISK*, *ORB* and *LDB*. Default: *LDB*.
126 |
127 | - `gdescriptor`: Holistic method used to describe an image as a whole. Options: *PHOG*, *WI-SIFT*, *WI-SURF*, *WI-LDB* and *Brief-Gist*. Default: *PHOG*.
128 |
129 | - `load_feats`: If *true*, image keypoints and descriptions are loaded from disk, from a previous execution. Otherwise, images are described.
130 |
131 | - `match_method`: Method used to match between two images. Options: *ratio* and *crosscheck*. Default: *ratio*.
132 |
133 | - `match_ratio`: If `match_method` is *ratio*, nearest neighbour distance ratio to match descriptors. Usually, a value of 0.8 is a good option here.
134 |
135 | - `locLC_thresh`: Threshold to select locations according to their similarity with the current image during the coarse loop closure stage. Default: 0.65.
136 |
137 | - `imageLC_min_inliers`: Minimum number of inliers to consider a loop closure candidate as valid. Default: 45.
138 |
139 | - `imageLC_disc_recent`: Number of recent frames discarded to avoid loop closures with images close in time. This is highly dependant of the environment and should be configured accordingly.
140 |
141 | - `imageLC_tloop`: Minimum Bayes Filter sum of probabilities to consider an image as a possible candidate. Default: 0.8.
142 |
143 | - `loc_max_images`: Maximum number of images per location. Default: 500.
144 |
145 | - `max_sim_newnode`: Similarity to consider a new node. Default: 0.20.
146 |
147 | - `batch`: If *true*, the algorithm is executed several times according to the configuration indicated by the *inliers_* parameters. Otherwise, it is executed only once.
148 |
149 | - `inliers_begin`: If `batch` is *true*, the number of inliers to be used at the first execution of HTMap.
150 |
151 | - `inliers_end`: If `batch` is *true*, the number of inliers where the process will stop.
152 |
153 | - `inliers_step`: If `batch` is *true*, the number of inliers to increment between each execution of HTMap.
154 |
155 | # Contact
156 |
157 | If you have problems or questions using this code, please contact the author (emilio.garcia@uib.es). [Feature requests](http://github.com/emiliofidalgo/htmap/issues) and [contributions](http://github.com/emiliofidalgo/htmap/pulls) are totally welcome.
158 |
--------------------------------------------------------------------------------
/include/htmap/HTMap.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of htmap.
3 | *
4 | * Copyright (C) 2018 Emilio Garcia-Fidalgo (University of the Balearic Islands)
5 | *
6 | * htmap is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * htmap is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with htmap. If not, see .
18 | */
19 |
20 | #ifndef HTMAP_H
21 | #define HTMAP_H
22 |
23 | #include
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | #include "htmap/lc/LoopCloser.h"
30 | #include "htmap/map/HighLevelMap.h"
31 | #include "htmap/util/Image.h"
32 | #include "htmap/util/Statistics.h"
33 | #include "htmap/util/Params.h"
34 |
35 | #define SSTR( x ) dynamic_cast< std::ostringstream & >( \
36 | ( std::ostringstream() << std::dec << x ) ).str()
37 |
38 | namespace htmap
39 | {
40 |
41 | class HTMap
42 | {
43 | public:
44 | HTMap(const ros::NodeHandle nh);
45 | ~HTMap();
46 |
47 | void process();
48 | void processBatch();
49 |
50 | private:
51 | // ROS
52 | ros::NodeHandle _nh;
53 |
54 | // Parameters
55 | Params* _params;
56 |
57 | // Statistics
58 | Statistics* _st;
59 |
60 | void describeImages(std::vector& images);
61 | void map(const std::vector& images, HighLevelMap& map, LoopCloser& _lc);
62 | bool isNewLocation(const Image& img, HighLevelMap& map);
63 | };
64 |
65 | }
66 |
67 | #endif // HTMAP_H
68 |
--------------------------------------------------------------------------------
/include/htmap/bayes/BayesFilter.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of htmap.
3 | *
4 | * Copyright (C) 2018 Emilio Garcia-Fidalgo (University of the Balearic Islands)
5 | *
6 | * htmap is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * htmap is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with htmap. If not, see .
18 | */
19 |
20 | #ifndef _BAYESFILTER_H_
21 | #define _BAYESFILTER_H_
22 |
23 | #include
24 | #include
25 | #include
26 | #include