Point Cloud Library (PCL)  1.11.1
esf.hpp
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2012, Willow Garage, Inc.
6  * Copyright (c) 2012-, Open Perception, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of the copyright holder(s) nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * $Id: pfh.hpp 5027 2012-03-12 03:10:45Z rusu $
38  *
39  */
40 
41 #ifndef PCL_FEATURES_IMPL_ESF_H_
42 #define PCL_FEATURES_IMPL_ESF_H_
43 
44 #include <pcl/features/esf.h>
45 #include <pcl/common/distances.h>
46 #include <pcl/common/transforms.h>
47 #include <vector>
48 
49 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
50 template <typename PointInT, typename PointOutT> void
52  PointCloudIn &pc, std::vector<float> &hist)
53 {
54  const int binsize = 64;
55  unsigned int sample_size = 20000;
56  // @TODO: Replace with c++ stdlib uniform_random_generator
57  srand (static_cast<unsigned int> (time (nullptr)));
58  const auto maxindex = pc.size ();
59 
60  std::vector<float> d2v, d1v, d3v, wt_d3;
61  std::vector<int> wt_d2;
62  d1v.reserve (sample_size);
63  d2v.reserve (sample_size * 3);
64  d3v.reserve (sample_size);
65  wt_d2.reserve (sample_size * 3);
66  wt_d3.reserve (sample_size);
67 
68  float h_in[binsize] = {0};
69  float h_out[binsize] = {0};
70  float h_mix[binsize] = {0};
71  float h_mix_ratio[binsize] = {0};
72 
73  float h_a3_in[binsize] = {0};
74  float h_a3_out[binsize] = {0};
75  float h_a3_mix[binsize] = {0};
76 
77  float h_d3_in[binsize] = {0};
78  float h_d3_out[binsize] = {0};
79  float h_d3_mix[binsize] = {0};
80 
81  float ratio=0.0;
82  float pih = static_cast<float>(M_PI) / 2.0f;
83  float a,b,c,s;
84  int th1,th2,th3;
85  int vxlcnt = 0;
86  int pcnt1,pcnt2,pcnt3;
87  for (std::size_t nn_idx = 0; nn_idx < sample_size; ++nn_idx)
88  {
89  // get a new random point
90  int index1 = rand()%maxindex;
91  int index2 = rand()%maxindex;
92  int index3 = rand()%maxindex;
93 
94  if (index1==index2 || index1 == index3 || index2 == index3)
95  {
96  nn_idx--;
97  continue;
98  }
99 
100  Eigen::Vector4f p1 = pc[index1].getVector4fMap ();
101  Eigen::Vector4f p2 = pc[index2].getVector4fMap ();
102  Eigen::Vector4f p3 = pc[index3].getVector4fMap ();
103 
104  // A3
105  Eigen::Vector4f v21 (p2 - p1);
106  Eigen::Vector4f v31 (p3 - p1);
107  Eigen::Vector4f v23 (p2 - p3);
108  a = v21.norm (); b = v31.norm (); c = v23.norm (); s = (a+b+c) * 0.5f;
109  if (s * (s-a) * (s-b) * (s-c) <= 0.001f)
110  {
111  nn_idx--;
112  continue;
113  }
114 
115  v21.normalize ();
116  v31.normalize ();
117  v23.normalize ();
118 
119  //TODO: .dot gives nan's
120  th1 = static_cast<int> (pcl_round (std::acos (std::abs (v21.dot (v31))) / pih * (binsize-1)));
121  th2 = static_cast<int> (pcl_round (std::acos (std::abs (v23.dot (v31))) / pih * (binsize-1)));
122  th3 = static_cast<int> (pcl_round (std::acos (std::abs (v23.dot (v21))) / pih * (binsize-1)));
123  if (th1 < 0 || th1 >= binsize)
124  {
125  nn_idx--;
126  continue;
127  }
128  if (th2 < 0 || th2 >= binsize)
129  {
130  nn_idx--;
131  continue;
132  }
133  if (th3 < 0 || th3 >= binsize)
134  {
135  nn_idx--;
136  continue;
137  }
138 
139  // D2
140  d2v.push_back (pcl::euclideanDistance (pc[index1], pc[index2]));
141  d2v.push_back (pcl::euclideanDistance (pc[index1], pc[index3]));
142  d2v.push_back (pcl::euclideanDistance (pc[index2], pc[index3]));
143 
144  int vxlcnt_sum = 0;
145  int p_cnt = 0;
146  // IN, OUT, MIXED, Ratio line tracing, index1->index2
147  {
148  const int xs = p1[0] < 0.0? static_cast<int>(std::floor(p1[0])+GRIDSIZE_H): static_cast<int>(std::ceil(p1[0])+GRIDSIZE_H-1);
149  const int ys = p1[1] < 0.0? static_cast<int>(std::floor(p1[1])+GRIDSIZE_H): static_cast<int>(std::ceil(p1[1])+GRIDSIZE_H-1);
150  const int zs = p1[2] < 0.0? static_cast<int>(std::floor(p1[2])+GRIDSIZE_H): static_cast<int>(std::ceil(p1[2])+GRIDSIZE_H-1);
151  const int xt = p2[0] < 0.0? static_cast<int>(std::floor(p2[0])+GRIDSIZE_H): static_cast<int>(std::ceil(p2[0])+GRIDSIZE_H-1);
152  const int yt = p2[1] < 0.0? static_cast<int>(std::floor(p2[1])+GRIDSIZE_H): static_cast<int>(std::ceil(p2[1])+GRIDSIZE_H-1);
153  const int zt = p2[2] < 0.0? static_cast<int>(std::floor(p2[2])+GRIDSIZE_H): static_cast<int>(std::ceil(p2[2])+GRIDSIZE_H-1);
154  wt_d2.push_back (this->lci (xs, ys, zs, xt, yt, zt, ratio, vxlcnt, pcnt1));
155  if (wt_d2.back () == 2)
156  h_mix_ratio[static_cast<int> (pcl_round (ratio * (binsize-1)))]++;
157  vxlcnt_sum += vxlcnt;
158  p_cnt += pcnt1;
159  }
160  // IN, OUT, MIXED, Ratio line tracing, index1->index3
161  {
162  const int xs = p1[0] < 0.0? static_cast<int>(std::floor(p1[0])+GRIDSIZE_H): static_cast<int>(std::ceil(p1[0])+GRIDSIZE_H-1);
163  const int ys = p1[1] < 0.0? static_cast<int>(std::floor(p1[1])+GRIDSIZE_H): static_cast<int>(std::ceil(p1[1])+GRIDSIZE_H-1);
164  const int zs = p1[2] < 0.0? static_cast<int>(std::floor(p1[2])+GRIDSIZE_H): static_cast<int>(std::ceil(p1[2])+GRIDSIZE_H-1);
165  const int xt = p3[0] < 0.0? static_cast<int>(std::floor(p3[0])+GRIDSIZE_H): static_cast<int>(std::ceil(p3[0])+GRIDSIZE_H-1);
166  const int yt = p3[1] < 0.0? static_cast<int>(std::floor(p3[1])+GRIDSIZE_H): static_cast<int>(std::ceil(p3[1])+GRIDSIZE_H-1);
167  const int zt = p3[2] < 0.0? static_cast<int>(std::floor(p3[2])+GRIDSIZE_H): static_cast<int>(std::ceil(p3[2])+GRIDSIZE_H-1);
168  wt_d2.push_back (this->lci (xs, ys, zs, xt, yt, zt, ratio, vxlcnt, pcnt2));
169  if (wt_d2.back () == 2)
170  h_mix_ratio[static_cast<int>(pcl_round (ratio * (binsize-1)))]++;
171  vxlcnt_sum += vxlcnt;
172  p_cnt += pcnt2;
173  }
174  // IN, OUT, MIXED, Ratio line tracing, index2->index3
175  {
176  const int xs = p2[0] < 0.0? static_cast<int>(std::floor(p2[0])+GRIDSIZE_H): static_cast<int>(std::ceil(p2[0])+GRIDSIZE_H-1);
177  const int ys = p2[1] < 0.0? static_cast<int>(std::floor(p2[1])+GRIDSIZE_H): static_cast<int>(std::ceil(p2[1])+GRIDSIZE_H-1);
178  const int zs = p2[2] < 0.0? static_cast<int>(std::floor(p2[2])+GRIDSIZE_H): static_cast<int>(std::ceil(p2[2])+GRIDSIZE_H-1);
179  const int xt = p3[0] < 0.0? static_cast<int>(std::floor(p3[0])+GRIDSIZE_H): static_cast<int>(std::ceil(p3[0])+GRIDSIZE_H-1);
180  const int yt = p3[1] < 0.0? static_cast<int>(std::floor(p3[1])+GRIDSIZE_H): static_cast<int>(std::ceil(p3[1])+GRIDSIZE_H-1);
181  const int zt = p3[2] < 0.0? static_cast<int>(std::floor(p3[2])+GRIDSIZE_H): static_cast<int>(std::ceil(p3[2])+GRIDSIZE_H-1);
182  wt_d2.push_back (this->lci (xs,ys,zs,xt,yt,zt,ratio,vxlcnt,pcnt3));
183  if (wt_d2.back () == 2)
184  h_mix_ratio[static_cast<int>(pcl_round(ratio * (binsize-1)))]++;
185  vxlcnt_sum += vxlcnt;
186  p_cnt += pcnt3;
187  }
188 
189  // D3 ( herons formula )
190  d3v.push_back (std::sqrt (std::sqrt (s * (s-a) * (s-b) * (s-c))));
191  if (vxlcnt_sum <= 21)
192  {
193  wt_d3.push_back (0);
194  h_a3_out[th1] += static_cast<float> (pcnt3) / 32.0f;
195  h_a3_out[th2] += static_cast<float> (pcnt1) / 32.0f;
196  h_a3_out[th3] += static_cast<float> (pcnt2) / 32.0f;
197  }
198  else
199  if (p_cnt - vxlcnt_sum < 4)
200  {
201  h_a3_in[th1] += static_cast<float> (pcnt3) / 32.0f;
202  h_a3_in[th2] += static_cast<float> (pcnt1) / 32.0f;
203  h_a3_in[th3] += static_cast<float> (pcnt2) / 32.0f;
204  wt_d3.push_back (1);
205  }
206  else
207  {
208  h_a3_mix[th1] += static_cast<float> (pcnt3) / 32.0f;
209  h_a3_mix[th2] += static_cast<float> (pcnt1) / 32.0f;
210  h_a3_mix[th3] += static_cast<float> (pcnt2) / 32.0f;
211  wt_d3.push_back (static_cast<float> (vxlcnt_sum) / static_cast<float> (p_cnt));
212  }
213  }
214  // Normalizing, get max
215  float maxd2 = 0;
216  float maxd3 = 0;
217 
218  for (std::size_t nn_idx = 0; nn_idx < sample_size; ++nn_idx)
219  {
220  // get max of Dx
221  if (d2v[nn_idx] > maxd2)
222  maxd2 = d2v[nn_idx];
223  if (d2v[sample_size + nn_idx] > maxd2)
224  maxd2 = d2v[sample_size + nn_idx];
225  if (d2v[sample_size*2 +nn_idx] > maxd2)
226  maxd2 = d2v[sample_size*2 +nn_idx];
227  if (d3v[nn_idx] > maxd3)
228  maxd3 = d3v[nn_idx];
229  }
230 
231  // Normalize and create histogram
232  int index;
233  for (std::size_t nn_idx = 0; nn_idx < sample_size; ++nn_idx)
234  {
235  if (wt_d3[nn_idx] >= 0.999) // IN
236  {
237  index = static_cast<int>(pcl_round (d3v[nn_idx] / maxd3 * (binsize-1)));
238  if (index >= 0 && index < binsize)
239  h_d3_in[index]++;
240  }
241  else
242  {
243  if (wt_d3[nn_idx] <= 0.001) // OUT
244  {
245  index = static_cast<int>(pcl_round (d3v[nn_idx] / maxd3 * (binsize-1)));
246  if (index >= 0 && index < binsize)
247  h_d3_out[index]++ ;
248  }
249  else
250  {
251  index = static_cast<int>(pcl_round (d3v[nn_idx] / maxd3 * (binsize-1)));
252  if (index >= 0 && index < binsize)
253  h_d3_mix[index]++;
254  }
255  }
256  }
257  //normalize and create histogram
258  for (std::size_t nn_idx = 0; nn_idx < d2v.size(); ++nn_idx )
259  {
260  if (wt_d2[nn_idx] == 0)
261  h_in[static_cast<int>(pcl_round (d2v[nn_idx] / maxd2 * (binsize-1)))]++ ;
262  if (wt_d2[nn_idx] == 1)
263  h_out[static_cast<int>(pcl_round (d2v[nn_idx] / maxd2 * (binsize-1)))]++;
264  if (wt_d2[nn_idx] == 2)
265  h_mix[static_cast<int>(pcl_round (d2v[nn_idx] / maxd2 * (binsize-1)))]++ ;
266  }
267 
268  //float weights[10] = {1, 1, 1, 1, 1, 1, 1, 1 , 1 , 1};
269  float weights[10] = {0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f};
270 
271  hist.reserve (binsize * 10);
272  for (const float &i : h_a3_in)
273  hist.push_back (i * weights[0]);
274  for (const float &i : h_a3_out)
275  hist.push_back (i * weights[1]);
276  for (const float &i : h_a3_mix)
277  hist.push_back (i * weights[2]);
278 
279  for (const float &i : h_d3_in)
280  hist.push_back (i * weights[3]);
281  for (const float &i : h_d3_out)
282  hist.push_back (i * weights[4]);
283  for (const float &i : h_d3_mix)
284  hist.push_back (i * weights[5]);
285 
286  for (const float &i : h_in)
287  hist.push_back (i*0.5f * weights[6]);
288  for (const float &i : h_out)
289  hist.push_back (i * weights[7]);
290  for (const float &i : h_mix)
291  hist.push_back (i * weights[8]);
292  for (const float &i : h_mix_ratio)
293  hist.push_back (i*0.5f * weights[9]);
294 
295  float sm = 0;
296  for (const float &i : hist)
297  sm += i;
298 
299  for (float &i : hist)
300  i /= sm;
301 }
302 
303 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
304 template <typename PointInT, typename PointOutT> int
306  const int x1, const int y1, const int z1,
307  const int x2, const int y2, const int z2,
308  float &ratio, int &incnt, int &pointcount)
309 {
310  int voxelcount = 0;
311  int voxel_in = 0;
312  int act_voxel[3];
313  act_voxel[0] = x1;
314  act_voxel[1] = y1;
315  act_voxel[2] = z1;
316  int x_inc, y_inc, z_inc;
317  int dx = x2 - x1;
318  int dy = y2 - y1;
319  int dz = z2 - z1;
320  if (dx < 0)
321  x_inc = -1;
322  else
323  x_inc = 1;
324  int l = std::abs (dx);
325  if (dy < 0)
326  y_inc = -1 ;
327  else
328  y_inc = 1;
329  int m = std::abs (dy);
330  if (dz < 0)
331  z_inc = -1 ;
332  else
333  z_inc = 1;
334  int n = std::abs (dz);
335  int dx2 = 2 * l;
336  int dy2 = 2 * m;
337  int dz2 = 2 * n;
338  if ((l >= m) & (l >= n))
339  {
340  int err_1 = dy2 - l;
341  int err_2 = dz2 - l;
342  for (int i = 1; i<l; i++)
343  {
344  voxelcount++;;
345  voxel_in += static_cast<int>(lut_[act_voxel[0]][act_voxel[1]][act_voxel[2]] == 1);
346  if (err_1 > 0)
347  {
348  act_voxel[1] += y_inc;
349  err_1 -= dx2;
350  }
351  if (err_2 > 0)
352  {
353  act_voxel[2] += z_inc;
354  err_2 -= dx2;
355  }
356  err_1 += dy2;
357  err_2 += dz2;
358  act_voxel[0] += x_inc;
359  }
360  }
361  else if ((m >= l) & (m >= n))
362  {
363  int err_1 = dx2 - m;
364  int err_2 = dz2 - m;
365  for (int i=1; i<m; i++)
366  {
367  voxelcount++;
368  voxel_in += static_cast<int>(lut_[act_voxel[0]][act_voxel[1]][act_voxel[2]] == 1);
369  if (err_1 > 0)
370  {
371  act_voxel[0] += x_inc;
372  err_1 -= dy2;
373  }
374  if (err_2 > 0)
375  {
376  act_voxel[2] += z_inc;
377  err_2 -= dy2;
378  }
379  err_1 += dx2;
380  err_2 += dz2;
381  act_voxel[1] += y_inc;
382  }
383  }
384  else
385  {
386  int err_1 = dy2 - n;
387  int err_2 = dx2 - n;
388  for (int i=1; i<n; i++)
389  {
390  voxelcount++;
391  voxel_in += static_cast<int>(lut_[act_voxel[0]][act_voxel[1]][act_voxel[2]] == 1);
392  if (err_1 > 0)
393  {
394  act_voxel[1] += y_inc;
395  err_1 -= dz2;
396  }
397  if (err_2 > 0)
398  {
399  act_voxel[0] += x_inc;
400  err_2 -= dz2;
401  }
402  err_1 += dy2;
403  err_2 += dx2;
404  act_voxel[2] += z_inc;
405  }
406  }
407  voxelcount++;
408  voxel_in += static_cast<int>(lut_[act_voxel[0]][act_voxel[1]][act_voxel[2]] == 1);
409  incnt = voxel_in;
410  pointcount = voxelcount;
411 
412  if (voxel_in >= voxelcount-1)
413  return (0);
414 
415  if (voxel_in <= 7)
416  return (1);
417 
418  ratio = static_cast<float>(voxel_in) / static_cast<float>(voxelcount);
419  return (2);
420 }
421 
422 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
423 template <typename PointInT, typename PointOutT> void
425 {
426  for (const auto& point: cluster)
427  {
428  int xx = point.x<0.0? static_cast<int>(std::floor(point.x)+GRIDSIZE_H) : static_cast<int>(std::ceil(point.x)+GRIDSIZE_H-1);
429  int yy = point.y<0.0? static_cast<int>(std::floor(point.y)+GRIDSIZE_H) : static_cast<int>(std::ceil(point.y)+GRIDSIZE_H-1);
430  int zz = point.z<0.0? static_cast<int>(std::floor(point.z)+GRIDSIZE_H) : static_cast<int>(std::ceil(point.z)+GRIDSIZE_H-1);
431 
432  for (int x = -1; x < 2; x++)
433  for (int y = -1; y < 2; y++)
434  for (int z = -1; z < 2; z++)
435  {
436  int xi = xx + x;
437  int yi = yy + y;
438  int zi = zz + z;
439 
440  if (yi >= GRIDSIZE || xi >= GRIDSIZE || zi>=GRIDSIZE || yi < 0 || xi < 0 || zi < 0)
441  {
442  ;
443  }
444  else
445  this->lut_[xi][yi][zi] = 1;
446  }
447  }
448 }
449 
450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
451 template <typename PointInT, typename PointOutT> void
453 {
454  for (const auto& point: cluster)
455  {
456  int xx = point.x<0.0? static_cast<int>(std::floor(point.x)+GRIDSIZE_H) : static_cast<int>(std::ceil(point.x)+GRIDSIZE_H-1);
457  int yy = point.y<0.0? static_cast<int>(std::floor(point.y)+GRIDSIZE_H) : static_cast<int>(std::ceil(point.y)+GRIDSIZE_H-1);
458  int zz = point.z<0.0? static_cast<int>(std::floor(point.z)+GRIDSIZE_H) : static_cast<int>(std::ceil(point.z)+GRIDSIZE_H-1);
459 
460  for (int x = -1; x < 2; x++)
461  for (int y = -1; y < 2; y++)
462  for (int z = -1; z < 2; z++)
463  {
464  int xi = xx + x;
465  int yi = yy + y;
466  int zi = zz + z;
467 
468  if (yi >= GRIDSIZE || xi >= GRIDSIZE || zi>=GRIDSIZE || yi < 0 || xi < 0 || zi < 0)
469  {
470  ;
471  }
472  else
473  this->lut_[xi][yi][zi] = 0;
474  }
475  }
476 }
477 
478 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
479 template <typename PointInT, typename PointOutT> void
481  const pcl::PointCloud<PointInT> &pc, float scalefactor, Eigen::Vector4f& centroid)
482 {
483  pcl::compute3DCentroid (pc, centroid);
484  pcl::demeanPointCloud (pc, centroid, local_cloud_);
485 
486  float max_distance = 0;
487  pcl::PointXYZ cog (0, 0, 0);
488 
489  for (const auto& point: local_cloud_)
490  {
491  float d = pcl::euclideanDistance(cog,point);
492  if (d > max_distance)
493  max_distance = d;
494  }
495 
496  float scale_factor = 1.0f / max_distance * scalefactor;
497 
498  Eigen::Affine3f matrix = Eigen::Affine3f::Identity();
499  matrix.scale (scale_factor);
500  pcl::transformPointCloud (local_cloud_, local_cloud_, matrix);
501 }
502 
503 //////////////////////////////////////////////////////////////////////////////////////////////
504 template<typename PointInT, typename PointOutT> void
506 {
508  {
509  output.width = output.height = 0;
510  output.points.clear ();
511  return;
512  }
513  // Copy the header
514  output.header = input_->header;
515 
516  // Resize the output dataset
517  // Important! We should only allocate precisely how many elements we will need, otherwise
518  // we risk at pre-allocating too much memory which could lead to bad_alloc
519  // (see http://dev.pointclouds.org/issues/657)
520  output.width = output.height = 1;
521  output.is_dense = input_->is_dense;
522  output.points.resize (1);
523 
524  // Perform the actual feature computation
525  computeFeature (output);
526 
528 }
529 
530 
531 //////////////////////////////////////////////////////////////////////////////////////////////
532 template <typename PointInT, typename PointOutT> void
534 {
535  Eigen::Vector4f xyz_centroid;
536  std::vector<float> hist;
537  scale_points_unit_sphere (*surface_, static_cast<float>(GRIDSIZE_H), xyz_centroid);
538  this->voxelize9 (local_cloud_);
539  this->computeESF (local_cloud_, hist);
540  this->cleanup9 (local_cloud_);
541 
542  // We only output _1_ signature
543  output.points.resize (1);
544  output.width = 1;
545  output.height = 1;
546 
547  for (std::size_t d = 0; d < hist.size (); ++d)
548  output[0].histogram[d] = hist[d];
549 }
550 
551 #define PCL_INSTANTIATE_ESFEstimation(T,OutT) template class PCL_EXPORTS pcl::ESFEstimation<T,OutT>;
552 
553 #endif // PCL_FEATURES_IMPL_ESF_H_
554 
pcl::euclideanDistance
float euclideanDistance(const PointType1 &p1, const PointType2 &p2)
Calculate the euclidean distance between the two given points.
Definition: distances.h:204
pcl::demeanPointCloud
void demeanPointCloud(ConstCloudIterator< PointT > &cloud_iterator, const Eigen::Matrix< Scalar, 4, 1 > &centroid, pcl::PointCloud< PointT > &cloud_out, int npts=0)
Subtract a centroid from a point cloud and return the de-meaned representation.
Definition: centroid.hpp:627
pcl::PointCloud< PointInT >
pcl::ESFEstimation::compute
void compute(PointCloudOut &output)
Overloaded computed method from pcl::Feature.
Definition: esf.hpp:505
pcl::ESFEstimation::lci
int lci(const int x1, const int y1, const int z1, const int x2, const int y2, const int z2, float &ratio, int &incnt, int &pointcount)
...
Definition: esf.hpp:305
pcl::transformPointCloud
void transformPointCloud(const pcl::PointCloud< PointT > &cloud_in, pcl::PointCloud< PointT > &cloud_out, const Eigen::Transform< Scalar, 3, Eigen::Affine > &transform, bool copy_all_fields)
Apply an affine transform defined by an Eigen Transform.
Definition: transforms.hpp:221
pcl::ESFEstimation::cleanup9
void cleanup9(PointCloudIn &cluster)
...
Definition: esf.hpp:452
pcl::ESFEstimation::scale_points_unit_sphere
void scale_points_unit_sphere(const pcl::PointCloud< PointInT > &pc, float scalefactor, Eigen::Vector4f &centroid)
...
Definition: esf.hpp:480
pcl::PointXYZ
A point structure representing Euclidean xyz coordinates.
Definition: point_types.hpp:301
M_PI
#define M_PI
Definition: pcl_macros.h:192
pcl::ESFEstimation::voxelize9
void voxelize9(PointCloudIn &cluster)
...
Definition: esf.hpp:424
pcl_round
__inline double pcl_round(double number)
Win32 doesn't seem to have rounding functions.
Definition: pcl_macros.h:244
pcl::PointCloud::size
std::size_t size() const
Definition: point_cloud.h:459
pcl::ESFEstimation::PointCloudOut
typename Feature< PointInT, PointOutT >::PointCloudOut PointCloudOut
Definition: esf.h:74
pcl::ESFEstimation::computeESF
void computeESF(PointCloudIn &pc, std::vector< float > &hist)
...
Definition: esf.hpp:51
pcl::ESFEstimation::computeFeature
void computeFeature(PointCloudOut &output) override
Estimate the Ensebmel of Shape Function (ESF) descriptors at a set of points given by <setInputCloud ...
Definition: esf.hpp:533
pcl::compute3DCentroid
unsigned int compute3DCentroid(ConstCloudIterator< PointT > &cloud_iterator, Eigen::Matrix< Scalar, 4, 1 > &centroid)
Compute the 3D (X-Y-Z) centroid of a set of points and return it as a 3D vector.
Definition: centroid.hpp:56
distances.h
pcl::Feature
Feature represents the base feature class.
Definition: feature.h:107