40 #ifndef PCL_FEATURES_IMPL_INTENSITY_SPIN_H_
41 #define PCL_FEATURES_IMPL_INTENSITY_SPIN_H_
46 template <
typename Po
intInT,
typename Po
intOutT>
void
50 const std::vector<int> &indices,
51 const std::vector<float> &squared_distances,
52 Eigen::MatrixXf &intensity_spin_image)
55 int nr_distance_bins =
static_cast<int> (intensity_spin_image.cols ());
56 int nr_intensity_bins =
static_cast<int> (intensity_spin_image.rows ());
59 float min_intensity = std::numeric_limits<float>::max ();
60 float max_intensity = std::numeric_limits<float>::min ();
61 for (
int idx = 0; idx < k; ++idx)
63 min_intensity = (std::min) (min_intensity, cloud.
points[indices[idx]].intensity);
64 max_intensity = (std::max) (max_intensity, cloud.
points[indices[idx]].intensity);
67 float constant = 1.0f / (2.0f * sigma_ * sigma_);
69 intensity_spin_image.setZero ();
70 for (
int idx = 0; idx < k; ++idx)
73 const float eps = std::numeric_limits<float>::epsilon ();
74 float d =
static_cast<float> (nr_distance_bins) * sqrtf (squared_distances[idx]) / (radius + eps);
75 float i =
static_cast<float> (nr_intensity_bins) *
76 (cloud.
points[indices[idx]].intensity - min_intensity) / (max_intensity - min_intensity + eps);
81 int d_idx =
static_cast<int> (d);
82 int i_idx =
static_cast<int> (i);
83 intensity_spin_image (i_idx, d_idx) += 1;
88 int d_idx_min = (std::max)(static_cast<int> (floor (d - 3*sigma)), 0);
89 int d_idx_max = (std::min)(static_cast<int> (ceil (d + 3*sigma)), nr_distance_bins - 1);
90 int i_idx_min = (std::max)(static_cast<int> (floor (i - 3*sigma)), 0);
91 int i_idx_max = (std::min)(static_cast<int> (ceil (i + 3*sigma)), nr_intensity_bins - 1);
94 for (
int i_idx = i_idx_min; i_idx <= i_idx_max; ++i_idx)
96 for (
int d_idx = d_idx_min; d_idx <= d_idx_max; ++d_idx)
99 float w = expf (-powf (d - static_cast<float> (d_idx), 2.0f) * constant - powf (i - static_cast<float> (i_idx), 2.0f) * constant);
100 intensity_spin_image (i_idx, d_idx) += w;
108 template <
typename Po
intInT,
typename Po
intOutT>
void
112 if (search_radius_ == 0.0)
114 PCL_ERROR (
"[pcl::%s::computeFeature] The search radius must be set before computing the feature!\n",
115 getClassName ().c_str ());
122 if (nr_intensity_bins_ <= 0)
124 PCL_ERROR (
"[pcl::%s::computeFeature] The number of intensity bins must be greater than zero!\n",
125 getClassName ().c_str ());
130 if (nr_distance_bins_ <= 0)
132 PCL_ERROR (
"[pcl::%s::computeFeature] The number of distance bins must be greater than zero!\n",
133 getClassName ().c_str ());
139 Eigen::MatrixXf intensity_spin_image (nr_intensity_bins_, nr_distance_bins_);
141 std::vector<int> nn_indices (surface_->points.size ());
142 std::vector<float> nn_dist_sqr (surface_->points.size ());
146 for (
size_t idx = 0; idx < indices_->size (); ++idx)
150 int k = tree_->radiusSearch ((*indices_)[idx], search_radius_, nn_indices, nn_dist_sqr);
153 for (
int bin = 0; bin < nr_intensity_bins_ * nr_distance_bins_; ++bin)
154 output.
points[idx].histogram[bin] = std::numeric_limits<float>::quiet_NaN ();
160 computeIntensitySpinImage (*surface_, static_cast<float> (search_radius_), sigma_, k, nn_indices, nn_dist_sqr, intensity_spin_image);
164 for (
int bin_j = 0; bin_j < intensity_spin_image.cols (); ++bin_j)
165 for (
int bin_i = 0; bin_i < intensity_spin_image.rows (); ++bin_i)
166 output.
points[idx].histogram[bin++] = intensity_spin_image (bin_i, bin_j);
171 template <
typename Po
intInT>
void
177 if (search_radius_ == 0.0)
179 PCL_ERROR (
"[pcl::%s::computeFeature] The search radius must be set before computing the feature!\n",
180 getClassName ().c_str ());
182 output.
points.resize (0, 0);
189 PCL_ERROR (
"[pcl::%s::computeFeature] The number of intensity bins must be greater than zero!\n",
190 getClassName ().c_str ());
192 output.
points.resize (0, 0);
197 PCL_ERROR (
"[pcl::%s::computeFeature] The number of distance bins must be greater than zero!\n",
198 getClassName ().c_str ());
200 output.
points.resize (0, 0);
208 std::vector<int> nn_indices;
209 std::vector<float> nn_dist_sqr;
213 for (
size_t idx = 0; idx < indices_->size (); ++idx)
216 int k = tree_->radiusSearch ((*indices_)[idx], search_radius_, nn_indices, nn_dist_sqr);
219 output.
points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
229 for (
int bin_j = 0; bin_j < intensity_spin_image.cols (); ++bin_j)
230 for (
int bin_i = 0; bin_i < intensity_spin_image.rows (); ++bin_i)
231 output.
points (idx, bin++) = intensity_spin_image (bin_i, bin_j);
236 #define PCL_INSTANTIATE_IntensitySpinEstimation(T,NT) template class PCL_EXPORTS pcl::IntensitySpinEstimation<T,NT>;
238 #endif // PCL_FEATURES_IMPL_INTENSITY_SPIN_H_