g2o
Loading...
Searching...
No Matches
robust_kernel_impl.cpp
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
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// * Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#include "robust_kernel_impl.h"
28
29#include <cmath>
30
32
33namespace g2o {
34
36 double delta)
37 : RobustKernel(delta), _kernel(kernel) {}
38
41
45
46void RobustKernelScaleDelta::robustify(double error, Vector3& rho) const {
47 if (_kernel.get()) {
48 double dsqr = _delta * _delta;
49 double dsqrReci = 1. / dsqr;
50 _kernel->robustify(dsqrReci * error, rho);
51 rho[0] *= dsqr;
52 rho[2] *= dsqrReci;
53 } else { // no robustification
54 rho[0] = error;
55 rho[1] = 1.;
56 rho[2] = 0.;
57 }
58}
59
60void RobustKernelHuber::robustify(double e, Vector3& rho) const {
61 double dsqr = _delta * _delta;
62 if (e <= dsqr) { // inlier
63 rho[0] = e;
64 rho[1] = 1.;
65 rho[2] = 0.;
66 } else { // outlier
67 double sqrte = sqrt(e); // absolute value of the error
68 rho[0] =
69 2 * sqrte * _delta - dsqr; // rho(e) = 2 * delta * e^(1/2) - delta^2
70 rho[1] = _delta / sqrte; // rho'(e) = delta / sqrt(e)
71 rho[2] = -0.5 * rho[1] /
72 e; // rho''(e) = -1 / (2*e^(3/2)) = -1/2 * (delta/e) / e
73 }
74}
75
76void RobustKernelPseudoHuber::robustify(double e2, Vector3& rho) const {
77 double dsqr = _delta * _delta;
78 double dsqrReci = 1. / dsqr;
79 double aux1 = dsqrReci * e2 + 1.0;
80 double aux2 = sqrt(aux1);
81 rho[0] = 2 * dsqr * (aux2 - 1);
82 rho[1] = 1. / aux2;
83 rho[2] = -0.5 * dsqrReci * rho[1] / aux1;
84}
85
86void RobustKernelCauchy::robustify(double e2, Vector3& rho) const {
87 double dsqr = _delta * _delta;
88 double dsqrReci = 1. / dsqr;
89 double aux = dsqrReci * e2 + 1.0;
90 rho[0] = dsqr * log(aux);
91 rho[1] = 1. / aux;
92 rho[2] = -dsqrReci * std::pow(rho[1], 2);
93}
94
95void RobustKernelGemanMcClure::robustify(double e2, Vector3& rho) const {
96 const double aux = 1. / (_delta + e2);
97 rho[0] = _delta * e2 * aux;
98 rho[1] = _delta * _delta * aux * aux;
99 rho[2] = -2. * rho[1] * aux;
100}
101
102void RobustKernelWelsch::robustify(double e2, Vector3& rho) const {
103 const double dsqr = _delta * _delta;
104 const double aux = e2 / dsqr;
105 const double aux2 = exp(-aux);
106 rho[0] = dsqr * (1. - aux2);
107 rho[1] = aux2;
108 rho[2] = -aux2 / dsqr;
109}
110
111void RobustKernelFair::robustify(double e2, Vector3& rho) const {
112 const double sqrte = sqrt(e2);
113 const double dsqr = _delta * _delta;
114 const double aux = sqrte / _delta;
115 rho[0] = 2. * dsqr * (aux - log1p(aux));
116 rho[1] = 1. / (1. + aux);
117
118 const double drec = 1. / _delta;
119 const double e_3_2 = 1. / (sqrte * e2);
120 const double aux2 = drec * sqrte + 1;
121
122 rho[2] = 2 * dsqr *
123 (1 / (4 * dsqr * aux2 * aux2 * e2) + (drec * e_3_2) / (4 * aux2) -
124 (drec * e_3_2) / 4);
125}
126
127void RobustKernelTukey::robustify(double e2, Vector3& rho) const {
128 const double delta2 = _delta * _delta;
129 if (e2 <= delta2) {
130 const double aux = e2 / delta2;
131 rho[0] = delta2 * (1. - std::pow((1. - aux), 3)) / 3.;
132 rho[1] = std::pow((1. - aux), 2);
133 rho[2] = -2. * (1. - aux) / delta2;
134 } else {
135 rho[0] = delta2 / 3.;
136 rho[1] = 0;
137 rho[2] = 0;
138 }
139}
140
141void RobustKernelSaturated::robustify(double e2, Vector3& rho) const {
142 double dsqr = _delta * _delta;
143 if (e2 <= dsqr) { // inlier
144 rho[0] = e2;
145 rho[1] = 1.;
146 rho[2] = 0.;
147 } else { // outlier
148 rho[0] = dsqr;
149 rho[1] = 0.;
150 rho[2] = 0.;
151 }
152}
153
154// delta is used as $phi$
155void RobustKernelDCS::robustify(double e2, Vector3& rho) const {
156 const double& phi = _delta;
157 double scale = (2.0 * phi) / (phi + e2);
158 if (scale >= 1.0) { // limit scale to max of 1 and return this
159 rho[0] = e2;
160 rho[1] = 1.;
161 rho[2] = 0;
162 } else {
163 double phi_sqr = phi * phi;
164 rho[0] = scale * e2 * scale;
165 rho[1] = (4 * phi_sqr * (phi - e2)) / std::pow(phi + e2, 3);
166 rho[2] = -(8 * phi_sqr * (2 * phi - e2)) / std::pow(phi + e2, 4);
167 }
168}
169
170// register the kernel to their factory
180} // end namespace g2o
Cauchy cost function.
virtual void robustify(double e2, Vector3 &rho) const
Dynamic covariance scaling - DCS.
virtual void robustify(double e2, Vector3 &rho) const
Fair cost function.
virtual void robustify(double e2, Vector3 &rho) const
Geman-McClure cost function.
virtual void robustify(double e2, Vector3 &rho) const
Huber Cost Function.
virtual void robustify(double e2, Vector3 &rho) const
Pseudo Huber Cost Function.
virtual void robustify(double e2, Vector3 &rho) const
Saturated cost function.
virtual void robustify(double e2, Vector3 &rho) const
void setKernel(const RobustKernelPtr &ptr)
use another kernel for the underlying operation
void robustify(double error, Vector3 &rho) const
RobustKernelScaleDelta(const RobustKernelPtr &kernel, double delta=1.)
Tukey Cost Function.
virtual void robustify(double e2, Vector3 &rho) const
Welsch cost function.
virtual void robustify(double e2, Vector3 &rho) const
base for all robust cost functions
virtual void robustify(double squaredError, Vector3 &rho) const =0
VectorN< 3 > Vector3
Definition eigen_types.h:51
std::shared_ptr< RobustKernel > RobustKernelPtr
#define G2O_REGISTER_ROBUST_KERNEL(name, classname)