40 #ifndef PCL_FILTERS_CONVOLUTION_3D_IMPL_HPP
41 #define PCL_FILTERS_CONVOLUTION_3D_IMPL_HPP
43 #include <pcl/common/point_tests.h>
44 #include <pcl/search/organized.h>
45 #include <pcl/search/kdtree.h>
46 #include <pcl/pcl_config.h>
47 #include <pcl/point_types.h>
48 #include <pcl/common/point_tests.h>
60 template <
typename Po
intT>
66 n.normal_x = n.normal_y = n.normal_z = std::numeric_limits<float>::quiet_NaN ();
70 template <
typename Po
intT>
class
76 p.
x = p.
y = std::numeric_limits<float>::quiet_NaN ();
83 template<
typename Po
intInT,
typename Po
intOutT>
bool
88 PCL_ERROR (
"Sigma is not set or equal to 0!\n", sigma_);
91 sigma_sqr_ = sigma_ * sigma_;
93 if (sigma_coefficient_)
95 if ((*sigma_coefficient_) > 6 || (*sigma_coefficient_) < 3)
97 PCL_ERROR (
"Sigma coefficient (%f) out of [3..6]!\n", (*sigma_coefficient_));
101 threshold_ = (*sigma_coefficient_) * (*sigma_coefficient_) * sigma_sqr_;
108 template<
typename Po
intInT,
typename Po
intOutT> PointOutT
110 const std::vector<float>& distances)
114 float total_weight = 0;
115 std::vector<float>::const_iterator dist_it = distances.begin ();
117 for (Indices::const_iterator idx_it = indices.begin ();
118 idx_it != indices.end ();
121 if (*dist_it <= threshold_ &&
isFinite ((*input_) [*idx_it]))
123 float weight = std::exp (-0.5f * (*dist_it) / sigma_sqr_);
124 result += weight * (*input_) [*idx_it];
125 total_weight += weight;
128 if (total_weight != 0)
129 result /= total_weight;
131 makeInfinite (result);
137 template<
typename Po
intInT,
typename Po
intOutT> PointOutT
142 float total_weight = 0;
143 float r = 0, g = 0, b = 0;
144 std::vector<float>::const_iterator dist_it = distances.begin ();
146 for (Indices::const_iterator idx_it = indices.begin ();
147 idx_it != indices.end ();
150 if (*dist_it <= threshold_ &&
isFinite ((*input_) [*idx_it]))
152 float weight = std::exp (-0.5f * (*dist_it) / sigma_sqr_);
153 result.x += weight * (*input_) [*idx_it].x;
154 result.y += weight * (*input_) [*idx_it].y;
155 result.z += weight * (*input_) [*idx_it].z;
156 r += weight *
static_cast<float> ((*input_) [*idx_it].r);
157 g += weight *
static_cast<float> ((*input_) [*idx_it].g);
158 b += weight *
static_cast<float> ((*input_) [*idx_it].b);
159 total_weight += weight;
162 if (total_weight != 0)
164 total_weight = 1.f/total_weight;
165 r*= total_weight; g*= total_weight; b*= total_weight;
166 result.x*= total_weight; result.y*= total_weight; result.z*= total_weight;
167 result.r =
static_cast<std::uint8_t
> (r);
168 result.g =
static_cast<std::uint8_t
> (g);
169 result.b =
static_cast<std::uint8_t
> (b);
172 makeInfinite (result);
178 template <
typename Po
intInT,
typename Po
intOutT,
typename KernelT>
187 template <
typename Po
intInT,
typename Po
intOutT,
typename KernelT>
bool
192 PCL_ERROR (
"[pcl::filters::Convlution3D::initCompute] init failed!\n");
198 if (input_->isOrganized ())
207 tree_->setInputCloud (surface_);
209 if (search_radius_ <= 0.0)
211 PCL_ERROR (
"[pcl::filters::Convlution3D::initCompute] search radius (%f) must be > 0\n",
218 PCL_ERROR (
"[pcl::filters::Convlution3D::initCompute] init failed : ");
219 PCL_ERROR (
"kernel_ must implement ConvolvingKernel interface\n!");
222 kernel_.setInputCloud (surface_);
224 if (!kernel_.initCompute ())
226 PCL_ERROR (
"[pcl::filters::Convlution3D::initCompute] kernel initialization failed!\n");
233 template <
typename Po
intInT,
typename Po
intOutT,
typename KernelT>
void
238 PCL_ERROR (
"[pcl::filters::Convlution3D::convolve] init failed!\n");
241 output.
resize (surface_->size ());
242 output.
width = surface_->width;
243 output.
height = surface_->height;
244 output.
is_dense = surface_->is_dense;
246 std::vector<float> nn_distances;
248 #pragma omp parallel for \
251 firstprivate(nn_indices, nn_distances) \
252 num_threads(threads_) \
253 schedule(dynamic, 64)
254 for (std::int64_t point_idx = 0; point_idx < static_cast<std::int64_t> (surface_->size ()); ++point_idx)
256 const PointInT& point_in = surface_->points [point_idx];
257 PointOutT& point_out = output [point_idx];
259 tree_->radiusSearch (point_in, search_radius_, nn_indices, nn_distances))
261 point_out = kernel_ (nn_indices, nn_distances);
265 kernel_.makeInfinite (point_out);
A point structure representing normal coordinates and the surface curvature estimate.
search::KdTree is a wrapper class which inherits the pcl::KdTree class for performing search function...
bool isFinite(const PointT &pt)
Tests if the 3D components of a point are all finite param[in] pt point to be tested return true if f...
A 2D point structure representing Euclidean xy coordinates.
std::uint32_t width
The point cloud width (if organized as an image-structure).
Convolution3D()
Constructor.
static void makeInfinite(PointOutT &p)
Utility function that annihilates a point making it fail the pcl::isFinite test.
void resize(std::size_t count)
Resizes the container to contain count elements.
std::uint32_t height
The point cloud height (if organized as an image-structure).
bool initCompute()
initialize computation
IndicesAllocator<> Indices
Type used for indices in PCL.
bool initCompute()
Must call this method before doing any computation.
PointCloud represents the base class in PCL for storing collections of 3D points. ...
Class ConvolvingKernel base class for all convolving kernels.
void convolve(PointCloudOut &output)
Convolve point cloud.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields)...
OrganizedNeighbor is a class for optimized nearest neighbor search in organized projectable point clo...
A point structure representing Euclidean xyz coordinates, and the RGB color.
PointOutT operator()(const Indices &indices, const std::vector< float > &distances)
Convolve point at the center of this local information.
virtual PointOutT operator()(const Indices &indices, const std::vector< float > &distances)
Convolve point at the center of this local information.