43 #include <pcl/pcl_config.h>
45 #include <pcl/common/point_tests.h>
53 template <
typename Po
intIn,
typename Po
intOut>
55 : borders_policy_ (BORDERS_POLICY_IGNORE)
56 , distance_threshold_ (std::numeric_limits<float>::infinity ())
60 template <
typename Po
intIn,
typename Po
intOut>
void
63 if (borders_policy_ != BORDERS_POLICY_IGNORE &&
64 borders_policy_ != BORDERS_POLICY_MIRROR &&
65 borders_policy_ != BORDERS_POLICY_DUPLICATE)
67 "[pcl::filters::Convolution::initCompute] unknown borders policy.");
69 if(kernel_.size () % 2 == 0)
71 "[pcl::filters::Convolution::initCompute] convolving element width must be odd.");
73 if (distance_threshold_ != std::numeric_limits<float>::infinity ())
74 distance_threshold_ *=
static_cast<float> (kernel_.size () % 2) * distance_threshold_;
76 half_width_ =
static_cast<int> (kernel_.size ()) / 2;
77 kernel_width_ =
static_cast<int> (kernel_.size () - 1);
79 if (&(*input_) != &output)
81 if (output.
height != input_->height || output.
width != input_->width)
83 output.
resize (input_->width * input_->height);
84 output.
width = input_->width;
85 output.
height = input_->height;
91 template <
typename Po
intIn,
typename Po
intOut>
inline void
97 switch (borders_policy_)
99 case BORDERS_POLICY_MIRROR : convolve_rows_mirror (output);
break;
100 case BORDERS_POLICY_DUPLICATE : convolve_rows_duplicate (output);
break;
101 case BORDERS_POLICY_IGNORE : convolve_rows (output);
107 "[pcl::filters::Convolution::convolveRows] init failed " << e.what ());
111 template <
typename Po
intIn,
typename Po
intOut>
inline void
116 initCompute (output);
117 switch (borders_policy_)
119 case BORDERS_POLICY_MIRROR : convolve_cols_mirror (output);
break;
120 case BORDERS_POLICY_DUPLICATE : convolve_cols_duplicate (output);
break;
121 case BORDERS_POLICY_IGNORE : convolve_cols (output);
127 "[pcl::filters::Convolution::convolveCols] init failed " << e.what ());
131 template <
typename Po
intIn,
typename Po
intOut>
inline void
133 const Eigen::ArrayXf& v_kernel,
139 setKernel (h_kernel);
142 setKernel (v_kernel);
143 convolveCols (output);
148 "[pcl::filters::Convolution::convolve] init failed " << e.what ());
152 template <
typename Po
intIn,
typename Po
intOut>
inline void
160 convolveCols (output);
165 "[pcl::filters::Convolution::convolve] init failed " << e.what ());
169 template <
typename Po
intIn,
typename Po
intOut>
inline PointOut
174 for (
int k = kernel_width_, l = i - half_width_; k > -1; --k, ++l)
175 result+= (*input_) (l,j) * kernel_[k];
179 template <
typename Po
intIn,
typename Po
intOut>
inline PointOut
184 for (
int k = kernel_width_, l = j - half_width_; k > -1; --k, ++l)
185 result+= (*input_) (i,l) * kernel_[k];
189 template <
typename Po
intIn,
typename Po
intOut>
inline PointOut
190 Convolution<PointIn, PointOut>::convolveOneRowNonDense (
int i,
int j)
195 for (
int k = kernel_width_, l = i - half_width_; k > -1; --k, ++l)
201 result+= (*input_) (l,j) * kernel_[k];
202 weight += kernel_[k];
206 result.x = result.y = result.z = std::numeric_limits<float>::quiet_NaN ();
215 template <
typename Po
intIn,
typename Po
intOut>
inline PointOut
216 Convolution<PointIn, PointOut>::convolveOneColNonDense (
int i,
int j)
221 for (
int k = kernel_width_, l = j - half_width_; k > -1; --k, ++l)
227 result+= (*input_) (i,l) * kernel_[k];
228 weight += kernel_[k];
232 result.x = result.y = result.z = std::numeric_limits<float>::quiet_NaN ();
242 PCL_EXPORTS Convolution<pcl::PointXYZRGB, pcl::PointXYZRGB>::convolveOneRowDense (
int i,
int j);
245 PCL_EXPORTS Convolution<pcl::PointXYZRGB, pcl::PointXYZRGB>::convolveOneColDense (
int i,
int j);
248 PCL_EXPORTS Convolution<pcl::PointXYZRGB, pcl::PointXYZRGB>::convolveOneRowNonDense (
int i,
int j);
251 PCL_EXPORTS Convolution<pcl::PointXYZRGB, pcl::PointXYZRGB>::convolveOneColNonDense (
int i,
int j);
254 PCL_EXPORTS Convolution<pcl::RGB, pcl::RGB>::convolveOneRowDense (
int i,
int j);
257 PCL_EXPORTS Convolution<pcl::RGB, pcl::RGB>::convolveOneColDense (
int i,
int j);
260 Convolution<pcl::RGB, pcl::RGB>::convolveOneRowNonDense (
int i,
int j)
262 return (convolveOneRowDense (i,j));
266 Convolution<pcl::RGB, pcl::RGB>::convolveOneColNonDense (
int i,
int j)
268 return (convolveOneColDense (i,j));
271 template<>
inline void
274 p.r = 0; p.g = 0; p.b = 0;
277 template <
typename Po
intIn,
typename Po
intOut>
void
282 int width = input_->width;
283 int height = input_->height;
284 int last = input_->width - half_width_;
285 if (input_->is_dense)
287 #pragma omp parallel for \
289 shared(height, last, output, width) \
290 num_threads(threads_)
291 for(
int j = 0; j < height; ++j)
293 for (
int i = 0; i < half_width_; ++i)
294 makeInfinite (output (i,j));
296 for (
int i = half_width_; i < last; ++i)
297 output (i,j) = convolveOneRowDense (i,j);
299 for (
int i = last; i < width; ++i)
300 makeInfinite (output (i,j));
305 #pragma omp parallel for \
307 shared(height, last, output, width) \
308 num_threads(threads_)
309 for(
int j = 0; j < height; ++j)
311 for (
int i = 0; i < half_width_; ++i)
312 makeInfinite (output (i,j));
314 for (
int i = half_width_; i < last; ++i)
315 output (i,j) = convolveOneRowNonDense (i,j);
317 for (
int i = last; i < width; ++i)
318 makeInfinite (output (i,j));
323 template <
typename Po
intIn,
typename Po
intOut>
void
328 int width = input_->width;
329 int height = input_->height;
330 int last = input_->width - half_width_;
332 if (input_->is_dense)
334 #pragma omp parallel for \
336 shared(height, last, output, w, width) \
337 num_threads(threads_)
338 for(
int j = 0; j < height; ++j)
340 for (
int i = half_width_; i < last; ++i)
341 output (i,j) = convolveOneRowDense (i,j);
343 for (
int i = last; i < width; ++i)
344 output (i,j) = output (w, j);
346 for (
int i = 0; i < half_width_; ++i)
347 output (i,j) = output (half_width_, j);
352 #pragma omp parallel for \
354 shared(height, last, output, w, width) \
355 num_threads(threads_)
356 for(
int j = 0; j < height; ++j)
358 for (
int i = half_width_; i < last; ++i)
359 output (i,j) = convolveOneRowNonDense (i,j);
361 for (
int i = last; i < width; ++i)
362 output (i,j) = output (w, j);
364 for (
int i = 0; i < half_width_; ++i)
365 output (i,j) = output (half_width_, j);
370 template <
typename Po
intIn,
typename Po
intOut>
void
375 int width = input_->width;
376 int height = input_->height;
377 int last = input_->width - half_width_;
379 if (input_->is_dense)
381 #pragma omp parallel for \
383 shared(height, last, output, w, width) \
384 num_threads(threads_)
385 for(
int j = 0; j < height; ++j)
387 for (
int i = half_width_; i < last; ++i)
388 output (i,j) = convolveOneRowDense (i,j);
390 for (
int i = last, l = 0; i < width; ++i, ++l)
391 output (i,j) = output (w-l, j);
393 for (
int i = 0; i < half_width_; ++i)
394 output (i,j) = output (half_width_+1-i, j);
399 #pragma omp parallel for \
401 shared(height, last, output, w, width) \
402 num_threads(threads_)
403 for(
int j = 0; j < height; ++j)
405 for (
int i = half_width_; i < last; ++i)
406 output (i,j) = convolveOneRowNonDense (i,j);
408 for (
int i = last, l = 0; i < width; ++i, ++l)
409 output (i,j) = output (w-l, j);
411 for (
int i = 0; i < half_width_; ++i)
412 output (i,j) = output (half_width_+1-i, j);
417 template <
typename Po
intIn,
typename Po
intOut>
void
422 int width = input_->width;
423 int height = input_->height;
424 int last = input_->height - half_width_;
425 if (input_->is_dense)
427 #pragma omp parallel for \
429 shared(height, last, output, width) \
430 num_threads(threads_)
431 for(
int i = 0; i < width; ++i)
433 for (
int j = 0; j < half_width_; ++j)
434 makeInfinite (output (i,j));
436 for (
int j = half_width_; j < last; ++j)
437 output (i,j) = convolveOneColDense (i,j);
439 for (
int j = last; j < height; ++j)
440 makeInfinite (output (i,j));
445 #pragma omp parallel for \
447 shared(height, last, output, width) \
448 num_threads(threads_)
449 for(
int i = 0; i < width; ++i)
451 for (
int j = 0; j < half_width_; ++j)
452 makeInfinite (output (i,j));
454 for (
int j = half_width_; j < last; ++j)
455 output (i,j) = convolveOneColNonDense (i,j);
457 for (
int j = last; j < height; ++j)
458 makeInfinite (output (i,j));
463 template <
typename Po
intIn,
typename Po
intOut>
void
468 int width = input_->width;
469 int height = input_->height;
470 int last = input_->height - half_width_;
472 if (input_->is_dense)
474 #pragma omp parallel for \
476 shared(h, height, last, output, width) \
477 num_threads(threads_)
478 for(
int i = 0; i < width; ++i)
480 for (
int j = half_width_; j < last; ++j)
481 output (i,j) = convolveOneColDense (i,j);
483 for (
int j = last; j < height; ++j)
484 output (i,j) = output (i,h);
486 for (
int j = 0; j < half_width_; ++j)
487 output (i,j) = output (i, half_width_);
492 #pragma omp parallel for \
494 shared(h, height, last, output, width) \
495 num_threads(threads_)
496 for(
int i = 0; i < width; ++i)
498 for (
int j = half_width_; j < last; ++j)
499 output (i,j) = convolveOneColNonDense (i,j);
501 for (
int j = last; j < height; ++j)
502 output (i,j) = output (i,h);
504 for (
int j = 0; j < half_width_; ++j)
505 output (i,j) = output (i,half_width_);
510 template <
typename Po
intIn,
typename Po
intOut>
void
515 int width = input_->width;
516 int height = input_->height;
517 int last = input_->height - half_width_;
519 if (input_->is_dense)
521 #pragma omp parallel for \
523 shared(h, height, last, output, width) \
524 num_threads(threads_)
525 for(
int i = 0; i < width; ++i)
527 for (
int j = half_width_; j < last; ++j)
528 output (i,j) = convolveOneColDense (i,j);
530 for (
int j = last, l = 0; j < height; ++j, ++l)
531 output (i,j) = output (i,h-l);
533 for (
int j = 0; j < half_width_; ++j)
534 output (i,j) = output (i, half_width_+1-j);
539 #pragma omp parallel for \
541 shared(h, height, last, output, width) \
542 num_threads(threads_)
543 for(
int i = 0; i < width; ++i)
545 for (
int j = half_width_; j < last; ++j)
546 output (i,j) = convolveOneColNonDense (i,j);
548 for (
int j = last, l = 0; j < height; ++j, ++l)
549 output (i,j) = output (i,h-l);
551 for (
int j = 0; j < half_width_; ++j)
552 output (i,j) = output (i,half_width_+1-j);
557 #define PCL_INSTANTIATE_Convolution(Tin, Tout) \
558 template class PCL_EXPORTS Convolution<Tin, Tout>;
An exception thrown when init can not be performed should be used in all the PCLBase class inheritant...
PointCloud represents the base class in PCL for storing collections of 3D points.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
void resize(std::size_t count)
Resizes the container to contain count elements.
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).
Convolution is a mathematical operation on two functions f and g, producing a third function that is ...
typename PointCloudIn::Ptr PointCloudInPtr
void convolveCols(PointCloudOut &output)
Convolve a float image columns by a given kernel.
Convolution()
Constructor.
void convolve_rows_mirror(PointCloudOut &output)
convolve rows and mirror borders
void makeInfinite(PointOut &p)
void convolve_cols_duplicate(PointCloudOut &output)
convolve cols and duplicate borders
void convolve_rows_duplicate(PointCloudOut &output)
convolve rows and duplicate borders
void convolveRows(PointCloudOut &output)
Convolve a float image rows by a given kernel.
void convolve_cols(PointCloudOut &output)
convolve cols and ignore borders
void convolve_cols_mirror(PointCloudOut &output)
convolve cols and mirror borders
void convolve_rows(PointCloudOut &output)
convolve rows and ignore borders
void convolve(const Eigen::ArrayXf &h_kernel, const Eigen::ArrayXf &v_kernel, PointCloudOut &output)
Convolve point cloud with an horizontal kernel along rows then vertical kernel along columns : convol...
void initCompute(PointCloudOut &output)
init compute is an internal method called before computation
Define standard C methods to do distance calculations.
float squaredEuclideanDistance(const PointType1 &p1, const PointType2 &p2)
Calculate the squared euclidean distance between the two given points.
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 point structure representing Euclidean xyz coordinates, and the RGB color.
A structure representing RGB color information.