1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
9 // This file originates from the openFABMAP project:
10 // [http://code.google.com/p/openfabmap/]
12 // For published work which uses all or part of OpenFABMAP, please cite:
13 // [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6224843]
15 // Original Algorithm by Mark Cummins and Paul Newman:
16 // [http://ijr.sagepub.com/content/27/6/647.short]
17 // [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=5613942]
18 // [http://ijr.sagepub.com/content/30/9/1100.abstract]
22 // Copyright (C) 2012 Arren Glover [aj.glover@qut.edu.au] and
23 // Will Maddern [w.maddern@qut.edu.au], all rights reserved.
26 // Redistribution and use in source and binary forms, with or without modification,
27 // are permitted provided that the following conditions are met:
29 // * Redistribution's of source code must retain the above copyright notice,
30 // this list of conditions and the following disclaimer.
32 // * Redistribution's in binary form must reproduce the above copyright notice,
33 // this list of conditions and the following disclaimer in the documentation
34 // and/or other materials provided with the distribution.
36 // * The name of the copyright holders may not be used to endorse or promote products
37 // derived from this software without specific prior written permission.
39 // This software is provided by the copyright holders and contributors "as is" and
40 // any express or implied warranties, including, but not limited to, the implied
41 // warranties of merchantability and fitness for a particular purpose are disclaimed.
42 // In no event shall the Intel Corporation or contributors be liable for any direct,
43 // indirect, incidental, special, exemplary, or consequential damages
44 // (including, but not limited to, procurement of substitute goods or services;
45 // loss of use, data, or profits; or business interruption) however caused
46 // and on any theory of liability, whether in contract, strict liability,
47 // or tort (including negligence or otherwise) arising in any way out of
48 // the use of this software, even if advised of the possibility of such damage.
52 #ifndef __OPENCV_OPENFABMAP_H_
53 #define __OPENCV_OPENFABMAP_H_
55 #include "opencv2/core/core.hpp"
56 #include "opencv2/features2d/features2d.hpp"
73 Return data format of a FABMAP compare call
75 struct CV_EXPORTS IMatch {
78 queryIdx(-1), imgIdx(-1), likelihood(-DBL_MAX), match(-DBL_MAX) {
80 IMatch(int _queryIdx, int _imgIdx, double _likelihood, double _match) :
81 queryIdx(_queryIdx), imgIdx(_imgIdx), likelihood(_likelihood), match(
85 int queryIdx; //query index
86 int imgIdx; //test index
88 double likelihood; //raw loglikelihood
89 double match; //normalised probability
91 bool operator<(const IMatch& m) const {
92 return match < m.match;
98 Base FabMap class. Each FabMap method inherits from this class.
100 class CV_EXPORTS FabMap {
112 FabMap(const Mat& clTree, double PzGe, double PzGNe, int flags,
116 //methods to add training data for sampling method
117 virtual void addTraining(const Mat& queryImgDescriptor);
118 virtual void addTraining(const vector<Mat>& queryImgDescriptors);
120 //methods to add to the test data
121 virtual void add(const Mat& queryImgDescriptor);
122 virtual void add(const vector<Mat>& queryImgDescriptors);
125 const vector<Mat>& getTrainingImgDescriptors() const;
126 const vector<Mat>& getTestImgDescriptors() const;
128 //Main FabMap image comparison
129 void compare(const Mat& queryImgDescriptor,
130 vector<IMatch>& matches, bool addQuery = false,
131 const Mat& mask = Mat());
132 void compare(const Mat& queryImgDescriptor,
133 const Mat& testImgDescriptors, vector<IMatch>& matches,
134 const Mat& mask = Mat());
135 void compare(const Mat& queryImgDescriptor,
136 const vector<Mat>& testImgDescriptors,
137 vector<IMatch>& matches, const Mat& mask = Mat());
138 void compare(const vector<Mat>& queryImgDescriptors, vector<
139 IMatch>& matches, bool addQuery = false, const Mat& mask =
141 void compare(const vector<Mat>& queryImgDescriptors,
142 const vector<Mat>& testImgDescriptors,
143 vector<IMatch>& matches, const Mat& mask = Mat());
147 void compareImgDescriptor(const Mat& queryImgDescriptor,
148 int queryIndex, const vector<Mat>& testImgDescriptors,
149 vector<IMatch>& matches);
151 void addImgDescriptor(const Mat& queryImgDescriptor);
153 //the getLikelihoods method is overwritten for each different FabMap
155 virtual void getLikelihoods(const Mat& queryImgDescriptor,
156 const vector<Mat>& testImgDescriptors,
157 vector<IMatch>& matches);
158 virtual double getNewPlaceLikelihood(const Mat& queryImgDescriptor);
160 //turn likelihoods into probabilities (also add in motion model if used)
161 void normaliseDistribution(vector<IMatch>& matches);
165 double Pzq(int q, bool zq);
166 double PzqGzpq(int q, bool zq, bool zpq);
169 double PzqGeq(bool zq, bool eq);
170 double PeqGL(int q, bool Lzq, bool eq);
171 double PzqGL(int q, bool zq, bool zpq, bool Lzq);
172 double PzqGzpqL(int q, bool zq, bool zpq, bool Lzq);
173 double (FabMap::*PzGL)(int q, bool zq, bool zpq, bool Lzq);
177 vector<Mat> trainingImgDescriptors;
178 vector<Mat> testImgDescriptors;
179 vector<IMatch> priorMatches;
195 The original FAB-MAP algorithm, developed based on:
196 http://ijr.sagepub.com/content/27/6/647.short
198 class CV_EXPORTS FabMap1: public FabMap {
200 FabMap1(const Mat& clTree, double PzGe, double PzGNe, int flags,
205 //FabMap1 implementation of likelihood comparison
206 void getLikelihoods(const Mat& queryImgDescriptor, const vector<
207 Mat>& testImgDescriptors, vector<IMatch>& matches);
211 A computationally faster version of the original FAB-MAP algorithm. A look-
212 up-table is used to precompute many of the reoccuring calculations
214 class CV_EXPORTS FabMapLUT: public FabMap {
216 FabMapLUT(const Mat& clTree, double PzGe, double PzGNe,
217 int flags, int numSamples = 0, int precision = 6);
218 virtual ~FabMapLUT();
221 //FabMap look-up-table implementation of the likelihood comparison
222 void getLikelihoods(const Mat& queryImgDescriptor, const vector<
223 Mat>& testImgDescriptors, vector<IMatch>& matches);
233 The Accelerated FAB-MAP algorithm, developed based on:
234 http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=5613942
236 class CV_EXPORTS FabMapFBO: public FabMap {
238 FabMapFBO(const Mat& clTree, double PzGe, double PzGNe, int flags,
239 int numSamples = 0, double rejectionThreshold = 1e-8, double PsGd =
240 1e-8, int bisectionStart = 512, int bisectionIts = 9);
241 virtual ~FabMapFBO();
245 //FabMap Fast Bail-out implementation of the likelihood comparison
246 void getLikelihoods(const Mat& queryImgDescriptor, const vector<
247 Mat>& testImgDescriptors, vector<IMatch>& matches);
249 //stucture used to determine word comparison order
252 q(0), info(0), V(0), M(0) {
255 WordStats(int _q, double _info) :
256 q(_q), info(_info), V(0), M(0) {
264 bool operator<(const WordStats& w) const {
265 return info < w.info;
270 //private fast bail-out necessary functions
271 void setWordStatistics(const Mat& queryImgDescriptor, multiset<WordStats>& wordData);
272 double limitbisection(double v, double m);
273 double bennettInequality(double v, double m, double delta);
274 static bool compInfo(const WordStats& first, const WordStats& second);
278 double rejectionThreshold;
284 The FAB-MAP2.0 algorithm, developed based on:
285 http://ijr.sagepub.com/content/30/9/1100.abstract
287 class CV_EXPORTS FabMap2: public FabMap {
290 FabMap2(const Mat& clTree, double PzGe, double PzGNe, int flags);
293 //FabMap2 builds the inverted index and requires an additional training/test
295 void addTraining(const Mat& queryImgDescriptors) {
296 FabMap::addTraining(queryImgDescriptors);
298 void addTraining(const vector<Mat>& queryImgDescriptors);
300 void add(const Mat& queryImgDescriptors) {
301 FabMap::add(queryImgDescriptors);
303 void add(const vector<Mat>& queryImgDescriptors);
307 //FabMap2 implementation of the likelihood comparison
308 void getLikelihoods(const Mat& queryImgDescriptor, const vector<
309 Mat>& testImgDescriptors, vector<IMatch>& matches);
310 double getNewPlaceLikelihood(const Mat& queryImgDescriptor);
312 //the likelihood function using the inverted index
313 void getIndexLikelihoods(const Mat& queryImgDescriptor, vector<
314 double>& defaults, map<int, vector<int> >& invertedMap,
315 vector<IMatch>& matches);
316 void addToIndex(const Mat& queryImgDescriptor,
317 vector<double>& defaults,
318 map<int, vector<int> >& invertedMap);
321 vector<double> d1, d2, d3, d4;
322 vector<vector<int> > children;
324 // TODO: inverted map a vector?
326 vector<double> trainingDefaults;
327 map<int, vector<int> > trainingInvertedMap;
329 vector<double> testDefaults;
330 map<int, vector<int> > testInvertedMap;
334 A Chow-Liu tree is required by FAB-MAP. The Chow-Liu tree provides an
335 estimate of the full distribution of visual words using a minimum spanning
336 tree. The tree is generated through training data.
338 class CV_EXPORTS ChowLiuTree {
341 virtual ~ChowLiuTree();
343 //add data to the chow-liu tree before calling make
344 void add(const Mat& imgDescriptor);
345 void add(const vector<Mat>& imgDescriptors);
347 const vector<Mat>& getImgDescriptors() const;
349 Mat make(double infoThreshold = 0.0);
352 vector<Mat> imgDescriptors;
353 Mat mergedImgDescriptors;
355 typedef struct info {
361 //probabilities extracted from mergedImgDescriptors
362 double P(int a, bool za);
363 double JP(int a, bool za, int b, bool zb); //a & b
364 double CP(int a, bool za, int b, bool zb); // a | b
366 //calculating mutual information of all edges
367 void createBaseEdges(list<info>& edges, double infoThreshold);
368 double calcMutInfo(int word1, int word2);
369 static bool sortInfoScores(const info& first, const info& second);
371 //selecting minimum spanning egdges with maximum information
372 bool reduceEdgesToMinSpan(list<info>& edges);
374 //building the tree sctructure
375 Mat buildTree(int root_word, list<info> &edges);
376 void recAddToTree(Mat &cltree, int q, int pq,
377 list<info> &remaining_edges);
378 vector<int> extractChildren(list<info> &remaining_edges, int q);
383 A custom vocabulary training method based on:
384 http://www.springerlink.com/content/d1h6j8x552532003/
386 class CV_EXPORTS BOWMSCTrainer: public BOWTrainer {
388 BOWMSCTrainer(double clusterSize = 0.4);
389 virtual ~BOWMSCTrainer();
391 // Returns trained vocabulary (i.e. cluster centers).
392 virtual Mat cluster() const;
393 virtual Mat cluster(const Mat& descriptors) const;
405 #endif /* OPENFABMAP_H_ */