Point Cloud Library (PCL)
1.15.1
Toggle main menu visibility
Loading...
Searching...
No Matches
pcl
sample_consensus
impl
lmeds.hpp
1
/*
2
* Software License Agreement (BSD License)
3
*
4
* Point Cloud Library (PCL) - www.pointclouds.org
5
* Copyright (c) 2009, Willow Garage, Inc.
6
* Copyright (c) 2012-, Open Perception, Inc.
7
*
8
* All rights reserved.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
*
14
* * Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* * Redistributions in binary form must reproduce the above
17
* copyright notice, this list of conditions and the following
18
* disclaimer in the documentation and/or other materials provided
19
* with the distribution.
20
* * Neither the name of the copyright holder(s) nor the names of its
21
* contributors may be used to endorse or promote products derived
22
* from this software without specific prior written permission.
23
*
24
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
* POSSIBILITY OF SUCH DAMAGE.
36
*
37
* $Id$
38
*
39
*/
40
41
#ifndef PCL_SAMPLE_CONSENSUS_IMPL_LMEDS_H_
42
#define PCL_SAMPLE_CONSENSUS_IMPL_LMEDS_H_
43
44
#include <pcl/sample_consensus/lmeds.h>
45
#include <
pcl/common/common.h
>
// for computeMedian
46
47
//////////////////////////////////////////////////////////////////////////
48
template
<
typename
Po
int
T>
bool
49
pcl::LeastMedianSquares<PointT>::computeModel
(
int
debug_verbosity_level)
50
{
51
// Warn and exit if no threshold was set
52
if
(
threshold_
== std::numeric_limits<double>::max())
53
{
54
PCL_ERROR (
"[pcl::LeastMedianSquares::computeModel] No threshold set!\n"
);
55
return
(
false
);
56
}
57
58
iterations_
= 0;
59
double
d_best_penalty = std::numeric_limits<double>::max();
60
61
Indices
selection;
62
Eigen::VectorXf model_coefficients (
sac_model_
->getModelSize ());
63
std::vector<double>
distances
;
64
65
unsigned
skipped_count = 0;
66
// suppress infinite loops by just allowing 10 x maximum allowed iterations for invalid model parameters!
67
const
unsigned
max_skip =
max_iterations_
* 10;
68
69
// Iterate
70
while
((
iterations_
<
max_iterations_
) && (skipped_count < max_skip))
71
{
72
// Get X samples which satisfy the model criteria
73
sac_model_
->getSamples (
iterations_
, selection);
74
75
if
(selection.empty ())
76
{
77
PCL_ERROR (
"[pcl::LeastMedianSquares::computeModel] No samples could be selected!\n"
);
78
break
;
79
}
80
81
// Search for inliers in the point cloud for the current plane model M
82
if
(!
sac_model_
->computeModelCoefficients (selection, model_coefficients))
83
{
84
//iterations_++;
85
++skipped_count;
86
PCL_DEBUG (
"[pcl::LeastMedianSquares::computeModel] The function computeModelCoefficients failed, so continue with next iteration.\n"
);
87
continue
;
88
}
89
90
double
d_cur_penalty;
91
// d_cur_penalty = sum (min (dist, threshold))
92
93
// Iterate through the 3d points and calculate the distances from them to the model
94
sac_model_
->getDistancesToModel (model_coefficients,
distances
);
95
96
// No distances? The model must not respect the user given constraints
97
if
(
distances
.empty ())
98
{
99
//iterations_++;
100
++skipped_count;
101
continue
;
102
}
103
// Move all NaNs in distances to the end
104
const
auto
new_end = (
sac_model_
->getInputCloud()->is_dense ?
distances
.end() : std::partition (
distances
.begin(),
distances
.end(), [](
double
d){return !std::isnan (d);}));
105
const
auto
nr_valid_dists = std::distance (
distances
.begin (), new_end);
106
107
// d_cur_penalty = median (distances)
108
PCL_DEBUG (
"[pcl::LeastMedianSquares::computeModel] There are %lu valid distances remaining after removing NaN values.\n"
, nr_valid_dists);
109
if
(nr_valid_dists == 0)
110
{
111
//iterations_++;
112
++skipped_count;
113
continue
;
114
}
115
d_cur_penalty =
pcl::computeMedian
(
distances
.begin (), new_end,
static_cast<
double
(*)(
double
)
>
(std::sqrt));
116
117
// Better match ?
118
if
(d_cur_penalty < d_best_penalty)
119
{
120
d_best_penalty = d_cur_penalty;
121
122
// Save the current model/coefficients selection as being the best so far
123
model_
= selection;
124
model_coefficients_
= model_coefficients;
125
}
126
127
++
iterations_
;
128
if
(debug_verbosity_level > 1)
129
{
130
PCL_DEBUG (
"[pcl::LeastMedianSquares::computeModel] Trial %d out of %d. Best penalty is %f.\n"
,
iterations_
,
max_iterations_
, d_best_penalty);
131
}
132
}
133
134
if
(
model_
.empty ())
135
{
136
if
(debug_verbosity_level > 0)
137
{
138
PCL_DEBUG (
"[pcl::LeastMedianSquares::computeModel] Unable to find a solution!\n"
);
139
}
140
return
(
false
);
141
}
142
143
// Classify the data points into inliers and outliers
144
// Sigma = 1.4826 * (1 + 5 / (n-d)) * sqrt (M)
145
// @note: See "Robust Regression Methods for Computer Vision: A Review"
146
//double sigma = 1.4826 * (1 + 5 / (sac_model_->getIndices ()->size () - best_model.size ())) * sqrt (d_best_penalty);
147
//double threshold = 2.5 * sigma;
148
149
// Iterate through the 3d points and calculate the distances from them to the model again
150
sac_model_
->getDistancesToModel (
model_coefficients_
,
distances
);
151
// No distances? The model must not respect the user given constraints
152
if
(
distances
.empty ())
153
{
154
PCL_ERROR (
"[pcl::LeastMedianSquares::computeModel] The model found failed to verify against the given constraints!\n"
);
155
return
(
false
);
156
}
157
158
Indices
&indices = *
sac_model_
->getIndices ();
159
160
if
(
distances
.size () != indices.size ())
161
{
162
PCL_ERROR (
"[pcl::LeastMedianSquares::computeModel] Estimated distances (%lu) differs than the normal of indices (%lu).\n"
,
distances
.size (), indices.size ());
163
return
(
false
);
164
}
165
166
inliers_
.resize (
distances
.size ());
167
// Get the inliers for the best model found
168
std::size_t n_inliers_count = 0;
169
for
(std::size_t i = 0; i <
distances
.size (); ++i)
170
{
171
if
(
distances
[i] <=
threshold_
)
172
{
173
inliers_
[n_inliers_count++] = indices[i];
174
}
175
}
176
177
// Resize the inliers vector
178
inliers_
.resize (n_inliers_count);
179
180
if
(debug_verbosity_level > 0)
181
{
182
PCL_DEBUG (
"[pcl::LeastMedianSquares::computeModel] Model: %lu size, %lu inliers.\n"
,
model_
.size (), n_inliers_count);
183
}
184
185
return
(
true
);
186
}
187
188
#define PCL_INSTANTIATE_LeastMedianSquares(T) template class PCL_EXPORTS pcl::LeastMedianSquares<T>;
189
190
#endif
// PCL_SAMPLE_CONSENSUS_IMPL_LMEDS_H_
pcl::LeastMedianSquares::computeModel
bool computeModel(int debug_verbosity_level=0) override
Compute the actual model and find the inliers.
Definition
lmeds.hpp:49
pcl::SampleConsensus< PointT >::inliers_
Indices inliers_
Definition
sac.h:346
pcl::SampleConsensus< PointT >::iterations_
int iterations_
Definition
sac.h:355
pcl::SampleConsensus< PointT >::model_
Indices model_
Definition
sac.h:343
pcl::SampleConsensus< PointT >::model_coefficients_
Eigen::VectorXf model_coefficients_
Definition
sac.h:349
pcl::SampleConsensus< PointT >::threshold_
double threshold_
Definition
sac.h:358
pcl::SampleConsensus< PointT >::sac_model_
SampleConsensusModelPtr sac_model_
Definition
sac.h:340
pcl::SampleConsensus< PointT >::max_iterations_
int max_iterations_
Definition
sac.h:361
common.h
Define standard C methods and C++ classes that are common to all methods.
pcl::computeMedian
auto computeMedian(IteratorT begin, IteratorT end, Functor f) noexcept -> std::result_of_t< Functor(decltype(*begin))>
Compute the median of a list of values (fast).
Definition
common.h:285
pcl::distances
Definition
distances.h:50
pcl::Indices
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition
types.h:133