38 #ifndef PCL_FILTERS_IMPL_SAMPLING_SURFACE_NORMAL_H_
39 #define PCL_FILTERS_IMPL_SAMPLING_SURFACE_NORMAL_H_
43 #include <pcl/common/eigen.h>
44 #include <pcl/common/point_tests.h>
45 #include <pcl/filters/sampling_surface_normal.h>
48 template<
typename Po
intT>
void
53 PCL_ERROR(
"[SamplingSurfaceNormal::applyFilter] Parameter 'ratio' must be larger than zero!\n");
59 PCL_ERROR(
"[SamplingSurfaceNormal::applyFilter] Parameter 'sample' must be at least 5!\n");
64 std::size_t npts = input_->size ();
65 for (std::size_t i = 0; i < npts; i++)
66 indices.push_back (i);
68 Vector max_vec (3, 1);
69 Vector min_vec (3, 1);
70 findXYZMaxMin (*input_, max_vec, min_vec);
72 partition (data, 0, npts, min_vec, max_vec, indices, output);
78 template<
typename Po
intT>
void
82 Eigen::Array4f min_array =
83 Eigen::Array4f::Constant(std::numeric_limits<float>::max());
84 Eigen::Array4f max_array =
85 Eigen::Array4f::Constant(std::numeric_limits<float>::lowest());
87 for (
const auto& point : cloud) {
88 min_array = min_array.min(point.getArray4fMap());
89 max_array = max_array.max(point.getArray4fMap());
92 max_vec = max_array.head<3>();
93 min_vec = min_array.head<3>();
97 template<
typename Po
intT>
void
99 const PointCloud& cloud,
const int first,
const int last,
100 const Vector min_values,
const Vector max_values,
103 const int count (last - first);
104 if (count <=
static_cast<int> (sample_))
106 samplePartition (cloud, first, last, indices, output);
110 (max_values - min_values).maxCoeff (&cutDim);
112 const int rightCount (count / 2);
113 const int leftCount (count - rightCount);
114 assert (last - rightCount == first + leftCount);
117 std::nth_element (indices.begin () + first, indices.begin () + first + leftCount,
118 indices.begin () + last, CompareDim (cutDim, cloud));
120 const int cutIndex (indices[first+leftCount]);
121 const float cutVal = findCutVal (cloud, cutDim, cutIndex);
124 Vector leftMaxValues (max_values);
125 leftMaxValues[cutDim] = cutVal;
127 Vector rightMinValues (min_values);
128 rightMinValues[cutDim] = cutVal;
131 partition (cloud, first, first + leftCount, min_values, leftMaxValues, indices, output);
132 partition (cloud, first + leftCount, last, rightMinValues, max_values, indices, output);
136 template<
typename Po
intT>
void
138 const PointCloud& data,
const int first,
const int last,
143 for (
int i = first; i < last; i++)
146 pt.x = data[indices[i]].x;
147 pt.y = data[indices[i]].y;
148 pt.z = data[indices[i]].z;
154 Eigen::Vector4f normal;
158 computeNormal (cloud, normal, curvature);
160 for (
const auto& point: cloud)
163 const float r =
static_cast<float>(std::rand ()) /
static_cast<float>(RAND_MAX);
168 pt.normal[0] = normal (0);
169 pt.normal[1] = normal (1);
170 pt.normal[2] = normal (2);
171 pt.curvature = curvature;
179 template<
typename Po
intT>
void
182 EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
183 Eigen::Vector4f xyz_centroid;
190 nx = ny = nz = curvature = std::numeric_limits<float>::quiet_NaN ();
202 normal (3) = -1 * normal.dot (xyz_centroid);
206 template <
typename Po
intT>
inline unsigned int
208 Eigen::Matrix3f &covariance_matrix,
209 Eigen::Vector4f ¢roid)
212 Eigen::Matrix<float, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<float, 1, 9, Eigen::RowMajor>::Zero ();
213 std::size_t point_count = 0;
214 for (
const auto& point: cloud)
216 if (!isXYZFinite (point))
222 accu [0] += point.x * point.x;
223 accu [1] += point.x * point.y;
224 accu [2] += point.x * point.z;
225 accu [3] += point.y * point.y;
226 accu [4] += point.y * point.z;
227 accu [5] += point.z * point.z;
233 accu /=
static_cast<float> (point_count);
234 centroid[0] = accu[6]; centroid[1] = accu[7]; centroid[2] = accu[8];
236 covariance_matrix.coeffRef (0) = accu [0] - accu [6] * accu [6];
237 covariance_matrix.coeffRef (1) = accu [1] - accu [6] * accu [7];
238 covariance_matrix.coeffRef (2) = accu [2] - accu [6] * accu [8];
239 covariance_matrix.coeffRef (4) = accu [3] - accu [7] * accu [7];
240 covariance_matrix.coeffRef (5) = accu [4] - accu [7] * accu [8];
241 covariance_matrix.coeffRef (8) = accu [5] - accu [8] * accu [8];
242 covariance_matrix.coeffRef (3) = covariance_matrix.coeff (1);
243 covariance_matrix.coeffRef (6) = covariance_matrix.coeff (2);
244 covariance_matrix.coeffRef (7) = covariance_matrix.coeff (5);
246 return (
static_cast<unsigned int> (point_count));
250 template <
typename Po
intT>
void
252 float &nx,
float &ny,
float &nz,
float &curvature)
255 EIGEN_ALIGN16 Eigen::Vector3f::Scalar eigen_value;
256 EIGEN_ALIGN16 Eigen::Vector3f eigen_vector;
257 pcl::eigen33 (covariance_matrix, eigen_value, eigen_vector);
259 nx = eigen_vector [0];
260 ny = eigen_vector [1];
261 nz = eigen_vector [2];
264 float eig_sum = covariance_matrix.coeff (0) + covariance_matrix.coeff (4) + covariance_matrix.coeff (8);
266 curvature = std::abs (eigen_value / eig_sum);
272 template <
typename Po
intT>
float
274 const PointCloud& cloud,
const int cut_dim,
const int cut_index)
277 return (cloud[cut_index].x);
279 return (cloud[cut_index].y);
281 return (cloud[cut_index].z);
287 #define PCL_INSTANTIATE_SamplingSurfaceNormal(T) template class PCL_EXPORTS pcl::SamplingSurfaceNormal<T>;
PointCloud represents the base class in PCL for storing collections of 3D points.
void push_back(const PointT &pt)
Insert a new point in the cloud, at the end of the container.
std::uint32_t width
The point cloud width (if organized as an image-structure).
std::uint32_t height
The point cloud height (if organized as an image-structure).
void clear()
Removes all points in a cloud and sets the width and height to 0.
SamplingSurfaceNormal divides the input space into grids until each grid contains a maximum of N poin...
void applyFilter(PointCloud &output) override
Sample of point indices into a separate PointCloud.
unsigned int computeMeanAndCovarianceMatrix(const pcl::PointCloud< PointT > &cloud, Eigen::Matrix< Scalar, 3, 3 > &covariance_matrix, Eigen::Matrix< Scalar, 4, 1 > ¢roid)
Compute the normalized 3x3 covariance matrix and the centroid of a given set of points in a single lo...
void eigen33(const Matrix &mat, typename Matrix::Scalar &eigenvalue, Vector &eigenvector)
determines the eigenvector and eigenvalue of the smallest eigenvalue of the symmetric positive semi d...
void solvePlaneParameters(const Eigen::Matrix3f &covariance_matrix, const Eigen::Vector4f &point, Eigen::Vector4f &plane_parameters, float &curvature)
Solve the eigenvalues and eigenvectors of a given 3x3 covariance matrix, and estimate the least-squar...
IndicesAllocator<> Indices
Type used for indices in PCL.
A point structure representing Euclidean xyz coordinates, and the RGB color.