18 #include <Eigen/Eigenvalues>
31 bool IsLocalMaxima(
int query_idx,
32 const std::vector<int>& indices,
33 const std::vector<double>& third_eigen_values) {
34 for (
const auto& idx : indices) {
35 if (third_eigen_values[query_idx] < third_eigen_values[idx]) {
42 double ComputeModelResolution(
const std::vector<Eigen::Vector3d>&
points,
43 const geometry::KDTreeFlann& kdtree) {
44 std::vector<int> indices(2);
45 std::vector<double> distances(2);
46 double resolution = 0.0;
48 for (
const auto& point :
points) {
49 if (kdtree.SearchKNN(point, 2, indices, distances) != 0) {
50 resolution += std::sqrt(distances[1]);
53 resolution /=
points.size();
64 double salient_radius ,
65 double non_max_radius ,
71 "[ComputeISSKeypoints] Input ccPointCloud is empty!");
72 return std::make_shared<ccPointCloud>();
77 if (salient_radius == 0.0 || non_max_radius == 0.0) {
78 const double resolution = ComputeModelResolution(
points, kdtree);
79 salient_radius = 6 * resolution;
80 non_max_radius = 4 * resolution;
82 "[ComputeISSKeypoints] Computed salient_radius = {}, "
83 "non_max_radius = {} from input model",
84 salient_radius, non_max_radius);
87 std::vector<double> third_eigen_values(
points.size());
88 #pragma omp parallel for schedule(static) shared(third_eigen_values)
89 for (
int i = 0; i < (int)
points.size(); i++) {
90 std::vector<int> indices;
91 std::vector<double> dist;
94 if (nb_neighbors < min_neighbors) {
104 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> solver(cov);
105 const double& e1c = solver.eigenvalues()[2];
106 const double& e2c = solver.eigenvalues()[1];
107 const double& e3c = solver.eigenvalues()[0];
109 if ((e2c / e1c) < gamma_21 && e3c / e2c < gamma_32) {
110 third_eigen_values[i] = e3c;
114 std::vector<size_t> kp_indices;
115 kp_indices.reserve(
points.size());
116 #pragma omp parallel for schedule(static) shared(kp_indices)
117 for (
int i = 0; i < (int)
points.size(); i++) {
118 if (third_eigen_values[i] > 0.0) {
119 std::vector<int> nn_indices;
120 std::vector<double> dist;
124 if (nb_neighbors >= min_neighbors &&
125 IsLocalMaxima(i, nn_indices, third_eigen_values)) {
126 kp_indices.emplace_back(i);
132 "[ComputeISSKeypoints] Extracted {} keypoints", kp_indices.size());
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
virtual bool IsEmpty() const override
std::shared_ptr< ccPointCloud > SelectByIndex(const std::vector< size_t > &indices, bool invert=false) const
Function to select points from input ccPointCloud into output ccPointCloud.
std::vector< Eigen::Vector3d > getEigenPoints() const
KDTree with FLANN for nearest neighbor search.
int SearchRadius(const T &query, double radius, std::vector< int > &indices, std::vector< double > &distance2) const
std::shared_ptr< ccPointCloud > ComputeISSKeypoints(const ccPointCloud &input, double salient_radius=0.0, double non_max_radius=0.0, double gamma_21=0.975, double gamma_32=0.975, int min_neighbors=5)
Function that computes the ISS Keypoints from an input point cloud. This implements the keypoint dete...
Eigen::Matrix3d ComputeCovariance(const std::vector< Eigen::Vector3d > &points, const std::vector< IdxType > &indices)
Function to compute the covariance matrix of a set of points.
Generic file read and write utility for python interface.