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);