├── .gitignore
├── CMakeLists.txt
├── COPYING
├── COPYING.LESSER
├── README.md
├── data
└── Vocabulary.voc
├── doc
└── Doxyfile.in
├── insertLicense
└── src
├── CMakeLists.txt
├── applications
├── CMakeLists.txt
├── FeatureExtractor.cpp
├── GFPLoopClosingTest.cpp
├── GenerateBoW.cpp
├── GenerateNN.cpp
├── LearnVocabularyKMeans.cpp
├── NNLoopClosingTest.cpp
├── gflip_cl.cpp
└── gflip_cl_onequery.cpp
├── build_tools
└── FindEigen3.cmake
├── gflip
├── CMakeLists.txt
├── gflip_engine.cpp
└── gflip_engine.hpp
├── gflip_mainpage.h
├── utils
├── CMakeLists.txt
├── Convolution.h
├── Convolution.hpp
├── HierarchicalKMeansClustering.h
├── HierarchicalKMeansClustering.hpp
├── HistogramDistances.h
├── HistogramDistances.hpp
├── KMeansClustering.h
├── KMeansClustering.hpp
├── PeakFinder.h
├── PoseEstimation.cpp
├── PoseEstimation.h
├── Regression.cpp
├── Regression.h
├── SimpleMinMaxPeakFinder.cpp
├── SimpleMinMaxPeakFinder.h
├── SimplePeakFinder.cpp
└── SimplePeakFinder.h
└── vocabulary
├── CMakeLists.txt
├── HierarchicalKMeansClustering.h
├── HierarchicalKMeansClustering.hpp
├── KMeansClustering.h
├── KMeansClustering.hpp
├── Vocabulary.cpp
└── Vocabulary.h
/.gitignore:
--------------------------------------------------------------------------------
1 | CMakeCache.txt
2 | CMakeFiles
3 | Makefile
4 | cmake_install.cmake
5 | install_manifest.txt
6 | bin
7 | lib*
8 | build
9 | *.kate-swp
10 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # This is the main CMake configuration file, you should always do "cmake ." from here and not from subdirs
2 |
3 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
4 |
5 | PROJECT(gflip CXX C)
6 |
7 | SET(CMAKE_VERBOSE_MAKEFILE 0)
8 |
9 | SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${PROJECT_SOURCE_DIR}/src/build_tools")
10 |
11 | if(NOT CMAKE_BUILD_TYPE)
12 | set (CMAKE_BUILD_TYPE Release)
13 | endif(NOT CMAKE_BUILD_TYPE)
14 |
15 | # Set to build shared objects as option
16 | OPTION(BUILD_SHARED_LIBS "Build package with shared libraries." ON)
17 |
18 | add_subdirectory(src)
19 |
20 | #-- Add the doc target to generate the API documentation
21 | option(BUILD_DOC "Build the documentation during install phase or when typed make doc" ON)
22 | if(BUILD_DOC)
23 | FIND_PACKAGE(Doxygen)
24 | if (NOT DOXYGEN_FOUND)
25 | message(WARNING "Doxygen is needed to build the documentation. Please install it correctly")
26 | else()
27 | configure_file(${PROJECT_SOURCE_DIR}/doc/Doxyfile.in ${PROJECT_BINARY_DIR}/Doxyfile @ONLY IMMEDIATE)
28 | add_custom_target (doc COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/Doxyfile SOURCES ${PROJECT_BINARY_DIR}/Doxyfile)
29 | message(STATUS ${PROJECT_BINARY_DIR})
30 | install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build ${PROJECT_BINARY_DIR} --target doc)")
31 | message(STATUS ${PROJECT_BINARY_DIR})
32 | install(DIRECTORY ${PROJECT_BINARY_DIR}/doc/html DESTINATION share/${PROJECT_NAME}/doc)
33 | endif()
34 | endif()
35 |
36 | # Install the licenses and the README
37 | install(FILES ${PROJECT_SOURCE_DIR}/COPYING ${PROJECT_SOURCE_DIR}/COPYING.LESSER ${PROJECT_SOURCE_DIR}/README DESTINATION share/${PROJECT_NAME})
38 |
39 | # Install the datasets
40 | install(DIRECTORY ${PROJECT_SOURCE_DIR}/data DESTINATION share/${PROJECT_NAME} PATTERN ".svn" EXCLUDE)
41 |
--------------------------------------------------------------------------------
/COPYING.LESSER:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | gflip
2 | =====
3 |
4 | GFLIP - Geometric FLIRT Phrases for Large Scale Place Recognition
5 |
--------------------------------------------------------------------------------
/data/Vocabulary.voc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tipaldi/gflip/d9ef02b8ed8ce0c5b4a645fd391dcdce9709c611/data/Vocabulary.voc
--------------------------------------------------------------------------------
/insertLicense:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | CH='/usr/local/bin/copyright-header'
4 |
5 | SW='GFLIP'
6 | DESC="Geometrical FLIRT Phrases for Large Scale Place Recognition"
7 | HOLDER="Gian Diego Tipaldi and Luciano Spinello and Wolfram Burgard"
8 | YEAR="2012-2013"
9 |
10 | $CH --copyright-software "$SW" --copyright-software-description "$DESC" --copyright-holder "$HOLDER" --copyright-year "$YEAR" $@
11 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # ---------------------------- Checking the OS ------------------------------
2 | IF("${CMAKE_SYSTEM}" MATCHES "Linux")
3 | MESSAGE(STATUS "Compiling on Linux")
4 | SET(LINUX 1)
5 | EXEC_PROGRAM("uname" ARGS -m OUTPUT_VARIABLE myArch)
6 | IF("${myArch}" MATCHES "x86_64")
7 | MESSAGE(STATUS " 64-bit architecture detected")
8 | SET(LINUX64 1)
9 | ENDIF("${myArch}" MATCHES "x86_64")
10 | ELSEIF(APPLE)
11 | SET(LINUX 0)
12 | MESSAGE(STATUS "Compiling on MacOSX")
13 | ELSEIF(WIN32)
14 | SET(LINUX 0)
15 | IF(CYGWIN)
16 | MESSAGE(STATUS "Compiling on CygWin")
17 | SET(CYGWIN 1)
18 | ELSE(CYGWIN)
19 | MESSAGE(FATAL_ERROR "Compiling on Windows is not possible at the moment")
20 | ENDIF(CYGWIN)
21 | ENDIF("${CMAKE_SYSTEM}" MATCHES "Linux")
22 |
23 | include(ExternalProject)
24 |
25 | # Set variables for external libraries
26 | INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src)
27 | SET(PROJECT_EXTERNAL_DIR ${PROJECT_SOURCE_DIR}/external)
28 | INCLUDE_DIRECTORIES(${PROJECT_EXTERNAL_DIR})
29 |
30 |
31 | # Library: FLIRT
32 | set(FLIRT_INSTALL_DIR ${PROJECT_EXTERNAL_DIR}/flirtlib)
33 | ExternalProject_Add(flirt
34 | PREFIX ${FLIRT_INSTALL_DIR}
35 | SVN_REPOSITORY https://svn.openslam.org/data/svn/flirtlib/trunk
36 | SVN_TRUST_CERT 1
37 | CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${FLIRT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_DOC=OFF -DBUILD_GUI=OFF
38 | INSTALL_DIR ${FLIRT_INSTALL_DIR}
39 | )
40 | INCLUDE_DIRECTORIES(${FLIRT_INSTALL_DIR}/include/flirtlib)
41 | LINK_DIRECTORIES(${FLIRT_INSTALL_DIR}/lib/flirtlib)
42 | install(DIRECTORY ${FLIRT_INSTALL_DIR}/share/flirtlib/data DESTINATION share/${PROJECT_NAME} PATTERN ".svn" EXCLUDE)
43 |
44 | # Library: Boost
45 | set(Boost_USE_MULTITHREADED ON)
46 | FIND_PACKAGE(Boost 1.36.0 COMPONENTS program_options serialization)
47 | #FIND_PACKAGE(Boost COMPONENTS program_options math graph)
48 | IF(Boost_FOUND)
49 | MESSAGE(STATUS "Boost found")
50 | IF($ENV{VERBOSE})
51 | MESSAGE(STATUS " Boost_INCLUDE_DIR = ${Boost_INCLUDE_DIR}")
52 | MESSAGE(STATUS " Boost_LINK_DIRECTORIES = ${Boost_LINK_DIRECTORIES}")
53 | MESSAGE(STATUS " Boost Version = m:${Boost_MINOR_VERSION} M:${Boost_MAJOR_VERSION} v:${Boost_VERSION}")
54 | ENDIF($ENV{VERBOSE})
55 | INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
56 | LINK_DIRECTORIES(${Boost_LINK_DIRECTORIES})
57 | ELSE(Boost_FOUND)
58 | MESSAGE(FATAL_ERROR " Boost not found, it is REQUIRED to build the FLIRT.\n Boost can be found on http://www.boost.org")
59 | ENDIF(Boost_FOUND)
60 |
61 | # Library: Eigen3
62 | INCLUDE(./build_tools/FindEigen3.cmake REQUIRED)
63 | IF(EIGEN3_FOUND)
64 | MESSAGE(STATUS "Eigen3 found")
65 | IF($ENV{VERBOSE})
66 | MESSAGE(STATUS " EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}")
67 | ENDIF($ENV{VERBOSE})
68 | INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIR})
69 | ELSE(EIGEN3_FOUND)
70 | MESSAGE(FATAL_ERROR " Eigen3 not found, but it is REQUIRED to build FLIRT.")
71 | ENDIF(EIGEN3_FOUND)
72 |
73 | # Optimization
74 | SET(LOCAL_OPTIMIZATION_FLAGS "-O3 -march=nocona -msse4.1 -funroll-loops -ftree-vectorize -DTBB -mfpmath=both")
75 | # SET(LOCAL_OPTIMIZATION_FLAGS "-O3 -march=native -msse4.2 -msse4.1 -funroll-loops -ftree-vectorize -DTBB -mfpmath=both")
76 | SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${LOCAL_OPTIMIZATION_FLAGS}")
77 | SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=gnu++0x ${LOCAL_OPTIMIZATION_FLAGS}")
78 |
79 | #Debug (it can clash with optimization)
80 | SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g3 -ggdb3 -fno-inline -Wall")
81 | SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=gnu++0x -O0 -g3 -ggdb3 -fno-inline -Wall")
82 |
83 | #Profiling
84 | #ADD_DEFINITIONS(-pg)
85 | #SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg")
86 | #SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
87 |
88 |
89 | # RPATH Handling during building and installation phases
90 | set(CMAKE_SKIP_BUILD_RPATH FALSE)
91 | set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
92 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
93 | SET(CMAKE_INSTALL_RPATH "${FLIRT_INSTALL_DIR}/lib/flirtlib:$ORIGIN/../lib/${CMAKE_PROJECT_NAME}")
94 | #
95 | # # use, i.e. don't skip the full RPATH for the build tree
96 | # SET(CMAKE_SKIP_BUILD_RPATH FALSE)
97 | # # when building, don't use the install RPATH already
98 | # # (but later on when installing)
99 | # SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
100 | # # set(INSTALL_RPATH_USE_LINK_PATH true)
101 | # # Set the install RPATH relative to the binaries
102 |
103 | # # add the automatically determined parts of the RPATH
104 | # # which point to directories outside the build tree to the install RPATH
105 | # SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
106 | # # the RPATH to be used when installing, but only if it's not a system directory
107 | # # LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_PROJECT_NAME}" isSystemDir)
108 | # # IF("${isSystemDir}" STREQUAL "-1")
109 | # # SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_PROJECT_NAME}")
110 | # # ENDIF("${isSystemDir}" STREQUAL "-1")
111 |
112 |
113 | add_subdirectory(gflip)
114 | ADD_SUBDIRECTORY(vocabulary)
115 | ADD_SUBDIRECTORY(applications)
116 |
117 | message(STATUS "INSTALL_RPATH: ${INSTALL_RPATH}")
118 | message(STATUS "CMAKE_INSTALL_RPATH: ${CMAKE_INSTALL_RPATH}")
119 |
120 |
121 |
--------------------------------------------------------------------------------
/src/applications/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ADD_EXECUTABLE(featureExtractor FeatureExtractor.cpp)
2 | TARGET_LINK_LIBRARIES(featureExtractor feature geometry sensorstream sensors utils boost_serialization)
3 | ADD_DEPENDENCIES(featureExtractor flirt)
4 |
5 | ADD_EXECUTABLE(learnVocabularyKMeans LearnVocabularyKMeans.cpp)
6 | TARGET_LINK_LIBRARIES(learnVocabularyKMeans vocabulary feature geometry sensorstream sensors utils boost_serialization)
7 | ADD_DEPENDENCIES(learnVocabularyKMeans flirt)
8 | #SET_SOURCE_FILES_PROPERTIES(LearnVocabularyKMeans.cpp PROPERTIES COMPILE_FLAGS "-O0 -ggdb ")
9 |
10 | ADD_EXECUTABLE(generateBoW GenerateBoW.cpp)
11 | TARGET_LINK_LIBRARIES(generateBoW vocabulary feature geometry sensorstream sensors utils boost_filesystem boost_serialization)
12 | ADD_DEPENDENCIES(generateBoW flirt)
13 |
14 | ADD_EXECUTABLE(nnLoopClosingTest NNLoopClosingTest.cpp)
15 | TARGET_LINK_LIBRARIES(nnLoopClosingTest feature geometry sensorstream sensors utils boost_filesystem boost_serialization)
16 | ADD_DEPENDENCIES(nnLoopClosingTest flirt)
17 | #SET_SOURCE_FILES_PROPERTIES(NNLoopClosingTest.cpp PROPERTIES COMPILE_FLAGS "-O0 -ggdb ")
18 |
19 | ADD_EXECUTABLE(generateNN GenerateNN.cpp)
20 | TARGET_LINK_LIBRARIES(generateNN vocabulary feature geometry sensorstream sensors utils boost_filesystem gflip boost_serialization)
21 | ADD_DEPENDENCIES(generateNN flirt)
22 | #SET_SOURCE_FILES_PROPERTIES(NNLoopClosingTest.cpp PROPERTIES COMPILE_FLAGS "-O0 -ggdb ")
23 |
24 | ADD_EXECUTABLE(GFPLoopClosingTest GFPLoopClosingTest.cpp)
25 | TARGET_LINK_LIBRARIES(GFPLoopClosingTest vocabulary feature geometry sensorstream sensors utils boost_filesystem gflip boost_serialization)
26 | ADD_DEPENDENCIES(GFPLoopClosingTest flirt)
27 | #SET_SOURCE_FILES_PROPERTIES(NNLoopClosingTest.cpp PROPERTIES COMPILE_FLAGS "-O0 -ggdb ")
28 |
29 | ADD_EXECUTABLE(gflip_cl gflip_cl.cpp)
30 | TARGET_LINK_LIBRARIES(gflip_cl gflip)
31 |
32 | ADD_EXECUTABLE(gflip_cl_onequery gflip_cl_onequery.cpp)
33 | TARGET_LINK_LIBRARIES(gflip_cl_onequery gflip)
34 |
35 | install(TARGETS featureExtractor learnVocabularyKMeans generateBoW nnLoopClosingTest generateNN GFPLoopClosingTest gflip_cl gflip_cl_onequery
36 | RUNTIME DESTINATION bin
37 | LIBRARY DESTINATION lib/flirtlib
38 | ARCHIVE DESTINATION lib/flirtlib)
39 |
--------------------------------------------------------------------------------
/src/applications/FeatureExtractor.cpp:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // GFLIP - Geometrical FLIRT Phrases for Large Scale Place Recognition
4 | // Copyright (C) 2012-2013 Gian Diego Tipaldi and Luciano Spinello and Wolfram
5 | // Burgard
6 | //
7 | // This file is part of GFLIP.
8 | //
9 | // GFLIP is free software: you can redistribute it and/or modify
10 | // it under the terms of the GNU Lesser General Public License as published by
11 | // the Free Software Foundation, either version 3 of the License, or
12 | // (at your option) any later version.
13 | //
14 | // GFLIP is distributed in the hope that it will be useful,
15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | // GNU Lesser General Public License for more details.
18 | //
19 | // You should have received a copy of the GNU Lesser General Public License
20 | // along with GFLIP. If not, see .
21 | //
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 |
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 |
42 | #include
43 |
44 | #include
45 | #include
46 | #include
47 | #include
48 | #include
49 | #include
50 |
51 | #include
52 |
53 | LogSensorStream m_sensorReference(NULL,NULL);
54 |
55 | CurvatureDetector *m_detectorCurvature = NULL;
56 | NormalBlobDetector *m_detectorNormalBlob = NULL;
57 | NormalEdgeDetector *m_detectorNormalEdge = NULL;
58 | RangeDetector *m_detectorRange = NULL;
59 | Detector* m_detector = NULL;
60 |
61 | BetaGridGenerator *m_betaGenerator = NULL;
62 | ShapeContextGenerator *m_shapeGenerator = NULL;
63 | DescriptorGenerator *m_descriptor = NULL;
64 |
65 | std::vector< std::vector > m_pointsReference;
66 | std::vector< OrientedPoint2D > m_posesReference;
67 |
68 | struct timeval detectTime, describeTime;
69 |
70 | void detectLog(){
71 | unsigned int i = 0;
72 | unsigned int position = m_sensorReference.tell();
73 | m_sensorReference.seek(0,END);
74 | unsigned int last = m_sensorReference.tell();
75 | m_sensorReference.seek(0);
76 |
77 | std::string bar(50, ' ');
78 |
79 | struct timeval start, end;
80 | gettimeofday(&start, NULL);
81 | while(!m_sensorReference.end()){
82 | bar[(m_sensorReference.tell()*50)/last] = '#';
83 | std::cout << "\rDetecting points [" << bar << "] " << (m_sensorReference.tell()*100)/last << "%" << std::flush;
84 | const LaserReading* lreadReference = dynamic_cast(m_sensorReference.next());
85 | if (lreadReference){
86 | m_detector->detect(*lreadReference, m_pointsReference[i]);
87 | m_posesReference[i] = lreadReference->getLaserPose();
88 | i++;
89 | }
90 | }
91 | gettimeofday(&end,NULL);
92 | timersub(&end,&start,&detectTime);
93 | m_sensorReference.seek(position);
94 | std::cout << "done. Time elapsed " << double(detectTime.tv_sec) + 1e-06 * double(detectTime.tv_usec) << std::endl;
95 | }
96 |
97 | void countLog(){
98 | double flirtNum = 0.;
99 | uint count = 0;
100 |
101 | std::string bar(50, ' ');
102 |
103 | for(unsigned int i = 0; i < m_pointsReference.size(); i++){
104 | bar[(i*50)/m_pointsReference.size()] = '#';
105 | std::cout << "\rCounting points [" << bar << "] " << (i*100)/m_pointsReference.size() << "%" << std::flush;
106 | if(m_pointsReference[i].size()){
107 | flirtNum += m_pointsReference[i].size();
108 | count++;
109 | }
110 | }
111 | flirtNum=count?flirtNum/double(count):0.;
112 | std::cout << "done: Total: " << flirtNum*double(count) << ", Avg: " << flirtNum << std::endl;
113 | }
114 |
115 | void describeLog(){
116 | unsigned int i = 0;
117 | unsigned int position = m_sensorReference.tell();
118 | m_sensorReference.seek(0,END);
119 | unsigned int last = m_sensorReference.tell();
120 | m_sensorReference.seek(0);
121 |
122 | std::string bar(50, ' ');
123 |
124 | struct timeval start, end;
125 | gettimeofday(&start, NULL);
126 | while(!m_sensorReference.end()){
127 | bar[(m_sensorReference.tell()*50)/last] = '#';
128 | std::cout << "\rDescribing points [" << bar << "] " << (m_sensorReference.tell()*100)/last << "%" << std::flush;
129 | const LaserReading* lreadReference = dynamic_cast(m_sensorReference.next());
130 | if (lreadReference){
131 | for(unsigned int j = 0; j < m_pointsReference[i].size(); j++){
132 | m_pointsReference[i][j]->setDescriptor(m_descriptor->describe(*m_pointsReference[i][j], *lreadReference));
133 | }
134 | i++;
135 | }
136 | }
137 | gettimeofday(&end,NULL);
138 | timersub(&end,&start,&describeTime);
139 | m_sensorReference.seek(position);
140 | std::cout << "done. Time elapsed " << double(describeTime.tv_sec) + 1e-06 * double(describeTime.tv_usec) << std::endl;
141 | }
142 |
143 | void writeGspan(std::ostream& out, const std::vector >& points){
144 | for(unsigned int i = 0; i < points.size(); i++) {
145 | out << "t # " << i << std::endl;
146 | for(unsigned int v = 0; v < points[i].size(); v++) {
147 | out << "v " << v << " a " << points[i][v]->getPosition().x << " " << points[i][v]->getPosition().y << " 0.0" << std::endl;
148 | }
149 | if(points[i].size() < 2) continue;
150 | std::vector usedVertexes(points[i].size(), false);
151 | usedVertexes[0] = true;
152 | unsigned int vertexCount = 1;
153 | while(vertexCount != points[i].size()){
154 | unsigned int minIndex1 = 0;
155 | unsigned int minIndex2 = 0;
156 | double minDistance = 1e10;
157 | for(unsigned int j = 0; j < points[i].size(); j++) {
158 | if(!usedVertexes[j]) continue;
159 | for(unsigned int k = 0; k < points[i].size(); k++) {
160 | if(usedVertexes[k]) continue;
161 | Point2D delta = points[i][j]->getPosition() - points[i][k]->getPosition();
162 | double currentDistance = delta * delta;
163 | if(currentDistance < minDistance){
164 | minDistance = currentDistance;
165 | minIndex1 = j;
166 | minIndex2 = k;
167 | }
168 | }
169 | }
170 | out << "e " << minIndex1 << " " << minIndex2 << " sparse" << std::endl;
171 | usedVertexes[minIndex2] = true;
172 | vertexCount++;
173 | }
174 | }
175 | }
176 |
177 | int main(int argc, char **argv){
178 |
179 | std::string filename("");
180 | unsigned int scale = 5, dmst = 2, window = 3, detectorType = 0, descriptorType = 0, distanceType = 2;
181 | double baseSigma = 0.2, sigmaStep = 1.4, minPeak = 0.34, minPeakDistance = 0.001;
182 | bool useMaxRange = false, gspan = false;
183 |
184 | int i = 1;
185 | while(i < argc){
186 | if(strncmp("-filename", argv[i], sizeof("-filename")) == 0 ){
187 | filename = argv[++i];
188 | i++;
189 | } else if(strncmp("-detector", argv[i], sizeof("-detector")) == 0 ){
190 | detectorType = atoi(argv[++i]);
191 | i++;
192 | } else if(strncmp("-descriptor", argv[i], sizeof("-descriptor")) == 0 ){
193 | descriptorType = atoi(argv[++i]);
194 | i++;
195 | } else if(strncmp("-distance", argv[i], sizeof("-distance")) == 0 ){
196 | distanceType = atoi(argv[++i]);
197 | i++;
198 | } else if(strncmp("-baseSigma", argv[i], sizeof("-baseSigma")) == 0 ){
199 | baseSigma = strtod(argv[++i], NULL);
200 | i++;
201 | } else if(strncmp("-sigmaStep", argv[i], sizeof("-sigmaStep")) == 0 ){
202 | sigmaStep = strtod(argv[++i], NULL);
203 | i++;
204 | } else if(strncmp("-minPeak", argv[i], sizeof("-minPeak")) == 0 ){
205 | minPeak = strtod(argv[++i], NULL);
206 | i++;
207 | } else if(strncmp("-minPeakDistance", argv[i], sizeof("-minPeakDistance")) == 0 ){
208 | minPeakDistance = strtod(argv[++i], NULL);
209 | i++;
210 | } else if(strncmp("-gspan", argv[i], sizeof("-gspan")) == 0 ){
211 | gspan = true;
212 | i++;
213 | } else {
214 | i++;
215 | }
216 | }
217 |
218 |
219 | CarmenLogWriter writer;
220 | CarmenLogReader reader;
221 |
222 | m_sensorReference = LogSensorStream(&reader, &writer);
223 |
224 | m_sensorReference.load(filename);
225 |
226 | SimpleMinMaxPeakFinder *m_peakMinMax = new SimpleMinMaxPeakFinder(minPeak, minPeakDistance);
227 |
228 |
229 | std::string detector("");
230 | switch(detectorType){
231 | case 0:
232 | m_detectorCurvature = new CurvatureDetector(m_peakMinMax, scale, baseSigma, sigmaStep, dmst);
233 | m_detectorCurvature->setUseMaxRange(useMaxRange);
234 | m_detector = m_detectorCurvature;
235 | detector = "curvature";
236 | break;
237 | case 1:
238 | m_detectorNormalEdge = new NormalEdgeDetector(m_peakMinMax, scale, baseSigma, sigmaStep, window);
239 | m_detector = m_detectorNormalEdge;
240 | detector = "edge";
241 | break;
242 | case 2:
243 | m_detectorNormalBlob = new NormalBlobDetector(m_peakMinMax, scale, baseSigma, sigmaStep, window);
244 | m_detector = m_detectorNormalBlob;
245 | detector = "blob";
246 | break;
247 | case 3:
248 | m_detectorRange = new RangeDetector(m_peakMinMax, scale, baseSigma, sigmaStep);
249 | m_detector = m_detectorRange;
250 | detector = "range";
251 | break;
252 | default:
253 | std::cerr << "Wrong detector type" << std::endl;
254 | exit(-1);
255 | }
256 |
257 | HistogramDistance *dist = NULL;
258 |
259 | std::string distance("");
260 | switch(distanceType){
261 | case 0:
262 | dist = new EuclideanDistance();
263 | distance = "euclid";
264 | break;
265 | case 1:
266 | dist = new Chi2Distance();
267 | distance = "chi2";
268 | break;
269 | case 2:
270 | dist = new SymmetricChi2Distance();
271 | distance = "symchi2";
272 | break;
273 | case 3:
274 | dist = new BatthacharyyaDistance();
275 | distance = "batt";
276 | break;
277 | case 4:
278 | dist = new KullbackLeiblerDistance();
279 | distance = "kld";
280 | break;
281 | case 5:
282 | dist = new JensenShannonDistance();
283 | distance = "jsd";
284 | break;
285 | default:
286 | std::cerr << "Wrong distance type" << std::endl;
287 | exit(-1);
288 | }
289 |
290 | std::string descriptor("");
291 | switch(descriptorType){
292 | case 0:
293 | m_betaGenerator = new BetaGridGenerator(0.02, 0.5, 4, 12);
294 | m_betaGenerator->setDistanceFunction(dist);
295 | m_descriptor = m_betaGenerator;
296 | descriptor = "beta";
297 | break;
298 | case 1:
299 | m_shapeGenerator = new ShapeContextGenerator(0.02, 0.5, 4, 12);
300 | m_shapeGenerator->setDistanceFunction(dist);
301 | m_descriptor = m_shapeGenerator;
302 | descriptor = "shape";
303 | break;
304 | default:
305 | std::cerr << "Wrong descriptor type" << std::endl;
306 | exit(-1);
307 | }
308 |
309 | std::cerr << "Processing file:\t" << filename << "\nDetector:\t\t" << detector << "\nDescriptor:\t\t" << descriptor << "\nDistance:\t\t" << distance << std::endl;
310 |
311 | m_sensorReference.seek(0,END);
312 | unsigned int end = m_sensorReference.tell();
313 | m_sensorReference.seek(0,BEGIN);
314 |
315 | m_pointsReference.resize(end + 1);
316 | m_posesReference.resize(end + 1);
317 |
318 | detectLog();
319 |
320 | countLog();
321 | // return 1;
322 |
323 | describeLog();
324 |
325 | std::string outfile = filename.substr(0, filename.find_last_of("."));
326 | outfile.append(".flt");
327 |
328 | if(gspan){
329 | std::string gspanfile = filename.substr(0, filename.find_last_of("."));
330 | gspanfile.append(".gspan");
331 | std::ofstream gspanStream(gspanfile.c_str());
332 | writeGspan(gspanStream, m_pointsReference);
333 | }
334 |
335 | std::ofstream outputStream(outfile.c_str());
336 | // boost::archive::xml_oarchive archive(outputStream);
337 | boost::archive::binary_oarchive archive(outputStream);
338 |
339 |
340 | std::cout << "Saving the points reference " << BOOST_PP_STRINGIZE(m_pointsReference) << std::endl;
341 | archive << BOOST_SERIALIZATION_NVP(m_pointsReference);
342 | std::cout << "Saving the points generators " << BOOST_PP_STRINGIZE(m_betaGenerator->getPhiEdges()) << std::endl;
343 | if(m_betaGenerator) {
344 |
345 | archive << boost::serialization::make_nvp("phiEdges", m_betaGenerator->getPhiEdges());
346 | archive << boost::serialization::make_nvp("rhoEdges", m_betaGenerator->getRhoEdges());
347 | } else if(m_shapeGenerator) {
348 | archive << boost::serialization::make_nvp("phiEdges", m_shapeGenerator->getPhiEdges());
349 | archive << boost::serialization::make_nvp("rhoEdges", m_shapeGenerator->getRhoEdges());
350 | }
351 | std::cout << "done" << std::endl;
352 |
353 | outputStream.close();
354 |
355 | // Uncomment for Serialization test
356 | // const InterestPoint* testPoint = m_pointsReference.back().back();
357 | // unsigned int numPoints = 0;
358 | // for(unsigned int j = 0; j < m_pointsReference.size(); numPoints += m_pointsReference[j++].size()){
359 | // std::cerr << numPoints << " " << m_pointsReference[j].size() << std::endl;
360 | //
361 | // }
362 | //
363 | // std::cout << "Filename: " << outfile
364 | // << ", Scans: " << m_pointsReference.size()
365 | // << ", Points: " << numPoints
366 | // << ", Avg: " << double(numPoints)/double(m_pointsReference.size()) << std::endl << std::endl;
367 | // std::cout << "Test Point: end, end" << std::endl
368 | // << testPoint->getPosition() << std::endl
369 | // << testPoint->getScale() << std::endl
370 | // << testPoint->getScaleLevel() << std::endl
371 | // << typeid(*testPoint->getDescriptor()).name() << std::endl
372 | // << testPoint->getSupport().size() << std::endl;
373 |
374 |
375 | }
376 |
377 |
--------------------------------------------------------------------------------
/src/applications/GenerateBoW.cpp:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // GFLIP - Geometrical FLIRT Phrases for Large Scale Place Recognition
4 | // Copyright (C) 2012-2013 Gian Diego Tipaldi and Luciano Spinello and Wolfram
5 | // Burgard
6 | //
7 | // This file is part of GFLIP.
8 | //
9 | // GFLIP is free software: you can redistribute it and/or modify
10 | // it under the terms of the GNU Lesser General Public License as published by
11 | // the Free Software Foundation, either version 3 of the License, or
12 | // (at your option) any later version.
13 | //
14 | // GFLIP is distributed in the hope that it will be useful,
15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | // GNU Lesser General Public License for more details.
18 | //
19 | // You should have received a copy of the GNU Lesser General Public License
20 | // along with GFLIP. If not, see .
21 | //
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 |
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 | #include