39 #ifndef PCL_FEATURES_IMPL_SHOT_H_
40 #define PCL_FEATURES_IMPL_SHOT_H_
47 #define PST_PI 3.1415926535897932384626433832795
48 #define PST_RAD_45 0.78539816339744830961566084581988
49 #define PST_RAD_90 1.5707963267948966192313216916398
50 #define PST_RAD_135 2.3561944901923449288469825374596
51 #define PST_RAD_180 PST_PI
52 #define PST_RAD_360 6.283185307179586476925286766558
53 #define PST_RAD_PI_7_8 2.7488935718910690836548129603691
69 return (fabs (val1 - val2)<zeroDoubleEps);
83 return (fabs (val1 - val2)<zeroFloatEps);
87 template <
typename Po
intNT,
typename Po
intRFT>
float
91 template <
typename Po
intNT,
typename Po
intRFT>
float
95 template <
typename Po
intNT,
typename Po
intRFT>
void
97 unsigned char B,
float &L,
float &A,
102 for (
int i = 0; i < 256; i++)
104 float f =
static_cast<float> (i) / 255.0f;
106 sRGB_LUT[i] = powf ((f + 0.055f) / 1.055f, 2.4f);
108 sRGB_LUT[i] = f / 12.92f;
111 for (
int i = 0; i < 4000; i++)
113 float f =
static_cast<float> (i) / 4000.0f;
115 sXYZ_LUT[i] =
static_cast<float> (powf (f, 0.3333f));
117 sXYZ_LUT[i] =
static_cast<float>((7.787 * f) + (16.0 / 116.0));
121 float fr = sRGB_LUT[R];
122 float fg = sRGB_LUT[G];
123 float fb = sRGB_LUT[
B];
126 const float x = fr * 0.412453f + fg * 0.357580f + fb * 0.180423f;
127 const float y = fr * 0.212671f + fg * 0.715160f + fb * 0.072169f;
128 const float z = fr * 0.019334f + fg * 0.119193f + fb * 0.950227f;
130 float vx = x / 0.95047f;
132 float vz = z / 1.08883f;
134 vx = sXYZ_LUT[int(vx*4000)];
135 vy = sXYZ_LUT[int(vy*4000)];
136 vz = sXYZ_LUT[int(vz*4000)];
138 L = 116.0f * vy - 16.0f;
142 A = 500.0f * (vx - vy);
148 B2 = 200.0f * (vy - vz);
156 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
float
157 pcl::SHOTColorEstimation<PointInT, PointNT, PointOutT, PointRFT>::sRGB_LUT[256] = {- 1};
160 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
float
161 pcl::SHOTColorEstimation<PointInT, PointNT, PointOutT, PointRFT>::sXYZ_LUT[4000] = {- 1};
164 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
void
165 pcl::SHOTColorEstimation<PointInT, PointNT, PointOutT, PointRFT>::RGB2CIELAB (
unsigned char R,
unsigned char G,
166 unsigned char B,
float &L,
float &A,
171 for (
int i = 0; i < 256; i++)
173 float f =
static_cast<float> (i) / 255.0f;
175 sRGB_LUT[i] = powf ((f + 0.055f) / 1.055f, 2.4f);
177 sRGB_LUT[i] = f / 12.92f;
180 for (
int i = 0; i < 4000; i++)
182 float f =
static_cast<float> (i) / 4000.0f;
184 sXYZ_LUT[i] =
static_cast<float> (powf (f, 0.3333f));
186 sXYZ_LUT[i] =
static_cast<float>((7.787 * f) + (16.0 / 116.0));
190 float fr = sRGB_LUT[R];
191 float fg = sRGB_LUT[G];
192 float fb = sRGB_LUT[
B];
195 const float x = fr * 0.412453f + fg * 0.357580f + fb * 0.180423f;
196 const float y = fr * 0.212671f + fg * 0.715160f + fb * 0.072169f;
197 const float z = fr * 0.019334f + fg * 0.119193f + fb * 0.950227f;
199 float vx = x / 0.95047f;
201 float vz = z / 1.08883f;
203 vx = sXYZ_LUT[int(vx*4000)];
204 vy = sXYZ_LUT[int(vy*4000)];
205 vz = sXYZ_LUT[int(vz*4000)];
207 L = 116.0f * vy - 16.0f;
211 A = 500.0f * (vx - vy);
217 B2 = 200.0f * (vy - vz);
225 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
bool
228 if (!FeatureFromNormals<PointInT, PointNT, PointOutT>::initCompute ())
230 PCL_ERROR (
"[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
235 if (this->getKSearch () != 0)
238 "[pcl::%s::initCompute] Error! Search method set to k-neighborhood. Call setKSearch(0) and setRadiusSearch( radius ) to use this class.\n",
239 getClassName().c_str ());
244 typename SHOTLocalReferenceFrameEstimation<PointInT, PointRFT>::Ptr lrf_estimator(
new SHOTLocalReferenceFrameEstimation<PointInT, PointRFT>());
245 lrf_estimator->setRadiusSearch (search_radius_);
246 lrf_estimator->setInputCloud (input_);
247 lrf_estimator->setIndices (indices_);
249 lrf_estimator->setSearchSurface(surface_);
251 if (!FeatureWithLocalReferenceFrames<PointInT, PointRFT>::initLocalReferenceFrames (indices_->size (), lrf_estimator))
253 PCL_ERROR (
"[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
261 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
void
264 const std::vector<int> &indices,
265 std::vector<double> &bin_distance_shape)
267 bin_distance_shape.resize (indices.size ());
269 const PointRFT& current_frame = frames_->points[index];
273 for (
size_t i_idx = 0; i_idx < indices.size (); ++i_idx)
276 double cosineDesc = normals_->points[indices[i_idx]].getNormalVector4fMap ().dot (current_frame.z_axis.getNormalVector4fMap ());
278 if (cosineDesc > 1.0)
280 if (cosineDesc < - 1.0)
283 bin_distance_shape[i_idx] = ((1.0 + cosineDesc) * nr_shape_bins_) / 2;
288 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
void
290 Eigen::VectorXf &shot,
int desc_length)
293 for (
int j = 0; j < desc_length; j++)
294 acc_norm += shot[j] * shot[j];
295 acc_norm =
sqrt (acc_norm);
296 for (
int j = 0; j < desc_length; j++)
297 shot[j] /= static_cast<float> (acc_norm);
301 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
void
303 const std::vector<int> &indices,
304 const std::vector<float> &sqr_dists,
306 std::vector<double> &binDistance,
308 Eigen::VectorXf &shot)
310 const Eigen::Vector4f& central_point = (*input_)[(*indices_)[index]].getVector4fMap ();
311 const PointRFT& current_frame = (*frames_)[index];
313 for (
size_t i_idx = 0; i_idx < indices.size (); ++i_idx)
315 Eigen::Vector4f delta = surface_->points[indices[i_idx]].getVector4fMap () - central_point;
324 double xInFeatRef = delta.dot (current_frame.x_axis.getNormalVector4fMap ());
325 double yInFeatRef = delta.dot (current_frame.y_axis.getNormalVector4fMap ());
326 double zInFeatRef = delta.dot (current_frame.z_axis.getNormalVector4fMap ());
329 if (fabs (yInFeatRef) < 1E-30)
331 if (fabs (xInFeatRef) < 1E-30)
333 if (fabs (zInFeatRef) < 1E-30)
337 unsigned char bit4 = ((yInFeatRef > 0) || ((yInFeatRef == 0.0) && (xInFeatRef < 0))) ? 1 : 0;
338 unsigned char bit3 =
static_cast<unsigned char> (((xInFeatRef > 0) || ((xInFeatRef == 0.0) && (yInFeatRef > 0))) ? !bit4 : bit4);
340 assert (bit3 == 0 || bit3 == 1);
342 int desc_index = (bit4<<3) + (bit3<<2);
344 desc_index = desc_index << 1;
346 if ((xInFeatRef * yInFeatRef > 0) || (xInFeatRef == 0.0))
347 desc_index += (fabs (xInFeatRef) >= fabs (yInFeatRef)) ? 0 : 4;
349 desc_index += (fabs (xInFeatRef) > fabs (yInFeatRef)) ? 4 : 0;
351 desc_index += zInFeatRef > 0 ? 1 : 0;
354 desc_index += (distance > radius1_2_) ? 2 : 0;
356 int step_index =
static_cast<int>(floor (binDistance[i_idx] +0.5));
357 int volume_index = desc_index * (nr_bins+1);
360 binDistance[i_idx] -= step_index;
361 double intWeight = (1- fabs (binDistance[i_idx]));
363 if (binDistance[i_idx] > 0)
364 shot[volume_index + ((step_index+1) % nr_bins)] +=
static_cast<float> (binDistance[i_idx]);
366 shot[volume_index + ((step_index - 1 + nr_bins) % nr_bins)] += -
static_cast<float> (binDistance[i_idx]);
370 if (distance > radius1_2_)
372 double radiusDistance = (distance - radius3_4_) / radius1_2_;
374 if (distance > radius3_4_)
375 intWeight += 1 - radiusDistance;
378 intWeight += 1 + radiusDistance;
379 shot[(desc_index - 2) * (nr_bins+1) + step_index] -=
static_cast<float> (radiusDistance);
384 double radiusDistance = (distance - radius1_4_) / radius1_2_;
386 if (distance < radius1_4_)
387 intWeight += 1 + radiusDistance;
390 intWeight += 1 - radiusDistance;
391 shot[(desc_index + 2) * (nr_bins+1) + step_index] +=
static_cast<float> (radiusDistance);
396 double inclinationCos = zInFeatRef / distance;
397 if (inclinationCos < - 1.0)
398 inclinationCos = - 1.0;
399 if (inclinationCos > 1.0)
400 inclinationCos = 1.0;
402 double inclination = acos (inclinationCos);
404 assert (inclination >= 0.0 && inclination <=
PST_RAD_180);
410 intWeight += 1 - inclinationDistance;
413 intWeight += 1 + inclinationDistance;
414 assert ((desc_index + 1) * (nr_bins+1) + step_index >= 0 && (desc_index + 1) * (nr_bins+1) + step_index < descLength_);
415 shot[(desc_index + 1) * (nr_bins+1) + step_index] -=
static_cast<float> (inclinationDistance);
422 intWeight += 1 + inclinationDistance;
425 intWeight += 1 - inclinationDistance;
426 assert ((desc_index - 1) * (nr_bins+1) + step_index >= 0 && (desc_index - 1) * (nr_bins+1) + step_index < descLength_);
427 shot[(desc_index - 1) * (nr_bins+1) + step_index] +=
static_cast<float> (inclinationDistance);
431 if (yInFeatRef != 0.0 || xInFeatRef != 0.0)
434 double azimuth = atan2 (yInFeatRef, xInFeatRef);
436 int sel = desc_index >> 2;
440 double azimuthDistance = (azimuth - (angularSectorStart + angularSectorSpan*sel)) / angularSectorSpan;
442 assert ((azimuthDistance < 0.5 ||
areEquals (azimuthDistance, 0.5)) && (azimuthDistance > - 0.5 ||
areEquals (azimuthDistance, - 0.5)));
444 azimuthDistance = (std::max)(- 0.5, std::min (azimuthDistance, 0.5));
446 if (azimuthDistance > 0)
448 intWeight += 1 - azimuthDistance;
449 int interp_index = (desc_index + 4) % maxAngularSectors_;
450 assert (interp_index * (nr_bins+1) + step_index >= 0 && interp_index * (nr_bins+1) + step_index < descLength_);
451 shot[interp_index * (nr_bins+1) + step_index] += static_cast<float> (azimuthDistance);
455 int interp_index = (desc_index - 4 + maxAngularSectors_) % maxAngularSectors_;
456 assert (interp_index * (nr_bins+1) + step_index >= 0 && interp_index * (nr_bins+1) + step_index < descLength_);
457 intWeight += 1 + azimuthDistance;
458 shot[interp_index * (nr_bins+1) + step_index] -= static_cast<float> (azimuthDistance);
463 assert (volume_index + step_index >= 0 && volume_index + step_index < descLength_);
464 shot[volume_index + step_index] +=
static_cast<float> (intWeight);
469 template <
typename Po
intNT,
typename Po
intRFT>
void
471 const std::vector<int> &indices,
472 const std::vector<float> &sqr_dists,
474 std::vector<double> &binDistanceShape,
475 std::vector<double> &binDistanceColor,
476 const int nr_bins_shape,
477 const int nr_bins_color,
478 Eigen::VectorXf &shot)
480 const Eigen::Vector4f ¢ral_point = (*input_)[(*indices_)[index]].getVector4fMap ();
481 const PointRFT& current_frame = (*frames_)[index];
483 int shapeToColorStride = nr_grid_sector_*(nr_bins_shape+1);
485 for (
size_t i_idx = 0; i_idx < indices.size (); ++i_idx)
487 Eigen::Vector4f delta = surface_->points[indices[i_idx]].getVector4fMap () - central_point;
491 double distance =
sqrt (sqr_dists[i_idx]);
496 double xInFeatRef = delta.dot (current_frame.x_axis.getNormalVector4fMap ());
497 double yInFeatRef = delta.dot (current_frame.y_axis.getNormalVector4fMap ());
498 double zInFeatRef = delta.dot (current_frame.z_axis.getNormalVector4fMap ());
501 if (fabs (yInFeatRef) < 1E-30)
503 if (fabs (xInFeatRef) < 1E-30)
505 if (fabs (zInFeatRef) < 1E-30)
508 unsigned char bit4 = ((yInFeatRef > 0) || ((yInFeatRef == 0.0) && (xInFeatRef < 0))) ? 1 : 0;
509 unsigned char bit3 =
static_cast<unsigned char> (((xInFeatRef > 0) || ((xInFeatRef == 0.0) && (yInFeatRef > 0))) ? !bit4 : bit4);
511 assert (bit3 == 0 || bit3 == 1);
513 int desc_index = (bit4<<3) + (bit3<<2);
515 desc_index = desc_index << 1;
517 if ((xInFeatRef * yInFeatRef > 0) || (xInFeatRef == 0.0))
518 desc_index += (fabs (xInFeatRef) >= fabs (yInFeatRef)) ? 0 : 4;
520 desc_index += (fabs (xInFeatRef) > fabs (yInFeatRef)) ? 4 : 0;
522 desc_index += zInFeatRef > 0 ? 1 : 0;
525 desc_index += (distance > radius1_2_) ? 2 : 0;
527 int step_index_shape =
static_cast<int>(floor (binDistanceShape[i_idx] +0.5));
528 int step_index_color =
static_cast<int>(floor (binDistanceColor[i_idx] +0.5));
530 int volume_index_shape = desc_index * (nr_bins_shape+1);
531 int volume_index_color = shapeToColorStride + desc_index * (nr_bins_color+1);
534 binDistanceShape[i_idx] -= step_index_shape;
535 binDistanceColor[i_idx] -= step_index_color;
537 double intWeightShape = (1- fabs (binDistanceShape[i_idx]));
538 double intWeightColor = (1- fabs (binDistanceColor[i_idx]));
540 if (binDistanceShape[i_idx] > 0)
541 shot[volume_index_shape + ((step_index_shape + 1) % nr_bins_shape)] +=
static_cast<float> (binDistanceShape[i_idx]);
543 shot[volume_index_shape + ((step_index_shape - 1 + nr_bins_shape) % nr_bins_shape)] -=
static_cast<float> (binDistanceShape[i_idx]);
545 if (binDistanceColor[i_idx] > 0)
546 shot[volume_index_color + ((step_index_color+1) % nr_bins_color)] +=
static_cast<float> (binDistanceColor[i_idx]);
548 shot[volume_index_color + ((step_index_color - 1 + nr_bins_color) % nr_bins_color)] -=
static_cast<float> (binDistanceColor[i_idx]);
552 if (distance > radius1_2_)
554 double radiusDistance = (distance - radius3_4_) / radius1_2_;
556 if (distance > radius3_4_)
558 intWeightShape += 1 - radiusDistance;
559 intWeightColor += 1 - radiusDistance;
563 intWeightShape += 1 + radiusDistance;
564 intWeightColor += 1 + radiusDistance;
565 shot[(desc_index - 2) * (nr_bins_shape+1) + step_index_shape] -=
static_cast<float> (radiusDistance);
566 shot[shapeToColorStride + (desc_index - 2) * (nr_bins_color+1) + step_index_color] -=
static_cast<float> (radiusDistance);
571 double radiusDistance = (distance - radius1_4_) / radius1_2_;
573 if (distance < radius1_4_)
575 intWeightShape += 1 + radiusDistance;
576 intWeightColor += 1 + radiusDistance;
580 intWeightShape += 1 - radiusDistance;
581 intWeightColor += 1 - radiusDistance;
582 shot[(desc_index + 2) * (nr_bins_shape+1) + step_index_shape] +=
static_cast<float> (radiusDistance);
583 shot[shapeToColorStride + (desc_index + 2) * (nr_bins_color+1) + step_index_color] +=
static_cast<float> (radiusDistance);
588 double inclinationCos = zInFeatRef / distance;
589 if (inclinationCos < - 1.0)
590 inclinationCos = - 1.0;
591 if (inclinationCos > 1.0)
592 inclinationCos = 1.0;
594 double inclination = acos (inclinationCos);
596 assert (inclination >= 0.0 && inclination <=
PST_RAD_180);
603 intWeightShape += 1 - inclinationDistance;
604 intWeightColor += 1 - inclinationDistance;
608 intWeightShape += 1 + inclinationDistance;
609 intWeightColor += 1 + inclinationDistance;
610 assert ((desc_index + 1) * (nr_bins_shape+1) + step_index_shape >= 0 && (desc_index + 1) * (nr_bins_shape+1) + step_index_shape < descLength_);
611 assert (shapeToColorStride + (desc_index + 1) * (nr_bins_color+ 1) + step_index_color >= 0 && shapeToColorStride + (desc_index + 1) * (nr_bins_color+1) + step_index_color < descLength_);
612 shot[(desc_index + 1) * (nr_bins_shape+1) + step_index_shape] -=
static_cast<float> (inclinationDistance);
613 shot[shapeToColorStride + (desc_index + 1) * (nr_bins_color+1) + step_index_color] -=
static_cast<float> (inclinationDistance);
621 intWeightShape += 1 + inclinationDistance;
622 intWeightColor += 1 + inclinationDistance;
626 intWeightShape += 1 - inclinationDistance;
627 intWeightColor += 1 - inclinationDistance;
628 assert ((desc_index - 1) * (nr_bins_shape+1) + step_index_shape >= 0 && (desc_index - 1) * (nr_bins_shape+1) + step_index_shape < descLength_);
629 assert (shapeToColorStride + (desc_index - 1) * (nr_bins_color+ 1) + step_index_color >= 0 && shapeToColorStride + (desc_index - 1) * (nr_bins_color+1) + step_index_color < descLength_);
630 shot[(desc_index - 1) * (nr_bins_shape+1) + step_index_shape] +=
static_cast<float> (inclinationDistance);
631 shot[shapeToColorStride + (desc_index - 1) * (nr_bins_color+1) + step_index_color] +=
static_cast<float> (inclinationDistance);
635 if (yInFeatRef != 0.0 || xInFeatRef != 0.0)
638 double azimuth = atan2 (yInFeatRef, xInFeatRef);
640 int sel = desc_index >> 2;
644 double azimuthDistance = (azimuth - (angularSectorStart + angularSectorSpan*sel)) / angularSectorSpan;
645 assert ((azimuthDistance < 0.5 ||
areEquals (azimuthDistance, 0.5)) && (azimuthDistance > - 0.5 ||
areEquals (azimuthDistance, - 0.5)));
646 azimuthDistance = (std::max)(- 0.5, std::min (azimuthDistance, 0.5));
648 if (azimuthDistance > 0)
650 intWeightShape += 1 - azimuthDistance;
651 intWeightColor += 1 - azimuthDistance;
652 int interp_index = (desc_index + 4) % maxAngularSectors_;
653 assert (interp_index * (nr_bins_shape+1) + step_index_shape >= 0 && interp_index * (nr_bins_shape+1) + step_index_shape < descLength_);
654 assert (shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color >= 0 && shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color < descLength_);
655 shot[interp_index * (nr_bins_shape+1) + step_index_shape] += static_cast<float> (azimuthDistance);
656 shot[shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color] += static_cast<float> (azimuthDistance);
660 int interp_index = (desc_index - 4 + maxAngularSectors_) % maxAngularSectors_;
661 intWeightShape += 1 + azimuthDistance;
662 intWeightColor += 1 + azimuthDistance;
663 assert (interp_index * (nr_bins_shape+1) + step_index_shape >= 0 && interp_index * (nr_bins_shape+1) + step_index_shape < descLength_);
664 assert (shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color >= 0 && shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color < descLength_);
665 shot[interp_index * (nr_bins_shape+1) + step_index_shape] -= static_cast<float> (azimuthDistance);
666 shot[shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color] -= static_cast<float> (azimuthDistance);
670 assert (volume_index_shape + step_index_shape >= 0 && volume_index_shape + step_index_shape < descLength_);
671 assert (volume_index_color + step_index_color >= 0 && volume_index_color + step_index_color < descLength_);
672 shot[volume_index_shape + step_index_shape] +=
static_cast<float> (intWeightShape);
673 shot[volume_index_color + step_index_color] +=
static_cast<float> (intWeightColor);
678 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
void
679 pcl::SHOTColorEstimation<PointInT, PointNT, PointOutT, PointRFT>::interpolateDoubleChannel (
680 const std::vector<int> &indices,
681 const std::vector<float> &sqr_dists,
683 std::vector<double> &binDistanceShape,
684 std::vector<double> &binDistanceColor,
685 const int nr_bins_shape,
686 const int nr_bins_color,
687 Eigen::VectorXf &shot)
689 const Eigen::Vector4f ¢ral_point = (*input_)[(*indices_)[index]].getVector4fMap ();
690 const PointRFT& current_frame = (*frames_)[index];
692 int shapeToColorStride = nr_grid_sector_*(nr_bins_shape+1);
694 for (
size_t i_idx = 0; i_idx < indices.size (); ++i_idx)
696 Eigen::Vector4f delta = surface_->points[indices[i_idx]].getVector4fMap () - central_point;
700 double distance =
sqrt (sqr_dists[i_idx]);
705 double xInFeatRef = delta.dot (current_frame.x_axis.getNormalVector4fMap ());
706 double yInFeatRef = delta.dot (current_frame.y_axis.getNormalVector4fMap ());
707 double zInFeatRef = delta.dot (current_frame.z_axis.getNormalVector4fMap ());
710 if (fabs (yInFeatRef) < 1E-30)
712 if (fabs (xInFeatRef) < 1E-30)
714 if (fabs (zInFeatRef) < 1E-30)
717 unsigned char bit4 = ((yInFeatRef > 0) || ((yInFeatRef == 0.0) && (xInFeatRef < 0))) ? 1 : 0;
718 unsigned char bit3 =
static_cast<unsigned char> (((xInFeatRef > 0) || ((xInFeatRef == 0.0) && (yInFeatRef > 0))) ? !bit4 : bit4);
720 assert (bit3 == 0 || bit3 == 1);
722 int desc_index = (bit4<<3) + (bit3<<2);
724 desc_index = desc_index << 1;
726 if ((xInFeatRef * yInFeatRef > 0) || (xInFeatRef == 0.0))
727 desc_index += (fabs (xInFeatRef) >= fabs (yInFeatRef)) ? 0 : 4;
729 desc_index += (fabs (xInFeatRef) > fabs (yInFeatRef)) ? 4 : 0;
731 desc_index += zInFeatRef > 0 ? 1 : 0;
734 desc_index += (distance > radius1_2_) ? 2 : 0;
736 int step_index_shape =
static_cast<int>(floor (binDistanceShape[i_idx] +0.5));
737 int step_index_color =
static_cast<int>(floor (binDistanceColor[i_idx] +0.5));
739 int volume_index_shape = desc_index * (nr_bins_shape+1);
740 int volume_index_color = shapeToColorStride + desc_index * (nr_bins_color+1);
743 binDistanceShape[i_idx] -= step_index_shape;
744 binDistanceColor[i_idx] -= step_index_color;
746 double intWeightShape = (1- fabs (binDistanceShape[i_idx]));
747 double intWeightColor = (1- fabs (binDistanceColor[i_idx]));
749 if (binDistanceShape[i_idx] > 0)
750 shot[volume_index_shape + ((step_index_shape + 1) % nr_bins_shape)] +=
static_cast<float> (binDistanceShape[i_idx]);
752 shot[volume_index_shape + ((step_index_shape - 1 + nr_bins_shape) % nr_bins_shape)] -=
static_cast<float> (binDistanceShape[i_idx]);
754 if (binDistanceColor[i_idx] > 0)
755 shot[volume_index_color + ((step_index_color+1) % nr_bins_color)] +=
static_cast<float> (binDistanceColor[i_idx]);
757 shot[volume_index_color + ((step_index_color - 1 + nr_bins_color) % nr_bins_color)] -=
static_cast<float> (binDistanceColor[i_idx]);
761 if (distance > radius1_2_)
763 double radiusDistance = (distance - radius3_4_) / radius1_2_;
765 if (distance > radius3_4_)
767 intWeightShape += 1 - radiusDistance;
768 intWeightColor += 1 - radiusDistance;
772 intWeightShape += 1 + radiusDistance;
773 intWeightColor += 1 + radiusDistance;
774 shot[(desc_index - 2) * (nr_bins_shape+1) + step_index_shape] -=
static_cast<float> (radiusDistance);
775 shot[shapeToColorStride + (desc_index - 2) * (nr_bins_color+1) + step_index_color] -=
static_cast<float> (radiusDistance);
780 double radiusDistance = (distance - radius1_4_) / radius1_2_;
782 if (distance < radius1_4_)
784 intWeightShape += 1 + radiusDistance;
785 intWeightColor += 1 + radiusDistance;
789 intWeightShape += 1 - radiusDistance;
790 intWeightColor += 1 - radiusDistance;
791 shot[(desc_index + 2) * (nr_bins_shape+1) + step_index_shape] +=
static_cast<float> (radiusDistance);
792 shot[shapeToColorStride + (desc_index + 2) * (nr_bins_color+1) + step_index_color] +=
static_cast<float> (radiusDistance);
797 double inclinationCos = zInFeatRef / distance;
798 if (inclinationCos < - 1.0)
799 inclinationCos = - 1.0;
800 if (inclinationCos > 1.0)
801 inclinationCos = 1.0;
803 double inclination = acos (inclinationCos);
805 assert (inclination >= 0.0 && inclination <=
PST_RAD_180);
812 intWeightShape += 1 - inclinationDistance;
813 intWeightColor += 1 - inclinationDistance;
817 intWeightShape += 1 + inclinationDistance;
818 intWeightColor += 1 + inclinationDistance;
819 assert ((desc_index + 1) * (nr_bins_shape+1) + step_index_shape >= 0 && (desc_index + 1) * (nr_bins_shape+1) + step_index_shape < descLength_);
820 assert (shapeToColorStride + (desc_index + 1) * (nr_bins_color+ 1) + step_index_color >= 0 && shapeToColorStride + (desc_index + 1) * (nr_bins_color+1) + step_index_color < descLength_);
821 shot[(desc_index + 1) * (nr_bins_shape+1) + step_index_shape] -=
static_cast<float> (inclinationDistance);
822 shot[shapeToColorStride + (desc_index + 1) * (nr_bins_color+1) + step_index_color] -=
static_cast<float> (inclinationDistance);
830 intWeightShape += 1 + inclinationDistance;
831 intWeightColor += 1 + inclinationDistance;
835 intWeightShape += 1 - inclinationDistance;
836 intWeightColor += 1 - inclinationDistance;
837 assert ((desc_index - 1) * (nr_bins_shape+1) + step_index_shape >= 0 && (desc_index - 1) * (nr_bins_shape+1) + step_index_shape < descLength_);
838 assert (shapeToColorStride + (desc_index - 1) * (nr_bins_color+ 1) + step_index_color >= 0 && shapeToColorStride + (desc_index - 1) * (nr_bins_color+1) + step_index_color < descLength_);
839 shot[(desc_index - 1) * (nr_bins_shape+1) + step_index_shape] +=
static_cast<float> (inclinationDistance);
840 shot[shapeToColorStride + (desc_index - 1) * (nr_bins_color+1) + step_index_color] +=
static_cast<float> (inclinationDistance);
844 if (yInFeatRef != 0.0 || xInFeatRef != 0.0)
847 double azimuth = atan2 (yInFeatRef, xInFeatRef);
849 int sel = desc_index >> 2;
853 double azimuthDistance = (azimuth - (angularSectorStart + angularSectorSpan*sel)) / angularSectorSpan;
854 assert ((azimuthDistance < 0.5 ||
areEquals (azimuthDistance, 0.5)) && (azimuthDistance > - 0.5 ||
areEquals (azimuthDistance, - 0.5)));
855 azimuthDistance = (std::max)(- 0.5, std::min (azimuthDistance, 0.5));
857 if (azimuthDistance > 0)
859 intWeightShape += 1 - azimuthDistance;
860 intWeightColor += 1 - azimuthDistance;
861 int interp_index = (desc_index + 4) % maxAngularSectors_;
862 assert (interp_index * (nr_bins_shape+1) + step_index_shape >= 0 && interp_index * (nr_bins_shape+1) + step_index_shape < descLength_);
863 assert (shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color >= 0 && shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color < descLength_);
864 shot[interp_index * (nr_bins_shape+1) + step_index_shape] += static_cast<float> (azimuthDistance);
865 shot[shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color] += static_cast<float> (azimuthDistance);
869 int interp_index = (desc_index - 4 + maxAngularSectors_) % maxAngularSectors_;
870 intWeightShape += 1 + azimuthDistance;
871 intWeightColor += 1 + azimuthDistance;
872 assert (interp_index * (nr_bins_shape+1) + step_index_shape >= 0 && interp_index * (nr_bins_shape+1) + step_index_shape < descLength_);
873 assert (shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color >= 0 && shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color < descLength_);
874 shot[interp_index * (nr_bins_shape+1) + step_index_shape] -= static_cast<float> (azimuthDistance);
875 shot[shapeToColorStride + interp_index * (nr_bins_color+1) + step_index_color] -= static_cast<float> (azimuthDistance);
879 assert (volume_index_shape + step_index_shape >= 0 && volume_index_shape + step_index_shape < descLength_);
880 assert (volume_index_color + step_index_color >= 0 && volume_index_color + step_index_color < descLength_);
881 shot[volume_index_shape + step_index_shape] +=
static_cast<float> (intWeightShape);
882 shot[volume_index_color + step_index_color] +=
static_cast<float> (intWeightColor);
888 template <
typename Po
intNT,
typename Po
intRFT>
void
890 const int index,
const std::vector<int> &indices,
const std::vector<float> &sqr_dists, Eigen::VectorXf &shot)
894 std::vector<double> binDistanceShape;
895 std::vector<double> binDistanceColor;
896 size_t nNeighbors = indices.size ();
900 PCL_WARN (
"[pcl::%s::computePointSHOT] Warning! Neighborhood has less than 5 vertexes. Aborting description of point with index %d\n",
901 getClassName ().c_str (), (*indices_)[index]);
903 shot.setConstant(descLength_, 1, std::numeric_limits<float>::quiet_NaN () );
908 const PointRFT& current_frame = frames_->points[index];
913 if (b_describe_shape_)
915 binDistanceShape.resize (nNeighbors);
917 for (
size_t i_idx = 0; i_idx < indices.size (); ++i_idx)
920 double cosineDesc = normals_->points[indices[i_idx]].getNormalVector4fMap ().dot (current_frame.z_axis.getNormalVector4fMap ());
922 if (cosineDesc > 1.0)
924 if (cosineDesc < - 1.0)
927 binDistanceShape[i_idx] = ((1.0 + cosineDesc) * nr_shape_bins_) / 2;
932 if (b_describe_color_)
934 binDistanceColor.resize (nNeighbors);
936 unsigned char redRef = input_->points[(*indices_)[index]].rgba >> 16 & 0xFF;
937 unsigned char greenRef = input_->points[(*indices_)[index]].rgba >> 8& 0xFF;
938 unsigned char blueRef = input_->points[(*indices_)[index]].rgba & 0xFF;
940 float LRef, aRef, bRef;
942 RGB2CIELAB (redRef, greenRef, blueRef, LRef, aRef, bRef);
947 for (
size_t i_idx = 0; i_idx < indices.size (); ++i_idx)
949 unsigned char red = surface_->points[indices[i_idx]].rgba >> 16 & 0xFF;
950 unsigned char green = surface_->points[indices[i_idx]].rgba >> 8 & 0xFF;
951 unsigned char blue = surface_->points[indices[i_idx]].rgba & 0xFF;
955 RGB2CIELAB (red, green, blue, L, a, b);
960 double colorDistance = (fabs (LRef - L) + ((fabs (aRef - a) + fabs (bRef - b)) / 2)) /3;
962 if (colorDistance > 1.0)
964 if (colorDistance < 0.0)
967 binDistanceColor[i_idx] = colorDistance * nr_color_bins_;
973 if (b_describe_shape_ && b_describe_color_)
974 interpolateDoubleChannel (indices, sqr_dists, index, binDistanceShape, binDistanceColor,
975 nr_shape_bins_, nr_color_bins_,
977 else if (b_describe_color_)
978 interpolateSingleChannel (indices, sqr_dists, index, binDistanceColor, nr_color_bins_, shot);
980 interpolateSingleChannel (indices, sqr_dists, index, binDistanceShape, nr_shape_bins_, shot);
983 this->normalizeHistogram (shot, descLength_);
987 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
void
989 const int index,
const std::vector<int> &indices,
const std::vector<float> &sqr_dists, Eigen::VectorXf &shot)
993 std::vector<double> binDistanceShape;
994 std::vector<double> binDistanceColor;
995 size_t nNeighbors = indices.size ();
999 PCL_WARN (
"[pcl::%s::computePointSHOT] Warning! Neighborhood has less than 5 vertexes. Aborting description of point with index %d\n",
1000 getClassName ().c_str (), (*indices_)[index]);
1002 shot.setConstant(descLength_, 1, std::numeric_limits<float>::quiet_NaN () );
1007 const PointRFT& current_frame = frames_->points[index];
1012 if (b_describe_shape_)
1014 binDistanceShape.resize (nNeighbors);
1016 for (
size_t i_idx = 0; i_idx < indices.size (); ++i_idx)
1019 double cosineDesc = normals_->points[indices[i_idx]].getNormalVector4fMap ().dot (current_frame.z_axis.getNormalVector4fMap ());
1021 if (cosineDesc > 1.0)
1023 if (cosineDesc < - 1.0)
1026 binDistanceShape[i_idx] = ((1.0 + cosineDesc) * nr_shape_bins_) / 2;
1031 if (b_describe_color_)
1033 binDistanceColor.resize (nNeighbors);
1038 unsigned char redRef = input_->points[(*indices_)[index]].r;
1039 unsigned char greenRef = input_->points[(*indices_)[index]].g;
1040 unsigned char blueRef = input_->points[(*indices_)[index]].b;
1042 float LRef, aRef, bRef;
1044 RGB2CIELAB (redRef, greenRef, blueRef, LRef, aRef, bRef);
1049 for (
size_t i_idx = 0; i_idx < indices.size (); ++i_idx)
1054 unsigned char red = surface_->points[indices[i_idx]].r;
1055 unsigned char green = surface_->points[indices[i_idx]].g;
1056 unsigned char blue = surface_->points[indices[i_idx]].b;
1060 RGB2CIELAB (red, green, blue, L, a, b);
1065 double colorDistance = (fabs (LRef - L) + ((fabs (aRef - a) + fabs (bRef - b)) / 2)) /3;
1067 if (colorDistance > 1.0)
1068 colorDistance = 1.0;
1069 if (colorDistance < 0.0)
1070 colorDistance = 0.0;
1072 binDistanceColor[i_idx] = colorDistance * nr_color_bins_;
1078 if (b_describe_shape_ && b_describe_color_)
1079 interpolateDoubleChannel (indices, sqr_dists, index, binDistanceShape, binDistanceColor,
1080 nr_shape_bins_, nr_color_bins_,
1082 else if (b_describe_color_)
1083 interpolateSingleChannel (indices, sqr_dists, index, binDistanceColor, nr_color_bins_, shot);
1085 interpolateSingleChannel (indices, sqr_dists, index, binDistanceShape, nr_shape_bins_, shot);
1088 this->normalizeHistogram (shot, descLength_);
1093 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intRFT>
void
1095 const int index,
const std::vector<int> &indices,
const std::vector<float> &sqr_dists, Eigen::VectorXf &shot)
1098 if (indices.size () < 5)
1100 PCL_WARN (
"[pcl::%s::computePointSHOT] Warning! Neighborhood has less than 5 vertexes. Aborting description of point with index %d\n",
1101 getClassName ().c_str (), (*indices_)[index]);
1103 shot.setConstant(descLength_, 1, std::numeric_limits<float>::quiet_NaN () );
1109 std::vector<double> binDistanceShape;
1110 this->createBinDistanceShape (index, indices, binDistanceShape);
1114 interpolateSingleChannel (indices, sqr_dists, index, binDistanceShape, nr_shape_bins_, shot);
1117 this->normalizeHistogram (shot, descLength_);
1121 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
void
1123 const int index,
const std::vector<int> &indices,
const std::vector<float> &sqr_dists, Eigen::VectorXf &shot)
1126 if (indices.size () < 5)
1128 PCL_WARN (
"[pcl::%s::computePointSHOT] Warning! Neighborhood has less than 5 vertexes. Aborting description of point with index %d\n",
1129 getClassName ().c_str (), (*indices_)[index]);
1131 shot.setConstant(descLength_, 1, std::numeric_limits<float>::quiet_NaN () );
1137 std::vector<double> binDistanceShape;
1138 this->createBinDistanceShape (index, indices, binDistanceShape);
1142 interpolateSingleChannel (indices, sqr_dists, index, binDistanceShape, nr_shape_bins_, shot);
1145 this->normalizeHistogram (shot, descLength_);
1179 template <
typename Po
intNT,
typename Po
intRFT>
void
1183 descLength_ = (b_describe_shape_) ? nr_grid_sector_*(nr_shape_bins_+1) : 0;
1184 descLength_ += (b_describe_color_) ? nr_grid_sector_*(nr_color_bins_+1) : 0;
1187 sqradius_ = search_radius_*search_radius_;
1188 radius3_4_ = (search_radius_*3) / 4;
1189 radius1_4_ = search_radius_ / 4;
1190 radius1_2_ = search_radius_ / 2;
1192 shot_.setZero (descLength_);
1195 for (
size_t idx = 0; idx < indices_->size (); ++idx)
1196 output.points[idx].descriptor.resize (descLength_);
1205 std::vector<int> nn_indices (k_);
1206 std::vector<float> nn_dists (k_);
1208 output.is_dense =
true;
1210 for (
size_t idx = 0; idx < indices_->size (); ++idx)
1212 bool lrf_is_nan =
false;
1213 const PointRFT& current_frame = (*frames_)[idx];
1218 PCL_WARN (
"[pcl::%s::computeFeature] The local reference frame is not valid! Aborting description of point with index %d\n",
1219 getClassName ().c_str (), (*indices_)[idx]);
1223 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
1225 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
1228 for (
int d = 0; d < shot_.size (); ++d)
1229 output.points[idx].descriptor[d] = std::numeric_limits<float>::quiet_NaN ();
1230 for (
int d = 0; d < 9; ++d)
1231 output.points[idx].rf[d] = std::numeric_limits<float>::quiet_NaN ();
1233 output.is_dense =
false;
1241 for (
int d = 0; d < shot_.size (); ++d)
1242 output.points[idx].descriptor[d] = shot_[d];
1243 for (
int d = 0; d < 9; ++d)
1244 output.points[idx].rf[d] = frames_->points[idx].rf[ (4*(d/3) + (d%3)) ];
1251 template <
typename Po
intNT,
typename Po
intRFT>
void
1255 descLength_ = (b_describe_shape_) ? nr_grid_sector_*(nr_shape_bins_+1) : 0;
1256 descLength_ += (b_describe_color_) ? nr_grid_sector_*(nr_color_bins_+1) : 0;
1259 output.
channels[
"shot"].name =
"shot";
1260 output.
channels[
"shot"].offset = 0;
1262 output.
channels[
"shot"].count = descLength_ + 9;
1266 sqradius_ = search_radius_*search_radius_;
1267 radius3_4_ = (search_radius_*3) / 4;
1268 radius1_4_ = search_radius_ / 4;
1269 radius1_2_ = search_radius_ / 2;
1271 shot_.setZero (descLength_);
1273 output.
points.resize (indices_->size (), descLength_ + 9);
1277 std::vector<int> nn_indices (k_);
1278 std::vector<float> nn_dists (k_);
1282 for (
size_t idx = 0; idx < indices_->size (); ++idx)
1284 bool lrf_is_nan =
false;
1285 const PointRFT& current_frame = (*frames_)[idx];
1290 PCL_WARN (
"[pcl::%s::computeFeature] The local reference frame is not valid! Aborting description of point with index %d\n",
1291 getClassName ().c_str (), (*indices_)[idx]);
1295 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
1297 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
1299 output.
points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
1306 this->
computePointSHOT (static_cast<int> (idx), nn_indices, nn_dists, shot_);
1309 for (
int d = 0; d < shot_.size (); ++d)
1310 output.
points (idx, d) = shot_[d];
1311 for (
int d = 0; d < 9; ++d)
1312 output.
points (idx, shot_.size () + d) = frames_->points[idx].rf[ (4*(d/3) + (d%3)) ];
1320 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intRFT>
void
1323 descLength_ = nr_grid_sector_ * (nr_shape_bins_+1);
1325 sqradius_ = search_radius_ * search_radius_;
1326 radius3_4_ = (search_radius_*3) / 4;
1327 radius1_4_ = search_radius_ / 4;
1328 radius1_2_ = search_radius_ / 2;
1330 shot_.setZero (descLength_);
1332 for (
size_t idx = 0; idx < indices_->size (); ++idx)
1333 output.
points[idx].descriptor.resize (descLength_);
1342 std::vector<int> nn_indices (k_);
1343 std::vector<float> nn_dists (k_);
1347 for (
size_t idx = 0; idx < indices_->size (); ++idx)
1349 bool lrf_is_nan =
false;
1350 const PointRFT& current_frame = (*frames_)[idx];
1355 PCL_WARN (
"[pcl::%s::computeFeature] The local reference frame is not valid! Aborting description of point with index %d\n",
1356 getClassName ().c_str (), (*indices_)[idx]);
1360 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
1362 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
1365 for (
int d = 0; d < shot_.size (); ++d)
1366 output.
points[idx].descriptor[d] = std::numeric_limits<float>::quiet_NaN ();
1367 for (
int d = 0; d < 9; ++d)
1368 output.
points[idx].rf[d] = std::numeric_limits<float>::quiet_NaN ();
1378 for (
int d = 0; d < shot_.size (); ++d)
1379 output.
points[idx].descriptor[d] = shot_[d];
1380 for (
int d = 0; d < 9; ++d)
1381 output.
points[idx].rf[d] = frames_->points[idx].rf[ (4*(d/3) + (d%3)) ];
1454 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
void
1457 descLength_ = nr_grid_sector_ * (nr_shape_bins_+1);
1459 sqradius_ = search_radius_ * search_radius_;
1460 radius3_4_ = (search_radius_*3) / 4;
1461 radius1_4_ = search_radius_ / 4;
1462 radius1_2_ = search_radius_ / 2;
1464 assert(descLength_ == 352);
1466 shot_.setZero (descLength_);
1470 std::vector<int> nn_indices (k_);
1471 std::vector<float> nn_dists (k_);
1475 for (
size_t idx = 0; idx < indices_->size (); ++idx)
1477 bool lrf_is_nan =
false;
1478 const PointRFT& current_frame = (*frames_)[idx];
1483 PCL_WARN (
"[pcl::%s::computeFeature] The local reference frame is not valid! Aborting description of point with index %d\n",
1484 getClassName ().c_str (), (*indices_)[idx]);
1488 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
1490 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
1493 for (
int d = 0; d < descLength_; ++d)
1494 output.
points[idx].descriptor[d] = std::numeric_limits<float>::quiet_NaN ();
1495 for (
int d = 0; d < 9; ++d)
1496 output.
points[idx].rf[d] = std::numeric_limits<float>::quiet_NaN ();
1506 for (
int d = 0; d < descLength_; ++d)
1507 output.
points[idx].descriptor[d] = shot_[d];
1508 for (
int d = 0; d < 9; ++d)
1509 output.
points[idx].rf[d] = frames_->points[idx].rf[ (4*(d/3) + (d%3)) ];
1516 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intRFT>
void
1519 descLength_ = nr_grid_sector_ * (nr_shape_bins_+1);
1522 output.
channels[
"shot"].name =
"shot";
1523 output.
channels[
"shot"].offset = 0;
1525 output.
channels[
"shot"].count = descLength_ + 9;
1528 sqradius_ = search_radius_ * search_radius_;
1529 radius3_4_ = (search_radius_*3) / 4;
1530 radius1_4_ = search_radius_ / 4;
1531 radius1_2_ = search_radius_ / 2;
1533 shot_.setZero (descLength_);
1535 output.
points.resize (indices_->size (), descLength_ + 9);
1539 std::vector<int> nn_indices (k_);
1540 std::vector<float> nn_dists (k_);
1544 for (
size_t idx = 0; idx < indices_->size (); ++idx)
1546 bool lrf_is_nan =
false;
1547 const PointRFT& current_frame = (*frames_)[idx];
1552 PCL_WARN (
"[pcl::%s::computeFeature] The local reference frame is not valid! Aborting description of point with index %d\n",
1553 getClassName ().c_str (), (*indices_)[idx]);
1557 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
1559 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
1561 output.
points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
1568 this->
computePointSHOT (static_cast<int> (idx), nn_indices, nn_dists, shot_);
1571 for (
int d = 0; d < descLength_; ++d)
1572 output.
points (idx, d) = shot_[d];
1573 for (
int d = 0; d < 9; ++d)
1574 output.
points (idx, shot_.size () + d) = frames_->points[idx].rf[ (4*(d/3) + (d%3)) ];
1581 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT,
typename Po
intRFT>
void
1585 descLength_ = (b_describe_shape_) ? nr_grid_sector_*(nr_shape_bins_+1) : 0;
1586 descLength_ += (b_describe_color_) ? nr_grid_sector_*(nr_color_bins_+1) : 0;
1588 assert( (!b_describe_color_ && b_describe_shape_ && descLength_ == 352) ||
1589 (b_describe_color_ && !b_describe_shape_ && descLength_ == 992) ||
1590 (b_describe_color_ && b_describe_shape_ && descLength_ == 1344)
1594 sqradius_ = search_radius_*search_radius_;
1595 radius3_4_ = (search_radius_*3) / 4;
1596 radius1_4_ = search_radius_ / 4;
1597 radius1_2_ = search_radius_ / 2;
1599 shot_.setZero (descLength_);
1603 std::vector<int> nn_indices (k_);
1604 std::vector<float> nn_dists (k_);
1608 for (
size_t idx = 0; idx < indices_->size (); ++idx)
1610 bool lrf_is_nan =
false;
1611 const PointRFT& current_frame = (*frames_)[idx];
1616 PCL_WARN (
"[pcl::%s::computeFeature] The local reference frame is not valid! Aborting description of point with index %d\n",
1617 getClassName ().c_str (), (*indices_)[idx]);
1621 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
1623 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
1626 for (
int d = 0; d < descLength_; ++d)
1627 output.
points[idx].descriptor[d] = std::numeric_limits<float>::quiet_NaN ();
1628 for (
int d = 0; d < 9; ++d)
1629 output.
points[idx].rf[d] = std::numeric_limits<float>::quiet_NaN ();
1639 for (
int d = 0; d < descLength_; ++d)
1640 output.
points[idx].descriptor[d] = shot_[d];
1641 for (
int d = 0; d < 9; ++d)
1642 output.
points[idx].rf[d] = frames_->points[idx].rf[ (4*(d/3) + (d%3)) ];
1649 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intRFT>
void
1653 descLength_ = (b_describe_shape_) ? nr_grid_sector_*(nr_shape_bins_+1) : 0;
1654 descLength_ += (b_describe_color_) ? nr_grid_sector_*(nr_color_bins_+1) : 0;
1657 output.
channels[
"shot"].name =
"shot";
1658 output.
channels[
"shot"].offset = 0;
1660 output.
channels[
"shot"].count = descLength_ + 9;
1664 sqradius_ = search_radius_*search_radius_;
1665 radius3_4_ = (search_radius_*3) / 4;
1666 radius1_4_ = search_radius_ / 4;
1667 radius1_2_ = search_radius_ / 2;
1669 shot_.setZero (descLength_);
1671 output.
points.resize (indices_->size (), descLength_ + 9);
1675 std::vector<int> nn_indices (k_);
1676 std::vector<float> nn_dists (k_);
1680 for (
size_t idx = 0; idx < indices_->size (); ++idx)
1682 bool lrf_is_nan =
false;
1683 const PointRFT& current_frame = (*frames_)[idx];
1688 PCL_WARN (
"[pcl::%s::computeFeature] The local reference frame is not valid! Aborting description of point with index %d\n",
1689 getClassName ().c_str (), (*indices_)[idx]);
1693 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
1695 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
1697 output.
points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
1704 this->
computePointSHOT (static_cast<int> (idx), nn_indices, nn_dists, shot_);
1707 for (
int d = 0; d < descLength_; ++d)
1708 output.
points (idx, d) = shot_[d];
1709 for (
int d = 0; d < 9; ++d)
1710 output.
points (idx, shot_.size () + d) = frames_->points[idx].rf[ (4*(d/3) + (d%3)) ];
1714 #define PCL_INSTANTIATE_SHOTEstimationBase(T,NT,OutT,RFT) template class PCL_EXPORTS pcl::SHOTEstimationBase<T,NT,OutT,RFT>;
1715 #define PCL_INSTANTIATE_SHOTEstimation(T,NT,OutT,RFT) template class PCL_EXPORTS pcl::SHOTEstimation<T,NT,OutT,RFT>;
1716 #define PCL_INSTANTIATE_SHOTColorEstimation(T,NT,OutT,RFT) template class PCL_EXPORTS pcl::SHOTColorEstimation<T,NT,OutT,RFT>;
1718 #endif // PCL_FEATURES_IMPL_SHOT_H_