137 Eigen::Map<Eigen::Vector3f> x_axis (rf);
138 Eigen::Map<Eigen::Vector3f> y_axis (rf + 3);
139 Eigen::Map<Eigen::Vector3f> normal (rf + 6);
143 std::vector<float> nn_dists;
147 std::fill (desc.begin (), desc.end (), std::numeric_limits<float>::quiet_NaN ());
148 std::fill_n (rf, 9, 0.f);
152 const auto minDistanceIt = std::min_element(nn_dists.begin (), nn_dists.end ());
153 const auto minIndex = nn_indices[std::distance (nn_dists.begin (), minDistanceIt)];
161 std::fill (desc.begin (), desc.end (), std::numeric_limits<float>::quiet_NaN ());
162 std::fill (rf, rf + 9, 0.f);
165 normal = normals[minIndex].getNormalVector3fMap ();
172 x_axis[2] = - (normal[0]*x_axis[0] + normal[1]*x_axis[1]) / normal[2];
174 x_axis[1] = - (normal[0]*x_axis[0] + normal[2]*x_axis[2]) / normal[1];
176 x_axis[0] = - (normal[1]*x_axis[1] + normal[2]*x_axis[2]) / normal[0];
181 assert (
pcl::utils::equal (x_axis[0]*normal[0] + x_axis[1]*normal[1] + x_axis[2]*normal[2], 0.0f, 1E-6f));
184 y_axis.matrix () = normal.cross (x_axis);
187 for (std::size_t ne = 0; ne < neighb_cnt; ne++)
192 Eigen::Vector3f neighbour = (*surface_)[nn_indices[ne]].getVector3fMap ();
196 float r = std::sqrt (nn_dists[ne]);
199 Eigen::Vector3f proj;
207 Eigen::Vector3f cross = x_axis.cross (proj);
208 float phi =
pcl::rad2deg (std::atan2 (cross.norm (), x_axis.dot (proj)));
209 phi = cross.dot (normal) < 0.f ? (360.0f - phi) : phi;
211 Eigen::Vector3f no = neighbour - origin;
213 float theta = normal.dot (no);
214 theta =
pcl::rad2deg (std::acos (std::min (1.0f, std::max (-1.0f, theta))));
222 const auto j = std::distance(
radii_interval_.cbegin (), std::prev(rad_min));
223 const auto k = std::distance(
theta_divisions_.cbegin (), std::prev(theta_min));
224 const auto l = std::distance(
phi_divisions_.cbegin (), std::prev(phi_min));
228 std::vector<float> neighbour_distances;
231 if (point_density == 0)
234 float w = (1.0f /
static_cast<float> (point_density)) *
238 if (w == std::numeric_limits<float>::infinity ())
239 PCL_ERROR (
"Shape Context Error INF!\n");
241 PCL_ERROR (
"Shape Context Error IND!\n");
249 std::fill_n (rf, 9, 0);
259 output.is_dense =
true;
261 for (std::size_t point_index = 0; point_index <
indices_->size (); point_index++)
269 std::numeric_limits<float>::quiet_NaN ());
270 std::fill_n (output[point_index].rf, 9, 0);
271 output.is_dense =
false;
277 output.is_dense =
false;
278 std::copy (descriptor.cbegin (), descriptor.cend (), output[point_index].descriptor);
bool computePoint(std::size_t index, const pcl::PointCloud< PointNT > &normals, float rf[9], std::vector< float > &desc)
Estimate a descriptor for a given point.
std::size_t azimuth_bins_
Bins along the azimuth dimension.
bool initCompute() override
Initialize computation by allocating all the intervals and the volume lookup table.
std::size_t radius_bins_
Bins along the radius dimension.
std::vector< float > radii_interval_
Values of the radii interval.
float rnd()
Boost-based random number generator.
typename Feature< PointInT, PointOutT >::PointCloudOut PointCloudOut
void computeFeature(PointCloudOut &output) override
Estimate the actual feature.
double point_density_radius_
Point density radius.
std::vector< float > volume_lut_
Volumes look up table.
std::size_t descriptor_length_
Descriptor length.
std::vector< float > theta_divisions_
Theta divisions interval.
std::vector< float > phi_divisions_
Phi divisions interval.
std::size_t elevation_bins_
Bins along the elevation dimension.