Berkeley SfM
distance_metric.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, The Regents of the University of California (Regents).
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer in the documentation and/or other materials provided
15  * with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Please contact the author(s) of this library if you have any questions.
34  * Authors: Erik Nelson ( eanelson@eecs.berkeley.edu )
35  * David Fridovich-Keil ( dfk@eecs.berkeley.edu )
36  */
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 //
40 // The DistanceMetric class defines a singleton that computes distances between
41 // two descriptors. The descriptor and distance metric have global access via
42 // the DistanceMetric::Instance() method.
43 //
44 ///////////////////////////////////////////////////////////////////////////////
45 
46 #ifndef BSFM_MATCHING_DISTANCE_METRIC_H
47 #define BSFM_MATCHING_DISTANCE_METRIC_H
48 
49 #include <Eigen/Core>
50 #include <glog/logging.h>
51 #include <limits>
52 
53 #include "../util/disallow_copy_and_assign.h"
54 #include "../util/types.h"
55 
56 namespace bsfm {
57 
59  public:
60  // Possible metrics.
61  enum Metric {
64  };
65 
66  // Get the singleton instance of the distance metric.
67  static DistanceMetric& Instance();
68 
69  // Set distance metric type.
70  void SetMetric(const Metric& metric = Metric::SCALED_L2);
71 
72  // Set a maximum tolerable distance between two descriptors. This is not
73  // required, but is useful for comparisons like:
74  //
75  // DistanceMetric& distance = DistanceMetric::Instance();
76  // if (distance(descriptor1, descriptor2) < DistanceMetric::Max()) {
77  // // This is a good match.
78  // }
79  //
80  // By default, a maximum distance is set to infinity, so if this function is
81  // not called, distance(descriptor1, descriptor2) < DistanceMetric::Max()
82  // will always evaluate to true.
83  void SetMaximumDistance(double maximum_distance);
84 
85  // Returns the maximum tolerable distance between two descriptors. If this
86  // value has not been set with 'SetMaximumDistance', returns 0.
87  double Max() const;
88 
89  // Functor method computes distance between two input descriptors.
90  double operator()(const Descriptor& descriptor1,
91  const Descriptor& descriptor2);
92 
93  // Depending on the distance metric used, normalize descriptors.
94  bool MaybeNormalizeDescriptors(std::vector<Descriptor>& descriptors) const;
95 
96  private:
97  // Ensure that DistanceMetric is a singleton.
100 
101  // Compute the L2 norm of the difference between two descriptor vectors. If both
102  // descriptors have unit length, the L2 norm is equal to 2*(1-x.y). Since all
103  // distances are computed this way, we can drop the leading 2*. The L2 norm
104  // induces an inner product space over R^{n}, and we can test as such.
105  double GetScaledL2Distance(const Descriptor& descriptor1,
106  const Descriptor& descriptor2) const;
107 
108  // Compute the Hamming distance between two binary descriptor vectors. This is
109  // the number of bits that are in disagreement (i.e. bit1 ^ bit2 == 1).
110  double GetHammingDistance(const Descriptor& descriptor1,
111  const Descriptor& descriptor2) const;
112 
113  // Normalize all input descriptor vectors.
114  void NormalizeDescriptors(std::vector<Descriptor>& descriptors) const;
115 
116  // The distance metric that will be used.
118 
119  // A maximum tolerable distance between two descriptors. Defaults to
120  // std::numeric_limits<double>::max(), which would imply that all descriptors
121  // match to one another.
123 
124 }; //\class DistanceMetric
125 
126 } //\namespace bsfm
127 
128 #endif
STL namespace.
double GetHammingDistance(const Descriptor &descriptor1, const Descriptor &descriptor2) const
static DistanceMetric & Instance()
void SetMaximumDistance(double maximum_distance)
double operator()(const Descriptor &descriptor1, const Descriptor &descriptor2)
double GetScaledL2Distance(const Descriptor &descriptor1, const Descriptor &descriptor2) const
void SetMetric(const Metric &metric=Metric::SCALED_L2)
Definition: camera.cpp:50
bool MaybeNormalizeDescriptors(std::vector< Descriptor > &descriptors) const
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
void NormalizeDescriptors(std::vector< Descriptor > &descriptors) const
::Eigen::Matrix< double, Eigen::Dynamic, 1 > Descriptor
Definition: types.h:83