Point Cloud Library (PCL)  1.11.1-dev
harris_3d.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 Willow Garage, Inc. 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  */
37 
38 #ifndef PCL_HARRIS_KEYPOINT_3D_IMPL_H_
39 #define PCL_HARRIS_KEYPOINT_3D_IMPL_H_
40 
41 #include <pcl/keypoints/harris_3d.h>
42 #include <pcl/common/io.h>
43 #include <pcl/filters/passthrough.h>
44 #include <pcl/filters/extract_indices.h>
45 #include <pcl/features/normal_3d.h>
46 #include <pcl/features/integral_image_normal.h>
47 #include <pcl/common/time.h>
48 #include <pcl/common/centroid.h>
49 #ifdef __SSE__
50 #include <xmmintrin.h>
51 #endif
52 
53 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54 template <typename PointInT, typename PointOutT, typename NormalT> void
56 {
57  if (normals_ && input_ && (cloud != input_))
58  normals_.reset ();
59  input_ = cloud;
60 }
61 
62 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63 template <typename PointInT, typename PointOutT, typename NormalT> void
65 {
66  method_ = method;
67 }
68 
69 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
70 template <typename PointInT, typename PointOutT, typename NormalT> void
72 {
73  threshold_= threshold;
74 }
75 
76 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
77 template <typename PointInT, typename PointOutT, typename NormalT> void
79 {
80  search_radius_ = radius;
81 }
82 
83 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84 template <typename PointInT, typename PointOutT, typename NormalT> void
86 {
87  refine_ = do_refine;
88 }
89 
90 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91 template <typename PointInT, typename PointOutT, typename NormalT> void
93 {
94  nonmax_ = nonmax;
95 }
96 
97 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
98 template <typename PointInT, typename PointOutT, typename NormalT> void
100 {
101  normals_ = normals;
102 }
103 
104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
105 template <typename PointInT, typename PointOutT, typename NormalT> void
106 pcl::HarrisKeypoint3D<PointInT, PointOutT, NormalT>::calculateNormalCovar (const std::vector<int>& neighbors, float* coefficients) const
107 {
108  unsigned count = 0;
109  // indices 0 1 2 3 4 5 6 7
110  // coefficients: xx xy xz ?? yx yy yz ??
111 #ifdef __SSE__
112  // accumulator for xx, xy, xz
113  __m128 vec1 = _mm_setzero_ps();
114  // accumulator for yy, yz, zz
115  __m128 vec2 = _mm_setzero_ps();
116 
117  __m128 norm1;
118 
119  __m128 norm2;
120 
121  float zz = 0;
122 
123  for (const int &neighbor : neighbors)
124  {
125  if (std::isfinite ((*normals_)[neighbor].normal_x))
126  {
127  // nx, ny, nz, h
128  norm1 = _mm_load_ps (&((*normals_)[neighbor].normal_x));
129 
130  // nx, nx, nx, nx
131  norm2 = _mm_set1_ps ((*normals_)[neighbor].normal_x);
132 
133  // nx * nx, nx * ny, nx * nz, nx * h
134  norm2 = _mm_mul_ps (norm1, norm2);
135 
136  // accumulate
137  vec1 = _mm_add_ps (vec1, norm2);
138 
139  // ny, ny, ny, ny
140  norm2 = _mm_set1_ps ((*normals_)[neighbor].normal_y);
141 
142  // ny * nx, ny * ny, ny * nz, ny * h
143  norm2 = _mm_mul_ps (norm1, norm2);
144 
145  // accumulate
146  vec2 = _mm_add_ps (vec2, norm2);
147 
148  zz += (*normals_)[neighbor].normal_z * (*normals_)[neighbor].normal_z;
149  ++count;
150  }
151  }
152  if (count > 0)
153  {
154  norm2 = _mm_set1_ps (float(count));
155  vec1 = _mm_div_ps (vec1, norm2);
156  vec2 = _mm_div_ps (vec2, norm2);
157  _mm_store_ps (coefficients, vec1);
158  _mm_store_ps (coefficients + 4, vec2);
159  coefficients [7] = zz / float(count);
160  }
161  else
162  memset (coefficients, 0, sizeof (float) * 8);
163 #else
164  memset (coefficients, 0, sizeof (float) * 8);
165  for (const auto& index : neighbors)
166  {
167  if (std::isfinite ((*normals_)[index].normal_x))
168  {
169  coefficients[0] += (*normals_)[index].normal_x * (*normals_)[index].normal_x;
170  coefficients[1] += (*normals_)[index].normal_x * (*normals_)[index].normal_y;
171  coefficients[2] += (*normals_)[index].normal_x * (*normals_)[index].normal_z;
172 
173  coefficients[5] += (*normals_)[index].normal_y * (*normals_)[index].normal_y;
174  coefficients[6] += (*normals_)[index].normal_y * (*normals_)[index].normal_z;
175  coefficients[7] += (*normals_)[index].normal_z * (*normals_)[index].normal_z;
176 
177  ++count;
178  }
179  }
180  if (count > 0)
181  {
182  float norm = 1.0 / float (count);
183  coefficients[0] *= norm;
184  coefficients[1] *= norm;
185  coefficients[2] *= norm;
186  coefficients[5] *= norm;
187  coefficients[6] *= norm;
188  coefficients[7] *= norm;
189  }
190 #endif
191 }
192 
193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
194 template <typename PointInT, typename PointOutT, typename NormalT> bool
196 {
198  {
199  PCL_ERROR ("[pcl::%s::initCompute] init failed!\n", name_.c_str ());
200  return (false);
201  }
202 
203  if (method_ < 1 || method_ > 5)
204  {
205  PCL_ERROR ("[pcl::%s::initCompute] method (%d) must be in [1..5]!\n", name_.c_str (), method_);
206  return (false);
207  }
208 
209  if (!normals_)
210  {
211  PointCloudNPtr normals (new PointCloudN ());
212  normals->reserve (normals->size ());
213  if (!surface_->isOrganized ())
214  {
216  normal_estimation.setInputCloud (surface_);
217  normal_estimation.setRadiusSearch (search_radius_);
218  normal_estimation.compute (*normals);
219  }
220  else
221  {
224  normal_estimation.setInputCloud (surface_);
225  normal_estimation.setNormalSmoothingSize (5.0);
226  normal_estimation.compute (*normals);
227  }
228  normals_ = normals;
229  }
230  if (normals_->size () != surface_->size ())
231  {
232  PCL_ERROR ("[pcl::%s::initCompute] normals given, but the number of normals does not match the number of input points!\n", name_.c_str (), method_);
233  return (false);
234  }
235 
236  return (true);
237 }
238 
239 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
240 template <typename PointInT, typename PointOutT, typename NormalT> void
242 {
244 
245  response->points.reserve (input_->size());
246 
247  switch (method_)
248  {
249  case HARRIS:
250  responseHarris(*response);
251  break;
252  case NOBLE:
253  responseNoble(*response);
254  break;
255  case LOWE:
256  responseLowe(*response);
257  break;
258  case CURVATURE:
259  responseCurvature(*response);
260  break;
261  case TOMASI:
262  responseTomasi(*response);
263  break;
264  }
265 
266  if (!nonmax_)
267  {
268  output = *response;
269  // we do not change the denseness in this case
270  output.is_dense = input_->is_dense;
271  for (std::size_t i = 0; i < response->size (); ++i)
272  keypoints_indices_->indices.push_back (i);
273  }
274  else
275  {
276  output.clear ();
277  output.reserve (response->size());
278 
279 #pragma omp parallel for \
280  default(none) \
281  shared(output, response) \
282  num_threads(threads_)
283  for (int idx = 0; idx < static_cast<int> (response->size ()); ++idx)
284  {
285  if (!isFinite ((*response)[idx]) ||
286  !std::isfinite ((*response)[idx].intensity) ||
287  (*response)[idx].intensity < threshold_)
288  continue;
289 
290  std::vector<int> nn_indices;
291  std::vector<float> nn_dists;
292  tree_->radiusSearch (idx, search_radius_, nn_indices, nn_dists);
293  bool is_maxima = true;
294  for (const auto& index : nn_indices)
295  {
296  if ((*response)[idx].intensity < (*response)[index].intensity)
297  {
298  is_maxima = false;
299  break;
300  }
301  }
302  if (is_maxima)
303 #pragma omp critical
304  {
305  output.push_back ((*response)[idx]);
306  keypoints_indices_->indices.push_back (idx);
307  }
308  }
309 
310  if (refine_)
311  refineCorners (output);
312 
313  output.height = 1;
314  output.width = output.size();
315  output.is_dense = true;
316  }
317 }
318 
319 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
320 template <typename PointInT, typename PointOutT, typename NormalT> void
322 {
323  PCL_ALIGN (16) float covar [8];
324  output.resize (input_->size ());
325 #pragma omp parallel for \
326  default(none) \
327  shared(output) \
328  firstprivate(covar) \
329  num_threads(threads_)
330  for (int pIdx = 0; pIdx < static_cast<int> (input_->size ()); ++pIdx)
331  {
332  const PointInT& pointIn = input_->points [pIdx];
333  output [pIdx].intensity = 0.0; //std::numeric_limits<float>::quiet_NaN ();
334  if (isFinite (pointIn))
335  {
336  std::vector<int> nn_indices;
337  std::vector<float> nn_dists;
338  tree_->radiusSearch (pointIn, search_radius_, nn_indices, nn_dists);
339  calculateNormalCovar (nn_indices, covar);
340 
341  float trace = covar [0] + covar [5] + covar [7];
342  if (trace != 0)
343  {
344  float det = covar [0] * covar [5] * covar [7] + 2.0f * covar [1] * covar [2] * covar [6]
345  - covar [2] * covar [2] * covar [5]
346  - covar [1] * covar [1] * covar [7]
347  - covar [6] * covar [6] * covar [0];
348 
349  output [pIdx].intensity = 0.04f + det - 0.04f * trace * trace;
350  }
351  }
352  output [pIdx].x = pointIn.x;
353  output [pIdx].y = pointIn.y;
354  output [pIdx].z = pointIn.z;
355  }
356  output.height = input_->height;
357  output.width = input_->width;
358 }
359 
360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
361 template <typename PointInT, typename PointOutT, typename NormalT> void
363 {
364  PCL_ALIGN (16) float covar [8];
365  output.resize (input_->size ());
366 #pragma omp parallel \
367  for default(none) \
368  shared(output) \
369  firstprivate(covar) \
370  num_threads(threads_)
371  for (int pIdx = 0; pIdx < static_cast<int> (input_->size ()); ++pIdx)
372  {
373  const PointInT& pointIn = input_->points [pIdx];
374  output [pIdx].intensity = 0.0;
375  if (isFinite (pointIn))
376  {
377  std::vector<int> nn_indices;
378  std::vector<float> nn_dists;
379  tree_->radiusSearch (pointIn, search_radius_, nn_indices, nn_dists);
380  calculateNormalCovar (nn_indices, covar);
381  float trace = covar [0] + covar [5] + covar [7];
382  if (trace != 0)
383  {
384  float det = covar [0] * covar [5] * covar [7] + 2.0f * covar [1] * covar [2] * covar [6]
385  - covar [2] * covar [2] * covar [5]
386  - covar [1] * covar [1] * covar [7]
387  - covar [6] * covar [6] * covar [0];
388 
389  output [pIdx].intensity = det / trace;
390  }
391  }
392  output [pIdx].x = pointIn.x;
393  output [pIdx].y = pointIn.y;
394  output [pIdx].z = pointIn.z;
395  }
396  output.height = input_->height;
397  output.width = input_->width;
398 }
399 
400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
401 template <typename PointInT, typename PointOutT, typename NormalT> void
403 {
404  PCL_ALIGN (16) float covar [8];
405  output.resize (input_->size ());
406 #pragma omp parallel for \
407  default(none) \
408  shared(output) \
409  firstprivate(covar) \
410  num_threads(threads_)
411  for (int pIdx = 0; pIdx < static_cast<int> (input_->size ()); ++pIdx)
412  {
413  const PointInT& pointIn = input_->points [pIdx];
414  output [pIdx].intensity = 0.0;
415  if (isFinite (pointIn))
416  {
417  std::vector<int> nn_indices;
418  std::vector<float> nn_dists;
419  tree_->radiusSearch (pointIn, search_radius_, nn_indices, nn_dists);
420  calculateNormalCovar (nn_indices, covar);
421  float trace = covar [0] + covar [5] + covar [7];
422  if (trace != 0)
423  {
424  float det = covar [0] * covar [5] * covar [7] + 2.0f * covar [1] * covar [2] * covar [6]
425  - covar [2] * covar [2] * covar [5]
426  - covar [1] * covar [1] * covar [7]
427  - covar [6] * covar [6] * covar [0];
428 
429  output [pIdx].intensity = det / (trace * trace);
430  }
431  }
432  output [pIdx].x = pointIn.x;
433  output [pIdx].y = pointIn.y;
434  output [pIdx].z = pointIn.z;
435  }
436  output.height = input_->height;
437  output.width = input_->width;
438 }
439 
440 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
441 template <typename PointInT, typename PointOutT, typename NormalT> void
443 {
444  PointOutT point;
445  for (std::size_t idx = 0; idx < input_->size(); ++idx)
446  {
447  point.x = (*input_)[idx].x;
448  point.y = (*input_)[idx].y;
449  point.z = (*input_)[idx].z;
450  point.intensity = (*normals_)[idx].curvature;
451  output.push_back(point);
452  }
453  // does not change the order
454  output.height = input_->height;
455  output.width = input_->width;
456 }
457 
458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
459 template <typename PointInT, typename PointOutT, typename NormalT> void
461 {
462  PCL_ALIGN (16) float covar [8];
463  Eigen::Matrix3f covariance_matrix;
464  output.resize (input_->size ());
465 #pragma omp parallel for \
466  default(none) \
467  shared(output) \
468  firstprivate(covar, covariance_matrix) \
469  num_threads(threads_)
470  for (int pIdx = 0; pIdx < static_cast<int> (input_->size ()); ++pIdx)
471  {
472  const PointInT& pointIn = input_->points [pIdx];
473  output [pIdx].intensity = 0.0;
474  if (isFinite (pointIn))
475  {
476  std::vector<int> nn_indices;
477  std::vector<float> nn_dists;
478  tree_->radiusSearch (pointIn, search_radius_, nn_indices, nn_dists);
479  calculateNormalCovar (nn_indices, covar);
480  float trace = covar [0] + covar [5] + covar [7];
481  if (trace != 0)
482  {
483  covariance_matrix.coeffRef (0) = covar [0];
484  covariance_matrix.coeffRef (1) = covariance_matrix.coeffRef (3) = covar [1];
485  covariance_matrix.coeffRef (2) = covariance_matrix.coeffRef (6) = covar [2];
486  covariance_matrix.coeffRef (4) = covar [5];
487  covariance_matrix.coeffRef (5) = covariance_matrix.coeffRef (7) = covar [6];
488  covariance_matrix.coeffRef (8) = covar [7];
489 
490  EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
491  pcl::eigen33(covariance_matrix, eigen_values);
492  output [pIdx].intensity = eigen_values[0];
493  }
494  }
495  output [pIdx].x = pointIn.x;
496  output [pIdx].y = pointIn.y;
497  output [pIdx].z = pointIn.z;
498  }
499  output.height = input_->height;
500  output.width = input_->width;
501 }
502 
503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
504 template <typename PointInT, typename PointOutT, typename NormalT> void
506 {
507  Eigen::Matrix3f nnT;
508  Eigen::Matrix3f NNT;
509  Eigen::Matrix3f NNTInv;
510  Eigen::Vector3f NNTp;
511  float diff;
512  const unsigned max_iterations = 10;
513 #pragma omp parallel for \
514  default(none) \
515  shared(corners) \
516  firstprivate(nnT, NNT, NNTInv, NNTp, diff) \
517  num_threads(threads_)
518  for (int cIdx = 0; cIdx < static_cast<int> (corners.size ()); ++cIdx)
519  {
520  unsigned iterations = 0;
521  do {
522  NNT.setZero();
523  NNTp.setZero();
524  PointInT corner;
525  corner.x = corners[cIdx].x;
526  corner.y = corners[cIdx].y;
527  corner.z = corners[cIdx].z;
528  std::vector<int> nn_indices;
529  std::vector<float> nn_dists;
530  tree_->radiusSearch (corner, search_radius_, nn_indices, nn_dists);
531  for (const auto& index : nn_indices)
532  {
533  if (!std::isfinite ((*normals_)[index].normal_x))
534  continue;
535 
536  nnT = (*normals_)[index].getNormalVector3fMap () * (*normals_)[index].getNormalVector3fMap ().transpose();
537  NNT += nnT;
538  NNTp += nnT * (*surface_)[index].getVector3fMap ();
539  }
540  if (invert3x3SymMatrix (NNT, NNTInv) != 0)
541  corners[cIdx].getVector3fMap () = NNTInv * NNTp;
542 
543  diff = (corners[cIdx].getVector3fMap () - corner.getVector3fMap()).squaredNorm ();
544  } while (diff > 1e-6 && ++iterations < max_iterations);
545  }
546 }
547 
548 #define PCL_INSTANTIATE_HarrisKeypoint3D(T,U,N) template class PCL_EXPORTS pcl::HarrisKeypoint3D<T,U,N>;
549 #endif // #ifndef PCL_HARRIS_KEYPOINT_3D_IMPL_H_
550 
pcl::HarrisKeypoint3D::setRefine
void setRefine(bool do_refine)
Whether the detected key points should be refined or not.
Definition: harris_3d.hpp:85
pcl::HarrisKeypoint3D::responseLowe
void responseLowe(PointCloudOut &output) const
Definition: harris_3d.hpp:402
pcl::HarrisKeypoint3D::setNonMaxSupression
void setNonMaxSupression(bool=false)
Whether non maxima suppression should be applied or the response for each point should be returned.
Definition: harris_3d.hpp:92
pcl::HarrisKeypoint3D::responseCurvature
void responseCurvature(PointCloudOut &output) const
Definition: harris_3d.hpp:442
pcl::NormalEstimation
NormalEstimation estimates local surface properties (surface normals and curvatures)at each 3D point.
Definition: normal_3d.h:243
pcl::PointCloud::points
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
Definition: point_cloud.h:388
pcl::isFinite
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:55
pcl::IntegralImageNormalEstimation
Surface normal estimation on organized data using integral images.
Definition: integral_image_normal.h:66
pcl::HarrisKeypoint3D::PointCloudNPtr
typename PointCloudN::Ptr PointCloudNPtr
Definition: harris_3d.h:63
pcl::HarrisKeypoint3D::refineCorners
void refineCorners(PointCloudOut &corners) const
Definition: harris_3d.hpp:505
pcl::PointCloud< NormalT >
pcl::IntegralImageNormalEstimation::setInputCloud
void setInputCloud(const typename PointCloudIn::ConstPtr &cloud) override
Provide a pointer to the input dataset (overwrites the PCLBase::setInputCloud method)
Definition: integral_image_normal.h:233
pcl::IntegralImageNormalEstimation::setNormalEstimationMethod
void setNormalEstimationMethod(NormalEstimationMethod normal_estimation_method)
Set the normal estimation method.
Definition: integral_image_normal.h:215
pcl::eigen33
void eigen33(const Matrix &mat, typename Matrix::Scalar &eigenvalue, Vector &eigenvector)
determines the eigenvector and eigenvalue of the smallest eigenvalue of the symmetric positive semi d...
Definition: eigen.hpp:296
pcl::HarrisKeypoint3D::initCompute
bool initCompute() override
Definition: harris_3d.hpp:195
pcl::HarrisKeypoint3D::setMethod
void setMethod(ResponseMethod type)
Set the method of the response to be calculated.
Definition: harris_3d.hpp:64
pcl::HarrisKeypoint3D::setRadius
void setRadius(float radius)
Set the radius for normal estimation and non maxima supression.
Definition: harris_3d.hpp:78
pcl::HarrisKeypoint3D::setInputCloud
void setInputCloud(const PointCloudInConstPtr &cloud) override
Provide a pointer to the input dataset.
Definition: harris_3d.hpp:55
pcl::NormalEstimation::setInputCloud
void setInputCloud(const PointCloudConstPtr &cloud) override
Provide a pointer to the input dataset.
Definition: normal_3d.h:332
pcl::IntegralImageNormalEstimation::setNormalSmoothingSize
void setNormalSmoothingSize(float normal_smoothing_size)
Set the normal smoothing size.
Definition: integral_image_normal.h:191
pcl::HarrisKeypoint3D::PointCloudNConstPtr
typename PointCloudN::ConstPtr PointCloudNConstPtr
Definition: harris_3d.h:64
pcl::Feature::compute
void compute(PointCloudOut &output)
Base method for feature estimation for all points given in <setInputCloud (), setIndices ()> using th...
Definition: feature.hpp:194
pcl::invert3x3SymMatrix
Matrix::Scalar invert3x3SymMatrix(const Matrix &matrix, Matrix &inverse)
Calculate the inverse of a 3x3 symmetric matrix.
Definition: eigen.hpp:424
pcl::HarrisKeypoint3D::PointCloudInConstPtr
typename PointCloudIn::ConstPtr PointCloudInConstPtr
Definition: harris_3d.h:60
pcl::PointCloud::is_dense
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:396
pcl::HarrisKeypoint3D::responseHarris
void responseHarris(PointCloudOut &output) const
gets the corner response for valid input points
Definition: harris_3d.hpp:321
pcl::HarrisKeypoint3D::calculateNormalCovar
void calculateNormalCovar(const std::vector< int > &neighbors, float *coefficients) const
calculates the upper triangular part of unnormalized covariance matrix over the normals given by the ...
Definition: harris_3d.hpp:106
pcl::PointCloud::size
std::size_t size() const
Definition: point_cloud.h:436
pcl::HarrisKeypoint3D::setThreshold
void setThreshold(float threshold)
Set the threshold value for detecting corners.
Definition: harris_3d.hpp:71
pcl::PointCloud::Ptr
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:406
pcl::HarrisKeypoint3D::responseTomasi
void responseTomasi(PointCloudOut &output) const
Definition: harris_3d.hpp:460
time.h
pcl::Feature::setRadiusSearch
void setRadiusSearch(double radius)
Set the sphere radius that is to be used for determining the nearest neighbors used for the feature e...
Definition: feature.h:201
pcl::HarrisKeypoint3D::ResponseMethod
ResponseMethod
Definition: harris_3d.h:78
pcl::Keypoint
Keypoint represents the base class for key points.
Definition: keypoint.h:49
pcl::HarrisKeypoint3D::setNormals
void setNormals(const PointCloudNConstPtr &normals)
Set normals if precalculated normals are available.
Definition: harris_3d.hpp:99
pcl::HarrisKeypoint3D::detectKeypoints
void detectKeypoints(PointCloudOut &output) override
Definition: harris_3d.hpp:241
pcl::HarrisKeypoint3D::PointCloudOut
typename Keypoint< PointInT, PointOutT >::PointCloudOut PointCloudOut
Definition: harris_3d.h:58
pcl::HarrisKeypoint3D::responseNoble
void responseNoble(PointCloudOut &output) const
Definition: harris_3d.hpp:362
centroid.h