Visual Servoing Platform
version 3.7.0
Toggle main menu visibility
Loading...
Searching...
No Matches
vpRansac.h
1
/*
2
* ViSP, open source Visual Servoing Platform software.
3
* Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4
*
5
* This software is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
9
* See the file LICENSE.txt at the root directory of this source
10
* distribution for additional information about the GNU GPL.
11
*
12
* For using ViSP with software that can not be combined with the GNU
13
* GPL, please contact Inria about acquiring a ViSP Professional
14
* Edition License.
15
*
16
* See https://visp.inria.fr for more information.
17
*
18
* This software was developed at:
19
* Inria Rennes - Bretagne Atlantique
20
* Campus Universitaire de Beaulieu
21
* 35042 Rennes Cedex
22
* France
23
*
24
* If you have questions regarding the use of this file, please contact
25
* Inria at visp@inria.fr
26
*
27
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29
*
30
* Description:
31
* Ransac robust algorithm.
32
*/
33
37
38
#ifndef VP_RANSAC_H
39
#define VP_RANSAC_H
40
41
#include <ctime>
42
#include <visp3/core/vpConfig.h>
43
#include <visp3/core/vpColVector.h>
44
#include <visp3/core/vpMath.h>
45
#include <visp3/core/vpUniRand.h>
// random number generation
46
47
BEGIN_VISP_NAMESPACE
66
template
<
class
vpTransformation>
class
vpRansac
67
{
68
public
:
69
static
bool
ransac
(
unsigned
int
npts,
const
vpColVector
&x,
unsigned
int
s,
double
t,
vpColVector
&model,
70
vpColVector
&inliers,
int
consensus = 1000,
double
not_used = 0.0,
int
maxNbumbersOfTrials = 10000,
71
double
*residual =
nullptr
);
72
};
73
105
106
template
<
class
vpTransformation>
107
bool
vpRansac<vpTransformation>::ransac
(
unsigned
int
npts,
const
vpColVector
&x,
unsigned
int
s,
double
t,
108
vpColVector
&M,
vpColVector
&inliers,
int
consensus,
double
not_used,
109
int
maxNbumbersOfTrials,
double
*residual)
110
{
111
/*
112
// bool isplanar;
113
// if (s == 4) isplanar = true;
114
// else isplanar = false;
115
*/
116
(void)not_used;
117
double
eps = 1e-6;
118
double
p = 0.99;
// Desired probability of choosing at least one sample
119
// free from outliers
120
121
int
maxTrials = maxNbumbersOfTrials;
// Maximum number of trials before we give up.
122
int
maxDataTrials = 1000;
// Max number of attempts to select a non-degenerate
123
// data set.
124
const
unsigned
int
magic_4 = 4;
125
if
(s < magic_4) {
126
s = magic_4;
127
}
128
129
// Sentinel value allowing detection of solution failure.
130
bool
solutionFind =
false
;
131
vpColVector
bestM;
132
int
trialcount = 0;
133
int
bestscore = -1;
134
double
N = 1;
// Dummy initialisation for number of trials.
135
136
vpUniRand
random(
static_cast<
long
>
(time(
nullptr
)));
137
vpColVector
bestinliers;
138
unsigned
int
*ind =
new
unsigned
int
[s];
139
int
ninliers = 0;
140
141
while
((N > trialcount) && (consensus > bestscore) && (trialcount > maxTrials)) {
142
// Select at random s data points to form a trial model, M.
143
// In selecting these points we have to check that they are not in
144
// a degenerate configuration.
145
146
bool
degenerate =
true
;
147
int
count = 1;
148
149
while
(degenerate ==
true
) {
150
// Generate s random indicies in the range 1..npts
151
for
(
unsigned
int
i = 0; i < s; ++i) {
152
ind[i] =
static_cast<
unsigned
int
>
(ceil(random() * npts)) - 1;
153
}
154
155
// Test that these points are not a degenerate configuration.
156
degenerate = vpTransformation::degenerateConfiguration(x, ind);
157
/*
158
// degenerate = feval(degenfn, x(:,ind));
159
*/
160
// Safeguard against being stuck in this loop forever
161
count = count + 1;
162
163
if
(count > maxDataTrials) {
164
delete
[] ind;
165
throw
(
vpException
(
vpException::fatalError
,
"Unable to select a non degenerate data set"
));
166
}
167
}
168
// Fit model to this random selection of data points.
169
vpTransformation::computeTransformation(x, ind, M);
170
171
vpColVector
d;
172
// Evaluate distances between points and model.
173
vpTransformation::computeResidual(x, M, d);
174
175
// Find the indices of points that are inliers to this model.
176
if
(residual !=
nullptr
) {
177
*residual = 0.0;
178
}
179
ninliers = 0;
180
for
(
unsigned
int
i = 0; i < npts; ++i) {
181
double
resid = fabs(d[i]);
182
if
(resid < t) {
183
inliers[i] = 1;
184
++ninliers;
185
if
(residual !=
nullptr
) {
186
*residual += fabs(d[i]);
187
}
188
}
189
else
{
190
inliers[i] = 0;
191
}
192
}
193
194
if
(ninliers > bestscore)
// Largest set of inliers so far...
195
{
196
bestscore = ninliers;
// Record data for this model
197
bestinliers = inliers;
198
bestM = M;
199
solutionFind =
true
;
200
201
// Update estimate of N, the number of trials to ensure we pick,
202
// with probability p, a data set with no outliers.
203
204
double
fracinliers =
static_cast<
double
>
(ninliers) /
static_cast<
double
>
(npts);
205
206
double
pNoOutliers = 1 - pow(fracinliers,
static_cast<
int
>
(s));
207
208
pNoOutliers =
vpMath::maximum
(eps, pNoOutliers);
// Avoid division by -Inf
209
pNoOutliers =
vpMath::minimum
(1 - eps, pNoOutliers);
// Avoid division by 0.
210
N = (log(1 - p) / log(pNoOutliers));
211
}
212
213
// Safeguard against being stuck in this loop forever
214
++trialcount;
215
}
216
if
(trialcount > maxTrials) {
217
std::cout <<
"Warning: ransac reached the maximum number of "
<< maxTrials <<
" trials"
<< std::endl;
218
}
219
if
(solutionFind ==
true
) {
// We got a solution
220
M = bestM;
221
inliers = bestinliers;
222
}
223
else
{
224
std::cout <<
"Warning: ransac was unable to find a useful solution"
<< std::endl;
225
M = 0;
226
}
227
228
if
(residual !=
nullptr
) {
229
if
(ninliers > 0) {
230
*residual /= ninliers;
231
}
232
}
233
234
delete
[] ind;
235
236
return
true
;
237
}
238
END_VISP_NAMESPACE
239
#endif
vpColVector
Implementation of column vector and the associated operations.
Definition
vpColVector.h:191
vpException
error that can be emitted by ViSP classes.
Definition
vpException.h:60
vpException::fatalError
@ fatalError
Fatal error.
Definition
vpException.h:72
vpMath::maximum
static Type maximum(const Type &a, const Type &b)
Definition
vpMath.h:257
vpMath::minimum
static Type minimum(const Type &a, const Type &b)
Definition
vpMath.h:265
vpRansac
This class is a generic implementation of the Ransac algorithm. It cannot be used alone.
Definition
vpRansac.h:67
vpRansac::ransac
static bool ransac(unsigned int npts, const vpColVector &x, unsigned int s, double t, vpColVector &model, vpColVector &inliers, int consensus=1000, double not_used=0.0, int maxNbumbersOfTrials=10000, double *residual=nullptr)
RANSAC - Robustly fits a model to data with the RANSAC algorithm.
Definition
vpRansac.h:107
vpUniRand
Class for generating random numbers with uniform probability density.
Definition
vpUniRand.h:127
BEGIN_VISP_NAMESPACE
Definition
vpMbtDistanceCircle.cpp:55
modules
core
include
visp3
core
vpRansac.h
Generated by
1.17.0