41 #ifndef PCL_FEATURES_IMPL_RIFT_H_
42 #define PCL_FEATURES_IMPL_RIFT_H_
44 #include <pcl/features/rift.h>
49 template <
typename Po
intInT,
typename GradientT,
typename Po
intOutT>
void
53 const std::vector<float> &sqr_distances, Eigen::MatrixXf &rift_descriptor)
57 PCL_ERROR (
"[pcl::RIFTEstimation] Null indices points passed!\n");
62 int nr_distance_bins =
static_cast<int> (rift_descriptor.rows ());
63 int nr_gradient_bins =
static_cast<int> (rift_descriptor.cols ());
66 const Eigen::Map<const Eigen::Vector3f> p0 = cloud[p_idx].getVector3fMap ();
69 rift_descriptor.setZero ();
70 for (std::size_t idx = 0; idx < indices.size (); ++idx)
73 const Eigen::Map<const Eigen::Vector3f> point = cloud[indices[idx]].getVector3fMap ();
74 Eigen::Map<const Eigen::Vector3f> gradient_vector (& (gradient[indices[idx]].gradient[0]));
76 float gradient_magnitude = gradient_vector.norm ();
77 float gradient_angle_from_center = std::acos (gradient_vector.dot ((point - p0).normalized ()) / gradient_magnitude);
78 if (!std::isfinite (gradient_angle_from_center))
79 gradient_angle_from_center = 0.0;
82 const float eps = std::numeric_limits<float>::epsilon ();
83 float d =
static_cast<float> (nr_distance_bins) * std::sqrt (sqr_distances[idx]) / (radius + eps);
84 float g =
static_cast<float> (nr_gradient_bins) * gradient_angle_from_center / (
static_cast<float> (
M_PI) + eps);
87 int d_idx_min = (std::max)(
static_cast<int> (std::ceil (d - 1)), 0);
88 int d_idx_max = (std::min)(
static_cast<int> (std::floor (d + 1)), nr_distance_bins - 1);
89 int g_idx_min =
static_cast<int> (std::ceil (g - 1));
90 int g_idx_max =
static_cast<int> (std::floor (g + 1));
93 for (
int g_idx = g_idx_min; g_idx <= g_idx_max; ++g_idx)
96 int g_idx_wrapped = ((g_idx + nr_gradient_bins) % nr_gradient_bins);
98 for (
int d_idx = d_idx_min; d_idx <= d_idx_max; ++d_idx)
101 float w = (1.0f - std::abs (d -
static_cast<float> (d_idx))) * (1.0f - std::abs (g -
static_cast<float> (g_idx)));
103 rift_descriptor (d_idx, g_idx_wrapped) += w * gradient_magnitude;
109 rift_descriptor.normalize ();
114 template <
typename Po
intInT,
typename GradientT,
typename Po
intOutT>
void
118 if (search_radius_ == 0.0)
120 PCL_ERROR (
"[pcl::%s::computeFeature] The search radius must be set before computing the feature!\n",
121 getClassName ().c_str ());
128 if (nr_gradient_bins_ <= 0)
130 PCL_ERROR (
"[pcl::%s::computeFeature] The number of gradient bins must be greater than zero!\n",
131 getClassName ().c_str ());
136 if (nr_distance_bins_ <= 0)
138 PCL_ERROR (
"[pcl::%s::computeFeature] The number of distance bins must be greater than zero!\n",
139 getClassName ().c_str ());
148 PCL_ERROR (
"[pcl::%s::computeFeature] No input gradient was given!\n", getClassName ().c_str ());
153 if (gradient_->size () != surface_->size ())
155 PCL_ERROR (
"[pcl::%s::computeFeature] ", getClassName ().c_str ());
156 PCL_ERROR (
"The number of points in the input dataset differs from the number of points in the gradient!\n");
162 Eigen::MatrixXf rift_descriptor (nr_distance_bins_, nr_gradient_bins_);
164 std::vector<float> nn_dist_sqr;
167 for (std::size_t idx = 0; idx < indices_->size (); ++idx)
170 tree_->radiusSearch ((*indices_)[idx], search_radius_, nn_indices, nn_dist_sqr);
173 computeRIFT (*surface_, *gradient_, (*indices_)[idx],
static_cast<float> (search_radius_), nn_indices, nn_dist_sqr, rift_descriptor);
176 std::copy (rift_descriptor.data (), rift_descriptor.data () + rift_descriptor.size (), output[idx].histogram);
180 #define PCL_INSTANTIATE_RIFTEstimation(T,NT,OutT) template class PCL_EXPORTS pcl::RIFTEstimation<T,NT,OutT>;
std::uint32_t width
The point cloud width (if organized as an image-structure).
std::uint32_t height
The point cloud height (if organized as an image-structure).
void clear()
Removes all points in a cloud and sets the width and height to 0.
void computeFeature(PointCloudOut &output) override
Estimate the Rotation Invariant Feature Transform (RIFT) descriptors at a set of points given by <set...
void computeRIFT(const PointCloudIn &cloud, const PointCloudGradient &gradient, int p_idx, float radius, const pcl::Indices &indices, const std::vector< float > &squared_distances, Eigen::MatrixXf &rift_descriptor)
Estimate the Rotation Invariant Feature Transform (RIFT) descriptor for a given point based on its sp...
IndicesAllocator<> Indices
Type used for indices in PCL.