37 #ifndef PCL_FEATURES_IMPL_SHOT_LRF_H_
38 #define PCL_FEATURES_IMPL_SHOT_LRF_H_
45 template<
typename Po
intInT,
typename Po
intOutT>
float
48 const Eigen::Vector4f& central_point = (*input_)[current_point_idx].getVector4fMap ();
49 std::vector<int> n_indices;
50 std::vector<float> n_sqr_distances;
52 this->searchForNeighbors (current_point_idx, search_parameter_, n_indices, n_sqr_distances);
54 Eigen::Matrix<double, Eigen::Dynamic, 4> vij (n_indices.size (), 4);
56 Eigen::Matrix3d cov_m = Eigen::Matrix3d::Zero ();
61 int valid_nn_points = 0;
63 for (
size_t i_idx = 0; i_idx < n_indices.size (); ++i_idx)
65 Eigen::Vector4f pt = surface_->points[n_indices[i_idx]].getVector4fMap ();
66 if (pt.head<3> () == central_point.head<3> ())
70 vij.row (valid_nn_points) = (pt - central_point).cast<double> ();
71 vij (valid_nn_points, 3) = 0;
73 distance = search_parameter_ -
sqrt (n_sqr_distances[i_idx]);
76 cov_m += distance * (vij.row (valid_nn_points).head<3> ().transpose () * vij.row (valid_nn_points).head<3> ());
82 if (valid_nn_points < 5)
85 rf.setConstant (std::numeric_limits<float>::quiet_NaN ());
87 return (std::numeric_limits<float>::max ());
92 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> solver (cov_m);
94 const double& e1c = solver.eigenvalues ()[0];
95 const double& e2c = solver.eigenvalues ()[1];
96 const double& e3c = solver.eigenvalues ()[2];
101 rf.setConstant (std::numeric_limits<float>::quiet_NaN ());
103 return (std::numeric_limits<float>::max ());
107 Eigen::Vector4d v1 = Eigen::Vector4d::Zero ();
108 Eigen::Vector4d v3 = Eigen::Vector4d::Zero ();
109 v1.head<3> () = solver.eigenvectors ().col (2);
110 v3.head<3> () = solver.eigenvectors ().col (0);
112 int plusNormal = 0, plusTangentDirection1=0;
113 for (
int ne = 0; ne < valid_nn_points; ne++)
115 double dp = vij.row (ne).dot (v1);
117 plusTangentDirection1++;
119 dp = vij.row (ne).dot (v3);
125 plusTangentDirection1 = 2*plusTangentDirection1 - valid_nn_points;
126 if (plusTangentDirection1 == 0)
129 int medianIndex = valid_nn_points/2;
131 for (
int i = -points/2; i <= points/2; i++)
132 if ( vij.row (medianIndex - i).dot (v1) > 0)
133 plusTangentDirection1 ++;
135 if (plusTangentDirection1 < points/2+1)
137 }
else if (plusTangentDirection1 < 0)
141 plusNormal = 2*plusNormal - valid_nn_points;
145 int medianIndex = valid_nn_points/2;
147 for (
int i = -points/2; i <= points/2; i++)
148 if ( vij.row (medianIndex - i).dot (v3) > 0)
151 if (plusNormal < points/2+1)
153 }
else if (plusNormal < 0)
156 rf.row (0) = v1.head<3> ().cast<float> ();
157 rf.row (2) = v3.head<3> ().cast<float> ();
158 rf.row (1) = rf.row (2).cross (rf.row (0));
163 template <
typename Po
intInT,
typename Po
intOutT>
void
167 if (this->getKSearch () != 0)
170 "[pcl::%s::computeFeature] Error! Search method set to k-neighborhood. Call setKSearch(0) and setRadiusSearch( radius ) to use this class.\n",
171 getClassName().c_str ());
174 tree_->setSortedResults (
true);
176 for (
size_t i = 0; i < indices_->size (); ++i)
180 PointOutT& output_rf = output[i];
184 if (getLocalRF ((*indices_)[i], rf) == std::numeric_limits<float>::max ())
186 output.is_dense =
false;
189 output_rf.x_axis.getNormalVector3fMap () = rf.row (0);
190 output_rf.y_axis.getNormalVector3fMap () = rf.row (1);
191 output_rf.z_axis.getNormalVector3fMap () = rf.row (2);
196 template <
typename Po
intInT,
typename Po
intOutT>
void
200 if (this->getKSearch () != 0)
203 "[pcl::%s::computeFeatureEigen] Error! Search method set to k-neighborhood. Call setKSearch(0) and setRadiusSearch( radius ) to use this class.\n",
204 getClassName().c_str ());
207 tree_->setSortedResults (
true);
210 output.
channels[
"shot_lrf"].name =
"shot_lrf";
211 output.
channels[
"shot_lrf"].offset = 0;
212 output.
channels[
"shot_lrf"].size = 4;
213 output.
channels[
"shot_lrf"].count = 9;
217 output.
points.resize (indices_->size (), 9);
218 for (
size_t i = 0; i < indices_->size (); ++i)
225 if (getLocalRF ((*indices_)[i], rf) == std::numeric_limits<float>::max ())
230 output.
points.block<1, 3> (i, 0) = rf.row (0);
231 output.
points.block<1, 3> (i, 3) = rf.row (1);
232 output.
points.block<1, 3> (i, 6) = rf.row (2);
237 #define PCL_INSTANTIATE_SHOTLocalReferenceFrameEstimation(T,OutT) template class PCL_EXPORTS pcl::SHOTLocalReferenceFrameEstimation<T,OutT>;
239 #endif // PCL_FEATURES_IMPL_SHOT_LRF_H_