00001
00063 #ifndef __IMPL_ORGANIZED_CURVATURE_ESTIMATION_H__
00064 #define __IMPL_ORGANIZED_CURVATURE_ESTIMATION_H__
00065
00066 #include <pcl/common/eigen.h>
00067 #include "cob_3d_features/organized_curvature_estimation.h"
00068
00069 template <typename PointInT, typename PointNT, typename PointLabelT, typename PointOutT> void
00070 cob_3d_features::OrganizedCurvatureEstimation<PointInT,PointNT,PointLabelT,PointOutT>::computePointCurvatures (
00071 const NormalCloudIn &normals,
00072 const int index,
00073 const std::vector<int> &indices,
00074 float &pcx, float &pcy, float &pcz, float &pc1, float &pc2,
00075 int &label_out)
00076 {
00077 std::vector<float> weights(indices.size(),1.0f);
00078 computePointCurvatures(normals, index, indices, weights, pcx, pcy, pcz, pc1, pc2, label_out);
00079 }
00080
00081
00082 template <typename PointInT, typename PointNT, typename PointLabelT, typename PointOutT> void
00083 cob_3d_features::OrganizedCurvatureEstimation<PointInT,PointNT,PointLabelT,PointOutT>::computePointCurvatures (
00084 const NormalCloudIn &normals,
00085 const int index,
00086 const std::vector<int> &indices,
00087 const std::vector<float> &sqr_distances,
00088 float &pcx, float &pcy, float &pcz, float &pc1, float &pc2,
00089 int &label_out)
00090 {
00091 Eigen::Vector3f n_idx(normals.points[index].normal);
00092 Eigen::Matrix3f M = Eigen::Matrix3f::Identity() - n_idx * n_idx.transpose();
00093
00094 std::vector<Eigen::Vector3f> normals_projected;
00095 normals_projected.reserve(n_points_);
00096 Eigen::Vector3f centroid = Eigen::Vector3f::Zero();
00097 Eigen::Vector3f p_idx = surface_->points[index].getVector3fMap();
00098 float angle = 0.0;
00099 int prob_concave = 0, prob_convex = 0;
00100 for (std::vector<int>::const_iterator it = indices.begin(); it != indices.end(); ++it)
00101 {
00102 PointNT const* n_i = &(normals.points[*it]);
00103 if ( pcl_isnan(n_i->normal[2]) ) continue;
00104 normals_projected.push_back( M * Eigen::Vector3f(n_i->normal) );
00105 centroid += normals_projected.back();
00106 if ( (surface_->points[*it].getVector3fMap() - p_idx).normalized().dot(n_idx) > 0.0) ++prob_concave;
00107 else ++prob_convex;
00108 }
00109
00110 if (normals_projected.size() <=1) return;
00111 float num_p_inv = 1.0f / normals_projected.size();
00112 centroid *= num_p_inv;
00113
00114 Eigen::Matrix3f cov = Eigen::Matrix3f::Zero();
00115 {
00116 std::vector<Eigen::Vector3f>::iterator n_it = normals_projected.begin();
00117 std::vector<float>::const_iterator d_it = sqr_distances.begin();
00118 for (; n_it != normals_projected.end(); ++n_it, ++d_it)
00119 {
00120 Eigen::Vector3f demean = *n_it - centroid;
00121
00122 cov += demean * demean.transpose();
00123 }
00124 }
00125
00126 Eigen::Vector3f eigenvalues;
00127 Eigen::Matrix3f eigenvectors;
00128 pcl::eigen33(cov, eigenvectors, eigenvalues);
00129 pcx = eigenvectors (0,2);
00130 pcy = eigenvectors (1,2);
00131 pcz = eigenvectors (2,2);
00132 if (prob_concave < prob_convex)
00133 num_p_inv *= surface_->points[index].z * (-1);
00134
00135 else
00136 num_p_inv *= surface_->points[index].z;
00137
00138 pc1 = eigenvalues (2) * num_p_inv;
00139 pc2 = eigenvalues (1) * num_p_inv;
00140
00141 if (std::abs(pc1) >= edge_curvature_threshold_ && label_out == 0)
00142 label_out = I_EDGE;
00143 }
00144
00145
00146 template <typename PointInT, typename PointNT, typename PointLabelT, typename PointOutT> void
00147 cob_3d_features::OrganizedCurvatureEstimation<PointInT,PointNT,PointLabelT,PointOutT>::computeFeature (PointCloudOut &output)
00148 {
00149 if (labels_->points.size() != input_->size())
00150 {
00151 labels_->points.resize(input_->size());
00152 labels_->height = input_->height;
00153 labels_->width = input_->width;
00154 }
00155 if (output.points.size() != input_->size())
00156 {
00157 output.points.resize(input_->size());
00158 output.height = input_->height;
00159 output.width = input_->width;
00160 }
00161
00162 std::vector<int> nn_indices;
00163 std::vector<float> nn_distances;
00164
00165 for (std::vector<int>::iterator it=indices_->begin(); it != indices_->end(); ++it)
00166 {
00167 if (pcl_isnan(surface_->points[*it].z) ||
00168 pcl_isnan(normals_->points[*it].normal[2]))
00169 {
00170 labels_->points[*it].label = I_NAN;
00171 }
00172 else if (this->searchForNeighborsInRange(*it, nn_indices, nn_distances) != -1)
00173 {
00174 computePointCurvatures(*normals_, *it, nn_indices, nn_distances,
00175 output.points[*it].principal_curvature[0],
00176 output.points[*it].principal_curvature[1],
00177 output.points[*it].principal_curvature[2],
00178 output.points[*it].pc1,
00179 output.points[*it].pc2,
00180 labels_->points[*it].label);
00181 }
00182 else
00183 {
00184 labels_->points[*it].label = I_NAN;
00185 }
00186 }
00187 }
00188
00189 #define PCL_INSTANTIATE_OrganizedCurvatureEstimation(T,NT,LabelT,OutT) template class PCL_EXPORTS cob_3d_features::OrganizedCurvatureEstimation<T,NT,LabelT,OutT>;
00190
00191
00192 #endif