Point Cloud Library (PCL)  1.9.1-dev
convolution.hpp
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id$
37  *
38  */
39 
40 #ifndef PCL_FILTERS_CONVOLUTION_IMPL_HPP
41 #define PCL_FILTERS_CONVOLUTION_IMPL_HPP
42 
43 #include <pcl/pcl_config.h>
44 #include <pcl/common/distances.h>
45 
46 template <typename PointIn, typename PointOut>
48  : borders_policy_ (BORDERS_POLICY_IGNORE)
49  , distance_threshold_ (std::numeric_limits<float>::infinity ())
50  , input_ ()
51  , half_width_ ()
52  , kernel_width_ ()
53  , threads_ (1)
54 {}
55 
56 template <typename PointIn, typename PointOut> void
58 {
59  if (borders_policy_ != BORDERS_POLICY_IGNORE &&
60  borders_policy_ != BORDERS_POLICY_MIRROR &&
61  borders_policy_ != BORDERS_POLICY_DUPLICATE)
62  PCL_THROW_EXCEPTION (InitFailedException,
63  "[pcl::filters::Convolution::initCompute] unknown borders policy.");
64 
65  if(kernel_.size () % 2 == 0)
66  PCL_THROW_EXCEPTION (InitFailedException,
67  "[pcl::filters::Convolution::initCompute] convolving element width must be odd.");
68 
69  if (distance_threshold_ != std::numeric_limits<float>::infinity ())
70  distance_threshold_ *= static_cast<float> (kernel_.size () % 2) * distance_threshold_;
71 
72  half_width_ = static_cast<int> (kernel_.size ()) / 2;
73  kernel_width_ = static_cast<int> (kernel_.size () - 1);
74 
75  if (&(*input_) != &output)
76  {
77  if (output.height != input_->height || output.width != input_->width)
78  {
79  output.resize (input_->width * input_->height);
80  output.width = input_->width;
81  output.height = input_->height;
82  }
83  }
84  output.is_dense = input_->is_dense;
85 }
86 
87 template <typename PointIn, typename PointOut> inline void
89 {
90  try
91  {
92  initCompute (output);
93  switch (borders_policy_)
94  {
97  case BORDERS_POLICY_IGNORE : convolve_rows (output);
98  }
99  }
100  catch (InitFailedException& e)
101  {
102  PCL_THROW_EXCEPTION (InitFailedException,
103  "[pcl::filters::Convolution::convolveRows] init failed " << e.what ());
104  }
105 }
106 
107 template <typename PointIn, typename PointOut> inline void
109 {
110  try
111  {
112  initCompute (output);
113  switch (borders_policy_)
114  {
117  case BORDERS_POLICY_IGNORE : convolve_cols (output);
118  }
119  }
120  catch (InitFailedException& e)
121  {
122  PCL_THROW_EXCEPTION (InitFailedException,
123  "[pcl::filters::Convolution::convolveCols] init failed " << e.what ());
124  }
125 }
126 
127 template <typename PointIn, typename PointOut> inline void
129  const Eigen::ArrayXf& v_kernel,
130  PointCloud<PointOut>& output)
131 {
132  try
133  {
135  setKernel (h_kernel);
136  convolveRows (*tmp);
137  setInputCloud (tmp);
138  setKernel (v_kernel);
139  convolveCols (output);
140  }
141  catch (InitFailedException& e)
142  {
143  PCL_THROW_EXCEPTION (InitFailedException,
144  "[pcl::filters::Convolution::convolve] init failed " << e.what ());
145  }
146 }
147 
148 template <typename PointIn, typename PointOut> inline void
150 {
151  try
152  {
154  convolveRows (*tmp);
155  setInputCloud (tmp);
156  convolveCols (output);
157  }
158  catch (InitFailedException& e)
159  {
160  PCL_THROW_EXCEPTION (InitFailedException,
161  "[pcl::filters::Convolution::convolve] init failed " << e.what ());
162  }
163 }
164 
165 template <typename PointIn, typename PointOut> inline PointOut
167 {
168  using namespace pcl::common;
169  PointOut result;
170  for (int k = kernel_width_, l = i - half_width_; k > -1; --k, ++l)
171  result+= (*input_) (l,j) * kernel_[k];
172  return (result);
173 }
174 
175 template <typename PointIn, typename PointOut> inline PointOut
177 {
178  using namespace pcl::common;
179  PointOut result;
180  for (int k = kernel_width_, l = j - half_width_; k > -1; --k, ++l)
181  result+= (*input_) (i,l) * kernel_[k];
182  return (result);
183 }
184 
185 template <typename PointIn, typename PointOut> inline PointOut
187 {
188  using namespace pcl::common;
189  PointOut result;
190  float weight = 0;
191  for (int k = kernel_width_, l = i - half_width_; k > -1; --k, ++l)
192  {
193  if (!isFinite ((*input_) (l,j)))
194  continue;
195  if (pcl::squaredEuclideanDistance ((*input_) (i,j), (*input_) (l,j)) < distance_threshold_)
196  {
197  result+= (*input_) (l,j) * kernel_[k];
198  weight += kernel_[k];
199  }
200  }
201  if (weight == 0)
202  result.x = result.y = result.z = std::numeric_limits<float>::quiet_NaN ();
203  else
204  {
205  weight = 1.f/weight;
206  result*= weight;
207  }
208  return (result);
209 }
210 
211 template <typename PointIn, typename PointOut> inline PointOut
213 {
214  using namespace pcl::common;
215  PointOut result;
216  float weight = 0;
217  for (int k = kernel_width_, l = j - half_width_; k > -1; --k, ++l)
218  {
219  if (!isFinite ((*input_) (i,l)))
220  continue;
221  if (pcl::squaredEuclideanDistance ((*input_) (i,j), (*input_) (i,l)) < distance_threshold_)
222  {
223  result+= (*input_) (i,l) * kernel_[k];
224  weight += kernel_[k];
225  }
226  }
227  if (weight == 0)
228  result.x = result.y = result.z = std::numeric_limits<float>::quiet_NaN ();
229  else
230  {
231  weight = 1.f/weight;
232  result*= weight;
233  }
234  return (result);
235 }
236 
237 namespace pcl
238 {
239  namespace filters
240  {
241  template<> pcl::PointXYZRGB
243  {
244  pcl::PointXYZRGB result;
245  float r = 0, g = 0, b = 0;
246  for (int k = kernel_width_, l = i - half_width_; k > -1; --k, ++l)
247  {
248  result.x += (*input_) (l,j).x * kernel_[k];
249  result.y += (*input_) (l,j).y * kernel_[k];
250  result.z += (*input_) (l,j).z * kernel_[k];
251  r += kernel_[k] * static_cast<float> ((*input_) (l,j).r);
252  g += kernel_[k] * static_cast<float> ((*input_) (l,j).g);
253  b += kernel_[k] * static_cast<float> ((*input_) (l,j).b);
254  }
255  result.r = static_cast<pcl::uint8_t> (r);
256  result.g = static_cast<pcl::uint8_t> (g);
257  result.b = static_cast<pcl::uint8_t> (b);
258  return (result);
259  }
260 
261  template<> pcl::PointXYZRGB
263  {
264  pcl::PointXYZRGB result;
265  float r = 0, g = 0, b = 0;
266  for (int k = kernel_width_, l = j - half_width_; k > -1; --k, ++l)
267  {
268  result.x += (*input_) (i,l).x * kernel_[k];
269  result.y += (*input_) (i,l).y * kernel_[k];
270  result.z += (*input_) (i,l).z * kernel_[k];
271  r += kernel_[k] * static_cast<float> ((*input_) (i,l).r);
272  g += kernel_[k] * static_cast<float> ((*input_) (i,l).g);
273  b += kernel_[k] * static_cast<float> ((*input_) (i,l).b);
274  }
275  result.r = static_cast<pcl::uint8_t> (r);
276  result.g = static_cast<pcl::uint8_t> (g);
277  result.b = static_cast<pcl::uint8_t> (b);
278  return (result);
279  }
280 
281  template<> pcl::PointXYZRGB
283  {
284  pcl::PointXYZRGB result;
285  float weight = 0;
286  float r = 0, g = 0, b = 0;
287  for (int k = kernel_width_, l = i - half_width_; k > -1; --k, ++l)
288  {
289  if (!isFinite ((*input_) (l,j)))
290  continue;
291  if (pcl::squaredEuclideanDistance ((*input_) (i,j), (*input_) (l,j)) < distance_threshold_)
292  {
293  result.x += (*input_) (l,j).x * kernel_[k]; result.y += (*input_) (l,j).y * kernel_[k]; result.z += (*input_) (l,j).z * kernel_[k];
294  r+= kernel_[k] * static_cast<float> ((*input_) (l,j).r);
295  g+= kernel_[k] * static_cast<float> ((*input_) (l,j).g);
296  b+= kernel_[k] * static_cast<float> ((*input_) (l,j).b);
297  weight += kernel_[k];
298  }
299  }
300 
301  if (weight == 0)
302  result.x = result.y = result.z = std::numeric_limits<float>::quiet_NaN ();
303  else
304  {
305  weight = 1.f/weight;
306  r*= weight; g*= weight; b*= weight;
307  result.x*= weight; result.y*= weight; result.z*= weight;
308  result.r = static_cast<pcl::uint8_t> (r);
309  result.g = static_cast<pcl::uint8_t> (g);
310  result.b = static_cast<pcl::uint8_t> (b);
311  }
312  return (result);
313  }
314 
315  template<> pcl::PointXYZRGB
317  {
318  pcl::PointXYZRGB result;
319  float weight = 0;
320  float r = 0, g = 0, b = 0;
321  for (int k = kernel_width_, l = j - half_width_; k > -1; --k, ++l)
322  {
323  if (!isFinite ((*input_) (i,l)))
324  continue;
325  if (pcl::squaredEuclideanDistance ((*input_) (i,j), (*input_) (i,l)) < distance_threshold_)
326  {
327  result.x += (*input_) (i,l).x * kernel_[k]; result.y += (*input_) (i,l).y * kernel_[k]; result.z += (*input_) (i,l).z * kernel_[k];
328  r+= kernel_[k] * static_cast<float> ((*input_) (i,l).r);
329  g+= kernel_[k] * static_cast<float> ((*input_) (i,l).g);
330  b+= kernel_[k] * static_cast<float> ((*input_) (i,l).b);
331  weight+= kernel_[k];
332  }
333  }
334  if (weight == 0)
335  result.x = result.y = result.z = std::numeric_limits<float>::quiet_NaN ();
336  else
337  {
338  weight = 1.f/weight;
339  r*= weight; g*= weight; b*= weight;
340  result.x*= weight; result.y*= weight; result.z*= weight;
341  result.r = static_cast<pcl::uint8_t> (r);
342  result.g = static_cast<pcl::uint8_t> (g);
343  result.b = static_cast<pcl::uint8_t> (b);
344  }
345  return (result);
346  }
347 
348  ///////////////////////////////////////////////////////////////////////////////////////////////
349  template<> pcl::RGB
351  {
352  pcl::RGB result;
353  float r = 0, g = 0, b = 0;
354  for (int k = kernel_width_, l = i - half_width_; k > -1; --k, ++l)
355  {
356  r += kernel_[k] * static_cast<float> ((*input_) (l,j).r);
357  g += kernel_[k] * static_cast<float> ((*input_) (l,j).g);
358  b += kernel_[k] * static_cast<float> ((*input_) (l,j).b);
359  }
360  result.r = static_cast<pcl::uint8_t> (r);
361  result.g = static_cast<pcl::uint8_t> (g);
362  result.b = static_cast<pcl::uint8_t> (b);
363  return (result);
364  }
365 
366  template<> pcl::RGB
368  {
369  pcl::RGB result;
370  float r = 0, g = 0, b = 0;
371  for (int k = kernel_width_, l = j - half_width_; k > -1; --k, ++l)
372  {
373  r += kernel_[k] * static_cast<float> ((*input_) (i,l).r);
374  g += kernel_[k] * static_cast<float> ((*input_) (i,l).g);
375  b += kernel_[k] * static_cast<float> ((*input_) (i,l).b);
376  }
377  result.r = static_cast<pcl::uint8_t> (r);
378  result.g = static_cast<pcl::uint8_t> (g);
379  result.b = static_cast<pcl::uint8_t> (b);
380  return (result);
381  }
382 
383  template<> pcl::RGB
385  {
386  return (convolveOneRowDense (i,j));
387  }
388 
389  template<> pcl::RGB
391  {
392  return (convolveOneColDense (i,j));
393  }
394 
395  template<> void
397  {
398  p.r = 0; p.g = 0; p.b = 0;
399  }
400  }
401 }
402 
403 template <typename PointIn, typename PointOut> void
405 {
406  using namespace pcl::common;
407 
408  int width = input_->width;
409  int height = input_->height;
410  int last = input_->width - half_width_;
411  if (input_->is_dense)
412  {
413 #ifdef _OPENMP
414 #pragma omp parallel for shared (output) num_threads (threads_)
415 #endif
416  for(int j = 0; j < height; ++j)
417  {
418  for (int i = 0; i < half_width_; ++i)
419  makeInfinite (output (i,j));
420 
421  for (int i = half_width_; i < last; ++i)
422  output (i,j) = convolveOneRowDense (i,j);
423 
424  for (int i = last; i < width; ++i)
425  makeInfinite (output (i,j));
426  }
427  }
428  else
429  {
430 #ifdef _OPENMP
431 #pragma omp parallel for shared (output) num_threads (threads_)
432 #endif
433  for(int j = 0; j < height; ++j)
434  {
435  for (int i = 0; i < half_width_; ++i)
436  makeInfinite (output (i,j));
437 
438  for (int i = half_width_; i < last; ++i)
439  output (i,j) = convolveOneRowNonDense (i,j);
440 
441  for (int i = last; i < width; ++i)
442  makeInfinite (output (i,j));
443  }
444  }
445 }
446 
447 template <typename PointIn, typename PointOut> void
449 {
450  using namespace pcl::common;
451 
452  int width = input_->width;
453  int height = input_->height;
454  int last = input_->width - half_width_;
455  int w = last - 1;
456  if (input_->is_dense)
457  {
458 #ifdef _OPENMP
459 #pragma omp parallel for shared (output) num_threads (threads_)
460 #endif
461  for(int j = 0; j < height; ++j)
462  {
463  for (int i = half_width_; i < last; ++i)
464  output (i,j) = convolveOneRowDense (i,j);
465 
466  for (int i = last; i < width; ++i)
467  output (i,j) = output (w, j);
468 
469  for (int i = 0; i < half_width_; ++i)
470  output (i,j) = output (half_width_, j);
471  }
472  }
473  else
474  {
475 #ifdef _OPENMP
476 #pragma omp parallel for shared (output) num_threads (threads_)
477 #endif
478  for(int j = 0; j < height; ++j)
479  {
480  for (int i = half_width_; i < last; ++i)
481  output (i,j) = convolveOneRowNonDense (i,j);
482 
483  for (int i = last; i < width; ++i)
484  output (i,j) = output (w, j);
485 
486  for (int i = 0; i < half_width_; ++i)
487  output (i,j) = output (half_width_, j);
488  }
489  }
490 }
491 
492 template <typename PointIn, typename PointOut> void
494 {
495  using namespace pcl::common;
496 
497  int width = input_->width;
498  int height = input_->height;
499  int last = input_->width - half_width_;
500  int w = last - 1;
501  if (input_->is_dense)
502  {
503 #ifdef _OPENMP
504 #pragma omp parallel for shared (output) num_threads (threads_)
505 #endif
506  for(int j = 0; j < height; ++j)
507  {
508  for (int i = half_width_; i < last; ++i)
509  output (i,j) = convolveOneRowDense (i,j);
510 
511  for (int i = last, l = 0; i < width; ++i, ++l)
512  output (i,j) = output (w-l, j);
513 
514  for (int i = 0; i < half_width_; ++i)
515  output (i,j) = output (half_width_+1-i, j);
516  }
517  }
518  else
519  {
520 #ifdef _OPENMP
521 #pragma omp parallel for shared (output) num_threads (threads_)
522 #endif
523  for(int j = 0; j < height; ++j)
524  {
525  for (int i = half_width_; i < last; ++i)
526  output (i,j) = convolveOneRowNonDense (i,j);
527 
528  for (int i = last, l = 0; i < width; ++i, ++l)
529  output (i,j) = output (w-l, j);
530 
531  for (int i = 0; i < half_width_; ++i)
532  output (i,j) = output (half_width_+1-i, j);
533  }
534  }
535 }
536 
537 template <typename PointIn, typename PointOut> void
539 {
540  using namespace pcl::common;
541 
542  int width = input_->width;
543  int height = input_->height;
544  int last = input_->height - half_width_;
545  if (input_->is_dense)
546  {
547 #ifdef _OPENMP
548 #pragma omp parallel for shared (output) num_threads (threads_)
549 #endif
550  for(int i = 0; i < width; ++i)
551  {
552  for (int j = 0; j < half_width_; ++j)
553  makeInfinite (output (i,j));
554 
555  for (int j = half_width_; j < last; ++j)
556  output (i,j) = convolveOneColDense (i,j);
557 
558  for (int j = last; j < height; ++j)
559  makeInfinite (output (i,j));
560  }
561  }
562  else
563  {
564 #ifdef _OPENMP
565 #pragma omp parallel for shared (output) num_threads (threads_)
566 #endif
567  for(int i = 0; i < width; ++i)
568  {
569  for (int j = 0; j < half_width_; ++j)
570  makeInfinite (output (i,j));
571 
572  for (int j = half_width_; j < last; ++j)
573  output (i,j) = convolveOneColNonDense (i,j);
574 
575  for (int j = last; j < height; ++j)
576  makeInfinite (output (i,j));
577  }
578  }
579 }
580 
581 template <typename PointIn, typename PointOut> void
583 {
584  using namespace pcl::common;
585 
586  int width = input_->width;
587  int height = input_->height;
588  int last = input_->height - half_width_;
589  int h = last -1;
590  if (input_->is_dense)
591  {
592 #ifdef _OPENMP
593 #pragma omp parallel for shared (output) num_threads (threads_)
594 #endif
595  for(int i = 0; i < width; ++i)
596  {
597  for (int j = half_width_; j < last; ++j)
598  output (i,j) = convolveOneColDense (i,j);
599 
600  for (int j = last; j < height; ++j)
601  output (i,j) = output (i,h);
602 
603  for (int j = 0; j < half_width_; ++j)
604  output (i,j) = output (i, half_width_);
605  }
606  }
607  else
608  {
609 #ifdef _OPENMP
610 #pragma omp parallel for shared (output) num_threads (threads_)
611 #endif
612  for(int i = 0; i < width; ++i)
613  {
614  for (int j = half_width_; j < last; ++j)
615  output (i,j) = convolveOneColNonDense (i,j);
616 
617  for (int j = last; j < height; ++j)
618  output (i,j) = output (i,h);
619 
620  for (int j = 0; j < half_width_; ++j)
621  output (i,j) = output (i,half_width_);
622  }
623  }
624 }
625 
626 template <typename PointIn, typename PointOut> void
628 {
629  using namespace pcl::common;
630 
631  int width = input_->width;
632  int height = input_->height;
633  int last = input_->height - half_width_;
634  int h = last -1;
635  if (input_->is_dense)
636  {
637 #ifdef _OPENMP
638 #pragma omp parallel for shared (output) num_threads (threads_)
639 #endif
640  for(int i = 0; i < width; ++i)
641  {
642  for (int j = half_width_; j < last; ++j)
643  output (i,j) = convolveOneColDense (i,j);
644 
645  for (int j = last, l = 0; j < height; ++j, ++l)
646  output (i,j) = output (i,h-l);
647 
648  for (int j = 0; j < half_width_; ++j)
649  output (i,j) = output (i, half_width_+1-j);
650  }
651  }
652  else
653  {
654 #ifdef _OPENMP
655 #pragma omp parallel for shared (output) num_threads (threads_)
656 #endif
657  for(int i = 0; i < width; ++i)
658  {
659  for (int j = half_width_; j < last; ++j)
660  output (i,j) = convolveOneColNonDense (i,j);
661 
662  for (int j = last, l = 0; j < height; ++j, ++l)
663  output (i,j) = output (i,h-l);
664 
665  for (int j = 0; j < half_width_; ++j)
666  output (i,j) = output (i,half_width_+1-j);
667  }
668  }
669 }
670 
671 #endif //PCL_FILTERS_CONVOLUTION_IMPL_HPP
typename PointCloudIn::Ptr PointCloudInPtr
Definition: convolution.h:80
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...
Definition: point_tests.h:53
void convolve_cols_mirror(PointCloudOut &output)
convolve cols and mirror borders
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:45
void convolve_cols_duplicate(PointCloudOut &output)
convolve cols and duplicate 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...
float squaredEuclideanDistance(const PointType1 &p1, const PointType2 &p2)
Calculate the squared euclidean distance between the two given points.
Definition: distances.h:174
uint32_t height
The point cloud height (if organized as an image-structure).
Definition: point_cloud.h:416
void setKernel(const Eigen::ArrayXf &kernel)
Set convolving kernel.
Definition: convolution.h:108
A structure representing RGB color information.
uint32_t width
The point cloud width (if organized as an image-structure).
Definition: point_cloud.h:414
void convolve_rows_duplicate(PointCloudOut &output)
convolve rows and duplicate borders
Convolution is a mathematical operation on two functions f and g, producing a third function that is ...
Definition: convolution.h:76
void setInputCloud(const PointCloudInConstPtr &cloud)
Provide a pointer to the input dataset.
Definition: convolution.h:103
void convolve_rows(PointCloudOut &output)
convolve rows and ignore borders
void convolve_rows_mirror(PointCloudOut &output)
convolve rows and mirror borders
An exception thrown when init can not be performed should be used in all the PCLBase class inheritant...
Definition: exceptions.h:194
PointCloud represents the base class in PCL for storing collections of 3D points. ...
Convolution()
Constructor.
Definition: convolution.hpp:47
void convolveRows(PointCloudOut &output)
Convolve a float image rows by a given kernel.
Definition: convolution.hpp:88
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields)...
Definition: point_cloud.h:419
void convolveCols(PointCloudOut &output)
Convolve a float image columns by a given kernel.
void resize(size_t n)
Resize the cloud.
Definition: point_cloud.h:456
void initCompute(PointCloudOut &output)
init compute is an internal method called before computation
Definition: convolution.hpp:57
A point structure representing Euclidean xyz coordinates, and the RGB color.
void makeInfinite(PointOut &p)
Definition: convolution.h:228
void convolve_cols(PointCloudOut &output)
convolve cols and ignore borders