40 #ifndef PCL_FEATURES_IMPL_PFH_H_
41 #define PCL_FEATURES_IMPL_PFH_H_
46 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
bool
49 int p_idx,
int q_idx,
float &f1,
float &f2,
float &f3,
float &f4)
52 cloud.
points[q_idx].getVector4fMap (), normals.
points[q_idx].getNormalVector4fMap (),
58 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
void
61 const std::vector<int> &indices,
int nr_split, Eigen::VectorXf &pfh_histogram)
66 pfh_histogram.setZero ();
69 float hist_incr = 100.0f /
static_cast<float> (indices.size () * (indices.size () - 1) / 2);
71 std::pair<int, int> key;
73 for (
size_t i_idx = 0; i_idx < indices.size (); ++i_idx)
75 for (
size_t j_idx = 0; j_idx < i_idx; ++j_idx)
95 key = std::pair<int, int> (p1, p2);
98 std::map<std::pair<int, int>, Eigen::Vector4f, std::less<std::pair<int, int> >, Eigen::aligned_allocator<Eigen::Vector4f> >::iterator fm_it = feature_map_.find (key);
99 if (fm_it != feature_map_.end ())
100 pfh_tuple_ = fm_it->second;
105 pfh_tuple_[0], pfh_tuple_[1], pfh_tuple_[2], pfh_tuple_[3]))
111 pfh_tuple_[0], pfh_tuple_[1], pfh_tuple_[2], pfh_tuple_[3]))
115 f_index_[0] =
static_cast<int> (floor (nr_split * ((pfh_tuple_[0] + M_PI) * d_pi_)));
116 if (f_index_[0] < 0) f_index_[0] = 0;
117 if (f_index_[0] >= nr_split) f_index_[0] = nr_split - 1;
119 f_index_[1] =
static_cast<int> (floor (nr_split * ((pfh_tuple_[1] + 1.0) * 0.5)));
120 if (f_index_[1] < 0) f_index_[1] = 0;
121 if (f_index_[1] >= nr_split) f_index_[1] = nr_split - 1;
123 f_index_[2] =
static_cast<int> (floor (nr_split * ((pfh_tuple_[2] + 1.0) * 0.5)));
124 if (f_index_[2] < 0) f_index_[2] = 0;
125 if (f_index_[2] >= nr_split) f_index_[2] = nr_split - 1;
130 for (
int d = 0; d < 3; ++d)
132 h_index += h_p * f_index_[d];
135 pfh_histogram[h_index] += hist_incr;
140 feature_map_[key] = pfh_tuple_;
143 key_list_.push (key);
145 if (key_list_.size () > max_cache_size_)
148 feature_map_.erase (key_list_.back ());
157 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
void
161 feature_map_.clear ();
162 std::queue<std::pair<int, int> > empty;
163 std::swap (key_list_, empty);
165 pfh_histogram_.setZero (nr_subdiv_ * nr_subdiv_ * nr_subdiv_);
169 std::vector<int> nn_indices (k_);
170 std::vector<float> nn_dists (k_);
172 output.is_dense =
true;
174 if (input_->is_dense)
177 for (
size_t idx = 0; idx < indices_->size (); ++idx)
179 if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
181 for (
int d = 0; d < pfh_histogram_.size (); ++d)
182 output.points[idx].histogram[d] = std::numeric_limits<float>::quiet_NaN ();
184 output.is_dense =
false;
189 computePointPFHSignature (*surface_, *normals_, nn_indices, nr_subdiv_, pfh_histogram_);
192 for (
int d = 0; d < pfh_histogram_.size (); ++d)
193 output.points[idx].histogram[d] = pfh_histogram_[d];
199 for (
size_t idx = 0; idx < indices_->size (); ++idx)
201 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
202 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
204 for (
int d = 0; d < pfh_histogram_.size (); ++d)
205 output.points[idx].histogram[d] = std::numeric_limits<float>::quiet_NaN ();
207 output.is_dense =
false;
212 computePointPFHSignature (*surface_, *normals_, nn_indices, nr_subdiv_, pfh_histogram_);
215 for (
int d = 0; d < pfh_histogram_.size (); ++d)
216 output.points[idx].histogram[d] = pfh_histogram_[d];
222 template <
typename Po
intInT,
typename Po
intNT>
void
226 output.
channels[
"pfh"].name =
"pfh";
229 output.
channels[
"pfh"].count = nr_subdiv_ * nr_subdiv_ * nr_subdiv_;
233 feature_map_.clear ();
234 std::queue<std::pair<int, int> > empty;
235 std::swap (key_list_, empty);
236 pfh_histogram_.setZero (nr_subdiv_ * nr_subdiv_ * nr_subdiv_);
239 output.
points.resize (indices_->size (), nr_subdiv_ * nr_subdiv_ * nr_subdiv_);
241 std::vector<int> nn_indices (k_);
242 std::vector<float> nn_dists (k_);
246 if (input_->is_dense)
249 for (
size_t idx = 0; idx < indices_->size (); ++idx)
251 if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
253 output.
points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
260 output.
points.row (idx) = pfh_histogram_;
266 for (
size_t idx = 0; idx < indices_->size (); ++idx)
268 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
269 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
271 output.
points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
278 output.
points.row (idx) = pfh_histogram_;
283 #define PCL_INSTANTIATE_PFHEstimation(T,NT,OutT) template class PCL_EXPORTS pcl::PFHEstimation<T,NT,OutT>;
285 #endif // PCL_FEATURES_IMPL_PFH_H_