Go to the documentation of this file.00001 #ifndef PCL_FEATURES_IMPL_CURVATURE_ESTIMATION_TAUBIN_HPP_
00002 #define PCL_FEATURES_IMPL_CURVATURE_ESTIMATION_TAUBIN_HPP_
00003
00004 #include "curvature_estimation_taubin.h"
00005
00006 template<typename PointInT, typename PointOutT> void pcl::CurvatureEstimationTaubin<PointInT, PointOutT>::computeFeature(
00007 const Eigen::MatrixXd &samples, PointCloudOut &output)
00008 {
00009 const double MIN_NEIGHBORS = 10;
00010
00011 this->time_taubin = 0.0;
00012 this->time_curvature = 0.0;
00013
00014
00015 std::vector<int> nn_indices;
00016 std::vector<float> nn_dists;
00017
00018
00019 output.is_dense = true;
00020
00021
00022 output.resize(samples.cols());
00023
00024
00025 neighborhoods_.resize(samples.cols());
00026 neighborhood_centroids_.resize(samples.cols());
00027
00028
00029 if (input_->isOrganized())
00030 {
00031 pcl::search::OrganizedNeighbor<PointXYZRGBA>::Ptr organized_neighbor(
00032 new pcl::search::OrganizedNeighbor<PointXYZRGBA>());
00033 organized_neighbor->setInputCloud(input_);
00034 pcl::PointXYZRGBA search_point;
00035
00036
00037 #ifdef _OPENMP
00038 #pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(num_threads_)
00039 #endif
00040
00041 for (int i = 0; i < samples.cols(); i++)
00042 {
00043 search_point.x = samples(0, i);
00044 search_point.y = samples(1, i);
00045 search_point.z = samples(2, i);
00046
00047
00048
00049 if (organized_neighbor->radiusSearch(search_point, search_radius_, nn_indices, nn_dists) < MIN_NEIGHBORS)
00050 {
00051 output.points[i].normal[0] = output.points[i].normal[1] = output.points[i].normal[2] =
00052 std::numeric_limits<float>::quiet_NaN();
00053 output.points[i].curvature_axis[0] = output.points[i].curvature_axis[1] = output.points[i].curvature_axis[2] =
00054 output.points[i].normal[0];
00055 output.points[i].curvature_centroid[0] = output.points[i].curvature_centroid[1] =
00056 output.points[i].curvature_centroid[2] = output.points[i].normal[0];
00057 output.points[i].median_curvature = output.points[i].normal[0];
00058
00059 output.is_dense = false;
00060 continue;
00061 }
00062 else
00063 {
00064
00065
00066 computeFeature(nn_indices, i, output);
00067
00068
00069 neighborhoods_[i] = nn_indices;
00070 neighborhood_centroids_[i] = i;
00071 }
00072 }
00073 }
00074 else
00075 {
00076 pcl::KdTreeFLANN<pcl::PointXYZRGBA>::Ptr tree(new pcl::KdTreeFLANN<pcl::PointXYZRGBA>());
00077 tree->setInputCloud(input_);
00078 pcl::PointXYZRGBA search_point;
00079
00080
00081 #ifdef _OPENMP
00082 #pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(num_threads_)
00083 #endif
00084
00085 for (int i = 0; i < samples.cols(); i++)
00086 {
00087 search_point.x = samples(0, i);
00088 search_point.y = samples(1, i);
00089 search_point.z = samples(2, i);
00090
00091
00092
00093 if (tree->radiusSearch(search_point, search_radius_, nn_indices, nn_dists) < MIN_NEIGHBORS)
00094 {
00095 output.points[i].normal[0] = output.points[i].normal[1] = output.points[i].normal[2] =
00096 std::numeric_limits<float>::quiet_NaN();
00097 output.points[i].curvature_axis[0] = output.points[i].curvature_axis[1] = output.points[i].curvature_axis[2] =
00098 output.points[i].normal[0];
00099 output.points[i].curvature_centroid[0] = output.points[i].curvature_centroid[1] =
00100 output.points[i].curvature_centroid[2] = output.points[i].normal[0];
00101 output.points[i].median_curvature = output.points[i].normal[0];
00102
00103 output.is_dense = false;
00104 continue;
00105 }
00106 else
00107 {
00108
00109
00110 computeFeature(nn_indices, i, output);
00111
00112
00113 neighborhoods_[i] = nn_indices;
00114 neighborhood_centroids_[i] = i;
00115 }
00116 }
00117 }
00118
00119 int n = 0;
00120 for (int i = 0; i < samples.cols(); i++)
00121 {
00122 if (neighborhoods_[i].size() >= MIN_NEIGHBORS)
00123 n++;
00124 }
00125 printf(" Taubin fitting: %.3f sec\n", this->time_taubin);
00126 printf(" Curvature estimation: %.3f sec\n", this->time_curvature);
00127 }
00128
00129 template<typename PointInT, typename PointOutT> void pcl::CurvatureEstimationTaubin<PointInT, PointOutT>::computeFeature(
00130 PointCloudOut &output)
00131 {
00132
00133 std::vector<int> nn_indices(k_);
00134 std::vector<float> nn_dists(k_);
00135
00136
00137 output.is_dense = true;
00138
00139
00140 output.resize(num_samples_);
00141
00142
00143 if (input_->is_dense)
00144 {
00145
00146 if (indices_->size() != num_samples_)
00147 {
00148 std::srand(std::time(0));
00149 indices_->resize(num_samples_);
00150
00151 for (int i = 0; i < num_samples_; i++)
00152 {
00153 (*indices_)[i] = std::rand() % input_->points.size();
00154 }
00155 }
00156 }
00157 else
00158 {
00159
00160 if (indices_->size() != num_samples_)
00161 {
00162 std::srand(std::time(0));
00163 indices_->resize(num_samples_);
00164
00165 for (int i = 0; i < num_samples_; i++)
00166 {
00167 int r = std::rand() % input_->points.size();
00168
00169 while (!isFinite((*input_)[r]))
00170 r = std::rand() % input_->points.size();
00171
00172 (*indices_)[i] = r;
00173 }
00174 }
00175 }
00176
00177
00178 neighborhoods_.resize(indices_->size());
00179 neighborhood_centroids_.resize(indices_->size());
00180
00181
00182 #ifdef _OPENMP
00183 #pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(num_threads_)
00184 #endif
00185
00186
00187 for (std::size_t idx = 0; idx < indices_->size(); ++idx)
00188 {
00189 if (this->searchForNeighbors((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
00190 {
00191 output.points[idx].normal[0] = output.points[idx].normal[1] = output.points[idx].normal[2] = std::numeric_limits<
00192 float>::quiet_NaN();
00193 output.points[idx].curvature_axis[0] = output.points[idx].curvature_axis[1] =
00194 output.points[idx].curvature_axis[2] = output.points[idx].normal[0];
00195 output.points[idx].curvature_centroid[0] = output.points[idx].curvature_centroid[1] =
00196 output.points[idx].curvature_centroid[2] = output.points[idx].normal[0];
00197 output.points[idx].median_curvature = output.points[idx].normal[0];
00198
00199 output.is_dense = false;
00200 continue;
00201 }
00202
00203
00204 computeFeature(nn_indices, idx, output);
00205
00206
00207 neighborhoods_[idx] = nn_indices;
00208 neighborhood_centroids_[idx] = (*indices_)[idx];
00209 }
00210 }
00211
00212 template<typename PointInT, typename PointOutT> void pcl::CurvatureEstimationTaubin<PointInT, PointOutT>::computeFeature(
00213 const std::vector<int> &nn_indices, int index, PointCloudOut &output)
00214 {
00215
00216 double t0 = omp_get_wtime();
00217 Eigen::VectorXd quadric_parameters(10);
00218 Eigen::Vector3d quadric_centroid;
00219 Eigen::Matrix3d quadric_covariance_matrix;
00220 this->fitQuadric(nn_indices, quadric_parameters, quadric_centroid, quadric_covariance_matrix);
00221 this->time_taubin += omp_get_wtime() - t0;
00222
00223
00224 t0 = omp_get_wtime();
00225 double median_curvature;
00226 Eigen::Vector3d normal;
00227 Eigen::Vector3d curvature_axis;
00228 Eigen::Vector3d curvature_centroid;
00229 this->estimateMedianCurvature(nn_indices, quadric_parameters, median_curvature, normal, curvature_axis,
00230 curvature_centroid);
00231 this->time_curvature += omp_get_wtime() - t0;
00232
00233
00234 output[index].normal[0] = normal[0];
00235 output[index].normal[1] = normal[1];
00236 output[index].normal[2] = normal[2];
00237 output[index].curvature_axis[0] = curvature_axis[0];
00238 output[index].curvature_axis[1] = curvature_axis[1];
00239 output[index].curvature_axis[2] = curvature_axis[2];
00240 output[index].curvature_centroid[0] = curvature_centroid[0];
00241 output[index].curvature_centroid[1] = curvature_centroid[1];
00242 output[index].curvature_centroid[2] = curvature_centroid[2];
00243 output[index].median_curvature = median_curvature;
00244 }
00245
00246 #endif // PCL_FEATURES_IMPL_CURVATURE_ESTIMATION_TAUBIN_HPP_