00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef PCL_FEATURES_IMPL_INTENSITY_SPIN_H_
00039 #define PCL_FEATURES_IMPL_INTENSITY_SPIN_H_
00040
00041 #include "pcl/features/intensity_spin.h"
00042
00044 template <typename PointInT, typename PointOutT> void
00045 pcl::IntensitySpinEstimation<PointInT, PointOutT>::computeIntensitySpinImage (
00046 const PointCloudIn &cloud, float radius, float sigma,
00047 int k,
00048 const std::vector<int> &indices,
00049 const std::vector<float> &squared_distances, Eigen::MatrixXf &intensity_spin_image)
00050 {
00051
00052 int nr_distance_bins = intensity_spin_image.cols ();
00053 int nr_intensity_bins = intensity_spin_image.rows ();
00054
00055
00056 float min_intensity = std::numeric_limits<float>::max ();
00057 float max_intensity = std::numeric_limits<float>::min ();
00058 for (int idx = 0; idx < k; ++idx)
00059 {
00060 min_intensity = (std::min) (min_intensity, cloud.points[indices[idx]].intensity);
00061 max_intensity = (std::max) (max_intensity, cloud.points[indices[idx]].intensity);
00062 }
00063
00064
00065 intensity_spin_image.setZero ();
00066 for (int idx = 0; idx < k; ++idx)
00067 {
00068
00069 const float eps = std::numeric_limits<float>::epsilon ();
00070 float d = nr_distance_bins * sqrt (squared_distances[idx]) / (radius + eps);
00071 float i = nr_intensity_bins *
00072 (cloud.points[indices[idx]].intensity - min_intensity) / (max_intensity - min_intensity + eps);
00073
00074 if (sigma == 0)
00075 {
00076
00077 int d_idx = (int) d;
00078 int i_idx = (int) i;
00079 intensity_spin_image (i_idx, d_idx) += 1;
00080 }
00081 else
00082 {
00083
00084 int d_idx_min = (std::max)((int) floor (d - 3*sigma), 0);
00085 int d_idx_max = (std::min)((int) ceil (d + 3*sigma), nr_distance_bins - 1);
00086 int i_idx_min = (std::max)((int) floor (i - 3*sigma), 0);
00087 int i_idx_max = (std::min)((int) ceil (i + 3*sigma), nr_intensity_bins - 1);
00088
00089
00090 for (int i_idx = i_idx_min; i_idx <= i_idx_max; ++i_idx)
00091 {
00092 for (int d_idx = d_idx_min; d_idx <= d_idx_max; ++d_idx)
00093 {
00094
00095 float w = exp (-pow (d - d_idx, 2) / (2.0*sigma_*sigma_)
00096 -pow (i - i_idx, 2) / (2.0*sigma_*sigma_));
00097 intensity_spin_image (i_idx, d_idx) += w;
00098 }
00099 }
00100 }
00101 }
00102 }
00103
00105 template <typename PointInT, typename PointOutT> void
00106 pcl::IntensitySpinEstimation<PointInT, PointOutT>::computeFeature (PointCloudOut &output)
00107 {
00108
00109 if (search_radius_ == 0.0)
00110 {
00111 ROS_ERROR ("[pcl::%s::computeFeature] The search radius must be set before computing the feature!",
00112 getClassName ().c_str ());
00113 output.width = output.height = 0;
00114 output.points.clear ();
00115 return;
00116 }
00117
00118
00119 if (nr_intensity_bins_ <= 0)
00120 {
00121 ROS_ERROR ("[pcl::%s::computeFeature] The number of intensity bins must be greater than zero!",
00122 getClassName ().c_str ());
00123 output.width = output.height = 0;
00124 output.points.clear ();
00125 return;
00126 }
00127 if (nr_distance_bins_ <= 0)
00128 {
00129 ROS_ERROR ("[pcl::%s::computeFeature] The number of distance bins must be greater than zero!",
00130 getClassName ().c_str ());
00131 output.width = output.height = 0;
00132 output.points.clear ();
00133 return;
00134 }
00135
00136 Eigen::MatrixXf intensity_spin_image (nr_intensity_bins_, nr_distance_bins_);
00137
00138 std::vector<int> nn_indices (surface_->points.size ());
00139 std::vector<float> nn_dist_sqr (surface_->points.size ());
00140
00141
00142 for (size_t idx = 0; idx < indices_->size (); ++idx)
00143 {
00144
00145
00146 int k = tree_->radiusSearch ((*indices_)[idx], search_radius_, nn_indices, nn_dist_sqr);
00147
00148
00149 computeIntensitySpinImage (*surface_, search_radius_, sigma_, k, nn_indices, nn_dist_sqr, intensity_spin_image);
00150
00151
00152 for (int bin = 0; bin < intensity_spin_image.size (); ++bin)
00153 output.points[idx].histogram[bin] = intensity_spin_image (bin);
00154 }
00155 }
00156
00157 #define PCL_INSTANTIATE_IntensitySpinEstimation(T,NT) template class pcl::IntensitySpinEstimation<T,NT>;
00158
00159 #endif // PCL_FEATURES_IMPL_INTENSITY_SPIN_H_
00160