Point Cloud Library (PCL)
1.15.1
Toggle main menu visibility
Loading...
Searching...
No Matches
pcl
sample_consensus
impl
sac_model_normal_sphere.hpp
1
/*
2
* Software License Agreement (BSD License)
3
*
4
* Point Cloud Library (PCL) - www.pointclouds.org
5
* Copyright (c) 2009-2012, 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: sac_model_normal_sphere.hpp schrandt $
38
*
39
*/
40
41
#ifndef PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_NORMAL_SPHERE_H_
42
#define PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_NORMAL_SPHERE_H_
43
44
#include <pcl/sample_consensus/sac_model_normal_sphere.h>
45
#include <
pcl/common/common.h
>
// for getAngle3D
46
47
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
48
template
<
typename
Po
int
T,
typename
Po
int
NT>
void
49
pcl::SampleConsensusModelNormalSphere<PointT, PointNT>::selectWithinDistance
(
50
const
Eigen::VectorXf &model_coefficients,
const
double
threshold,
Indices
&inliers)
51
{
52
if
(!
normals_
)
53
{
54
PCL_ERROR (
"[pcl::SampleConsensusModelNormalSphere::selectWithinDistance] No input dataset containing normals was given! Use setInputNormals\n"
);
55
inliers.clear ();
56
return
;
57
}
58
59
// Check if the model is valid given the user constraints
60
if
(!
isModelValid
(model_coefficients))
61
{
62
inliers.clear ();
63
return
;
64
}
65
66
// Obtain the sphere center
67
Eigen::Vector4f center = model_coefficients;
68
center[3] = 0.0f;
69
70
inliers.clear ();
71
error_sqr_dists_
.clear ();
72
inliers.reserve (
indices_
->size ());
73
error_sqr_dists_
.reserve (
indices_
->size ());
74
75
// Iterate through the 3d points and calculate the distances from them to the sphere
76
for
(std::size_t i = 0; i <
indices_
->size (); ++i)
77
{
78
// Calculate the distance from the point to the sphere center as the difference between
79
// dist(point,sphere_origin) and sphere_radius
80
Eigen::Vector4f p ((*
input_
)[(*
indices_
)[i]].x,
81
(*
input_
)[(*
indices_
)[i]].y,
82
(*
input_
)[(*
indices_
)[i]].z,
83
0.0f);
84
85
Eigen::Vector4f n_dir = p - center;
86
const
double
weighted_euclid_dist = (1.0 -
normal_distance_weight_
) * std::abs (n_dir.norm () - model_coefficients[3]);
87
if
(weighted_euclid_dist > threshold)
// Early termination: cannot be an inlier
88
continue
;
89
90
// Calculate the angular distance between the point normal and the sphere normal
91
Eigen::Vector4f n ((*
normals_
)[(*
indices_
)[i]].normal[0],
92
(*
normals_
)[(*
indices_
)[i]].normal[1],
93
(*
normals_
)[(*
indices_
)[i]].normal[2],
94
0.0f);
95
double
d_normal = std::abs (
getAngle3D
(n, n_dir));
96
d_normal = (std::min) (d_normal,
M_PI
- d_normal);
97
98
double
distance = std::abs (
normal_distance_weight_
* d_normal + weighted_euclid_dist);
99
if
(distance < threshold)
100
{
101
// Returns the indices of the points whose distances are smaller than the threshold
102
inliers.push_back ((*
indices_
)[i]);
103
error_sqr_dists_
.push_back (
static_cast<
double
>
(distance));
104
}
105
}
106
}
107
108
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
109
template
<
typename
Po
int
T,
typename
Po
int
NT> std::size_t
110
pcl::SampleConsensusModelNormalSphere<PointT, PointNT>::countWithinDistance
(
111
const
Eigen::VectorXf &model_coefficients,
const
double
threshold)
const
112
{
113
if
(!
normals_
)
114
{
115
PCL_ERROR (
"[pcl::SampleConsensusModelNormalSphere::getDistancesToModel] No input dataset containing normals was given! Use setInputNormals\n"
);
116
return
(0);
117
}
118
119
// Check if the model is valid given the user constraints
120
if
(!
isModelValid
(model_coefficients))
121
return
(0);
122
123
124
// Obtain the sphere centroid
125
Eigen::Vector4f center = model_coefficients;
126
center[3] = 0.0f;
127
128
std::size_t nr_p = 0;
129
130
// Iterate through the 3d points and calculate the distances from them to the sphere
131
for
(std::size_t i = 0; i <
indices_
->size (); ++i)
132
{
133
// Calculate the distance from the point to the sphere centroid as the difference between
134
// dist(point,sphere_origin) and sphere_radius
135
Eigen::Vector4f p ((*
input_
)[(*
indices_
)[i]].x,
136
(*
input_
)[(*
indices_
)[i]].y,
137
(*
input_
)[(*
indices_
)[i]].z,
138
0.0f);
139
140
Eigen::Vector4f n_dir = (p-center);
141
const
double
weighted_euclid_dist = (1.0 -
normal_distance_weight_
) * std::abs (n_dir.norm () - model_coefficients[3]);
142
if
(weighted_euclid_dist > threshold)
// Early termination: cannot be an inlier
143
continue
;
144
145
// Calculate the angular distance between the point normal and the sphere normal
146
Eigen::Vector4f n ((*
normals_
)[(*
indices_
)[i]].normal[0],
147
(*
normals_
)[(*
indices_
)[i]].normal[1],
148
(*
normals_
)[(*
indices_
)[i]].normal[2],
149
0.0f);
150
double
d_normal = std::abs (
getAngle3D
(n, n_dir));
151
d_normal = (std::min) (d_normal,
M_PI
- d_normal);
152
153
if
(std::abs (
normal_distance_weight_
* d_normal + weighted_euclid_dist) < threshold)
154
nr_p++;
155
}
156
return
(nr_p);
157
}
158
159
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
160
template
<
typename
Po
int
T,
typename
Po
int
NT>
void
161
pcl::SampleConsensusModelNormalSphere<PointT, PointNT>::getDistancesToModel
(
162
const
Eigen::VectorXf &model_coefficients, std::vector<double> &
distances
)
const
163
{
164
if
(!
normals_
)
165
{
166
PCL_ERROR (
"[pcl::SampleConsensusModelNormalSphere::getDistancesToModel] No input dataset containing normals was given! Use setInputNormals\n"
);
167
return
;
168
}
169
170
// Check if the model is valid given the user constraints
171
if
(!
isModelValid
(model_coefficients))
172
{
173
distances
.clear ();
174
return
;
175
}
176
177
// Obtain the sphere centroid
178
Eigen::Vector4f center = model_coefficients;
179
center[3] = 0.0f;
180
181
distances
.resize (
indices_
->size ());
182
183
// Iterate through the 3d points and calculate the distances from them to the sphere
184
for
(std::size_t i = 0; i <
indices_
->size (); ++i)
185
{
186
// Calculate the distance from the point to the sphere as the difference between
187
// dist(point,sphere_origin) and sphere_radius
188
Eigen::Vector4f p ((*
input_
)[(*
indices_
)[i]].x,
189
(*
input_
)[(*
indices_
)[i]].y,
190
(*
input_
)[(*
indices_
)[i]].z,
191
0.0f);
192
193
Eigen::Vector4f n_dir = (p-center);
194
const
double
weighted_euclid_dist = (1.0 -
normal_distance_weight_
) * std::abs (n_dir.norm () - model_coefficients[3]);
195
196
// Calculate the angular distance between the point normal and the sphere normal
197
Eigen::Vector4f n ((*
normals_
)[(*
indices_
)[i]].normal[0],
198
(*
normals_
)[(*
indices_
)[i]].normal[1],
199
(*
normals_
)[(*
indices_
)[i]].normal[2],
200
0.0f);
201
double
d_normal = std::abs (
getAngle3D
(n, n_dir));
202
d_normal = (std::min) (d_normal,
M_PI
- d_normal);
203
204
distances
[i] = std::abs (
normal_distance_weight_
* d_normal + weighted_euclid_dist);
205
}
206
}
207
208
#define PCL_INSTANTIATE_SampleConsensusModelNormalSphere(PointT, PointNT) template class PCL_EXPORTS pcl::SampleConsensusModelNormalSphere<PointT, PointNT>;
209
210
#endif
// PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_NORMAL_SPHERE_H_
211
pcl::SampleConsensusModelFromNormals::normals_
PointCloudNConstPtr normals_
A pointer to the input dataset that contains the point normals of the XYZ dataset.
Definition
sac_model.h:671
pcl::SampleConsensusModelFromNormals::normal_distance_weight_
double normal_distance_weight_
The relative weight (between 0 and 1) to give to the angular distance (0 to pi/2) between point norma...
Definition
sac_model.h:666
pcl::SampleConsensusModel::indices_
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition
sac_model.h:557
pcl::SampleConsensusModel::input_
PointCloudConstPtr input_
A boost shared pointer to the point cloud data array.
Definition
sac_model.h:554
pcl::SampleConsensusModel::error_sqr_dists_
std::vector< double > error_sqr_dists_
A vector holding the distances to the computed model.
Definition
sac_model.h:586
pcl::SampleConsensusModelNormalSphere::selectWithinDistance
void selectWithinDistance(const Eigen::VectorXf &model_coefficients, const double threshold, Indices &inliers) override
Select all the points which respect the given model coefficients as inliers.
Definition
sac_model_normal_sphere.hpp:49
pcl::SampleConsensusModelNormalSphere::countWithinDistance
std::size_t countWithinDistance(const Eigen::VectorXf &model_coefficients, const double threshold) const override
Count all the points which respect the given model coefficients as inliers.
Definition
sac_model_normal_sphere.hpp:110
pcl::SampleConsensusModelNormalSphere::getDistancesToModel
void getDistancesToModel(const Eigen::VectorXf &model_coefficients, std::vector< double > &distances) const override
Compute all distances from the cloud data to a given sphere model.
Definition
sac_model_normal_sphere.hpp:161
pcl::SampleConsensusModelSphere::isModelValid
bool isModelValid(const Eigen::VectorXf &model_coefficients) const override
Check whether a model is valid given the user constraints.
Definition
sac_model_sphere.h:222
common.h
Define standard C methods and C++ classes that are common to all methods.
pcl::getAngle3D
double getAngle3D(const Eigen::Vector4f &v1, const Eigen::Vector4f &v2, const bool in_degree=false)
Compute the smallest angle between two 3D vectors in radians (default) or degree.
Definition
common.hpp:47
pcl::distances
Definition
distances.h:50
pcl::Indices
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition
types.h:133
M_PI
#define M_PI
Definition
pcl_macros.h:203