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 ())
63 template <
typename Po
intIn,
typename Po
intOut>
void
66 if (borders_policy_ != BORDERS_POLICY_IGNORE &&
67 borders_policy_ != BORDERS_POLICY_MIRROR &&
68 borders_policy_ != BORDERS_POLICY_DUPLICATE)
70 "[pcl::filters::Convolution::initCompute] unknown borders policy.");
72 if(kernel_.size () % 2 == 0)
74 "[pcl::filters::Convolution::initCompute] convolving element width must be odd.");
76 if (distance_threshold_ != std::numeric_limits<float>::infinity ())
77 distance_threshold_ *=
static_cast<float> (kernel_.size () % 2) * distance_threshold_;
79 half_width_ =
static_cast<int> (kernel_.size ()) / 2;
80 kernel_width_ =
static_cast<int> (kernel_.size () - 1);
82 if (&(*input_) != &output)
84 if (output.
height != input_->height || output.
width != input_->width)
86 output.
resize (input_->width * input_->height);
87 output.
width = input_->width;
88 output.
height = input_->height;
94 template <
typename Po
intIn,
typename Po
intOut>
inline void
100 switch (borders_policy_)
102 case BORDERS_POLICY_MIRROR : convolve_rows_mirror (output);
break;
103 case BORDERS_POLICY_DUPLICATE : convolve_rows_duplicate (output);
break;
104 case BORDERS_POLICY_IGNORE : convolve_rows (output);
110 "[pcl::filters::Convolution::convolveRows] init failed " << e.what ());
114 template <
typename Po
intIn,
typename Po
intOut>
inline void
119 initCompute (output);
120 switch (borders_policy_)
122 case BORDERS_POLICY_MIRROR : convolve_cols_mirror (output);
break;
123 case BORDERS_POLICY_DUPLICATE : convolve_cols_duplicate (output);
break;
124 case BORDERS_POLICY_IGNORE : convolve_cols (output);
130 "[pcl::filters::Convolution::convolveCols] init failed " << e.what ());
134 template <
typename Po
intIn,
typename Po
intOut>
inline void
136 const Eigen::ArrayXf& v_kernel,
142 setKernel (h_kernel);
145 setKernel (v_kernel);
146 convolveCols (output);
151 "[pcl::filters::Convolution::convolve] init failed " << e.what ());
155 template <
typename Po
intIn,
typename Po
intOut>
inline void
163 convolveCols (output);
168 "[pcl::filters::Convolution::convolve] init failed " << e.what ());
172 template <
typename Po
intIn,
typename Po
intOut>
inline PointOut
177 for (
int k = kernel_width_, l = i - half_width_; k > -1; --k, ++l)
178 result+= (*input_) (l,j) * kernel_[k];
182 template <
typename Po
intIn,
typename Po
intOut>
inline PointOut
187 for (
int k = kernel_width_, l = j - half_width_; k > -1; --k, ++l)
188 result+= (*input_) (i,l) * kernel_[k];
192 template <
typename Po
intIn,
typename Po
intOut>
inline PointOut
193 Convolution<PointIn, PointOut>::convolveOneRowNonDense (
int i,
int j)
198 for (
int k = kernel_width_, l = i - half_width_; k > -1; --k, ++l)
204 result+= (*input_) (l,j) * kernel_[k];
205 weight += kernel_[k];
209 result.x = result.y = result.z = std::numeric_limits<float>::quiet_NaN ();
218 template <
typename Po
intIn,
typename Po
intOut>
inline PointOut
219 Convolution<PointIn, PointOut>::convolveOneColNonDense (
int i,
int j)
224 for (
int k = kernel_width_, l = j - half_width_; k > -1; --k, ++l)
230 result+= (*input_) (i,l) * kernel_[k];
231 weight += kernel_[k];
235 result.x = result.y = result.z = std::numeric_limits<float>::quiet_NaN ();
245 PCL_EXPORTS Convolution<pcl::PointXYZRGB, pcl::PointXYZRGB>::convolveOneRowDense (
int i,
int j);
248 PCL_EXPORTS Convolution<pcl::PointXYZRGB, pcl::PointXYZRGB>::convolveOneColDense (
int i,
int j);
251 PCL_EXPORTS Convolution<pcl::PointXYZRGB, pcl::PointXYZRGB>::convolveOneRowNonDense (
int i,
int j);
254 PCL_EXPORTS Convolution<pcl::PointXYZRGB, pcl::PointXYZRGB>::convolveOneColNonDense (
int i,
int j);
257 PCL_EXPORTS Convolution<pcl::RGB, pcl::RGB>::convolveOneRowDense (
int i,
int j);
260 PCL_EXPORTS Convolution<pcl::RGB, pcl::RGB>::convolveOneColDense (
int i,
int j);
263 Convolution<pcl::RGB, pcl::RGB>::convolveOneRowNonDense (
int i,
int j)
265 return (convolveOneRowDense (i,j));
269 Convolution<pcl::RGB, pcl::RGB>::convolveOneColNonDense (
int i,
int j)
271 return (convolveOneColDense (i,j));
274 template<>
inline void
277 p.r = 0; p.g = 0; p.b = 0;
280 template <
typename Po
intIn,
typename Po
intOut>
void
285 int width = input_->width;
286 int height = input_->height;
287 int last = input_->width - half_width_;
288 if (input_->is_dense)
290 #pragma omp parallel for \
292 shared(height, last, output, width) \
293 num_threads(threads_)
294 for(
int j = 0; j < height; ++j)
296 for (
int i = 0; i < half_width_; ++i)
297 makeInfinite (output (i,j));
299 for (
int i = half_width_; i < last; ++i)
300 output (i,j) = convolveOneRowDense (i,j);
302 for (
int i = last; i < width; ++i)
303 makeInfinite (output (i,j));
308 #pragma omp parallel for \
310 shared(height, last, output, width) \
311 num_threads(threads_)
312 for(
int j = 0; j < height; ++j)
314 for (
int i = 0; i < half_width_; ++i)
315 makeInfinite (output (i,j));
317 for (
int i = half_width_; i < last; ++i)
318 output (i,j) = convolveOneRowNonDense (i,j);
320 for (
int i = last; i < width; ++i)
321 makeInfinite (output (i,j));
326 template <
typename Po
intIn,
typename Po
intOut>
void
331 int width = input_->width;
332 int height = input_->height;
333 int last = input_->width - half_width_;
335 if (input_->is_dense)
337 #pragma omp parallel for \
339 shared(height, last, output, w, width) \
340 num_threads(threads_)
341 for(
int j = 0; j < height; ++j)
343 for (
int i = half_width_; i < last; ++i)
344 output (i,j) = convolveOneRowDense (i,j);
346 for (
int i = last; i < width; ++i)
347 output (i,j) = output (w, j);
349 for (
int i = 0; i < half_width_; ++i)
350 output (i,j) = output (half_width_, j);
355 #pragma omp parallel for \
357 shared(height, last, output, w, width) \
358 num_threads(threads_)
359 for(
int j = 0; j < height; ++j)
361 for (
int i = half_width_; i < last; ++i)
362 output (i,j) = convolveOneRowNonDense (i,j);
364 for (
int i = last; i < width; ++i)
365 output (i,j) = output (w, j);
367 for (
int i = 0; i < half_width_; ++i)
368 output (i,j) = output (half_width_, j);
373 template <
typename Po
intIn,
typename Po
intOut>
void
378 int width = input_->width;
379 int height = input_->height;
380 int last = input_->width - half_width_;
382 if (input_->is_dense)
384 #pragma omp parallel for \
386 shared(height, last, output, w, width) \
387 num_threads(threads_)
388 for(
int j = 0; j < height; ++j)
390 for (
int i = half_width_; i < last; ++i)
391 output (i,j) = convolveOneRowDense (i,j);
393 for (
int i = last, l = 0; i < width; ++i, ++l)
394 output (i,j) = output (w-l, j);
396 for (
int i = 0; i < half_width_; ++i)
397 output (i,j) = output (half_width_+1-i, j);
402 #pragma omp parallel for \
404 shared(height, last, output, w, width) \
405 num_threads(threads_)
406 for(
int j = 0; j < height; ++j)
408 for (
int i = half_width_; i < last; ++i)
409 output (i,j) = convolveOneRowNonDense (i,j);
411 for (
int i = last, l = 0; i < width; ++i, ++l)
412 output (i,j) = output (w-l, j);
414 for (
int i = 0; i < half_width_; ++i)
415 output (i,j) = output (half_width_+1-i, j);
420 template <
typename Po
intIn,
typename Po
intOut>
void
425 int width = input_->width;
426 int height = input_->height;
427 int last = input_->height - half_width_;
428 if (input_->is_dense)
430 #pragma omp parallel for \
432 shared(height, last, output, width) \
433 num_threads(threads_)
434 for(
int i = 0; i < width; ++i)
436 for (
int j = 0; j < half_width_; ++j)
437 makeInfinite (output (i,j));
439 for (
int j = half_width_; j < last; ++j)
440 output (i,j) = convolveOneColDense (i,j);
442 for (
int j = last; j < height; ++j)
443 makeInfinite (output (i,j));
448 #pragma omp parallel for \
450 shared(height, last, output, width) \
451 num_threads(threads_)
452 for(
int i = 0; i < width; ++i)
454 for (
int j = 0; j < half_width_; ++j)
455 makeInfinite (output (i,j));
457 for (
int j = half_width_; j < last; ++j)
458 output (i,j) = convolveOneColNonDense (i,j);
460 for (
int j = last; j < height; ++j)
461 makeInfinite (output (i,j));
466 template <
typename Po
intIn,
typename Po
intOut>
void
471 int width = input_->width;
472 int height = input_->height;
473 int last = input_->height - half_width_;
475 if (input_->is_dense)
477 #pragma omp parallel for \
479 shared(h, height, last, output, width) \
480 num_threads(threads_)
481 for(
int i = 0; i < width; ++i)
483 for (
int j = half_width_; j < last; ++j)
484 output (i,j) = convolveOneColDense (i,j);
486 for (
int j = last; j < height; ++j)
487 output (i,j) = output (i,h);
489 for (
int j = 0; j < half_width_; ++j)
490 output (i,j) = output (i, half_width_);
495 #pragma omp parallel for \
497 shared(h, height, last, output, width) \
498 num_threads(threads_)
499 for(
int i = 0; i < width; ++i)
501 for (
int j = half_width_; j < last; ++j)
502 output (i,j) = convolveOneColNonDense (i,j);
504 for (
int j = last; j < height; ++j)
505 output (i,j) = output (i,h);
507 for (
int j = 0; j < half_width_; ++j)
508 output (i,j) = output (i,half_width_);
513 template <
typename Po
intIn,
typename Po
intOut>
void
518 int width = input_->width;
519 int height = input_->height;
520 int last = input_->height - half_width_;
522 if (input_->is_dense)
524 #pragma omp parallel for \
526 shared(h, height, last, output, width) \
527 num_threads(threads_)
528 for(
int i = 0; i < width; ++i)
530 for (
int j = half_width_; j < last; ++j)
531 output (i,j) = convolveOneColDense (i,j);
533 for (
int j = last, l = 0; j < height; ++j, ++l)
534 output (i,j) = output (i,h-l);
536 for (
int j = 0; j < half_width_; ++j)
537 output (i,j) = output (i, half_width_+1-j);
542 #pragma omp parallel for \
544 shared(h, height, last, output, width) \
545 num_threads(threads_)
546 for(
int i = 0; i < width; ++i)
548 for (
int j = half_width_; j < last; ++j)
549 output (i,j) = convolveOneColNonDense (i,j);
551 for (
int j = last, l = 0; j < height; ++j, ++l)
552 output (i,j) = output (i,h-l);
554 for (
int j = 0; j < half_width_; ++j)
555 output (i,j) = output (i,half_width_+1-j);
560 #define PCL_INSTANTIATE_Convolution(Tin, Tout) \
561 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.