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_SURFACE_GRID_PROJECTION_H_
00039 #define PCL_SURFACE_GRID_PROJECTION_H_
00040
00041 #include <pcl/surface/reconstruction.h>
00042 #include <boost/dynamic_bitset/dynamic_bitset.hpp>
00043 #include <boost/unordered_map.hpp>
00044
00045 namespace pcl
00046 {
00048 const int I_SHIFT_EP[12][2] = {
00049 {0, 4}, {1, 5}, {2, 6}, {3, 7},
00050 {0, 1}, {1, 2}, {2, 3}, {3, 0},
00051 {4, 5}, {5, 6}, {6, 7}, {7, 4}
00052 };
00053
00054 const int I_SHIFT_PT[4] = {
00055 0, 4, 5, 7
00056 };
00057
00058 const int I_SHIFT_EDGE[3][2] = {
00059 {0,1}, {1,3}, {1,2}
00060 };
00061
00062
00072 template <typename PointNT>
00073 class GridProjection : public SurfaceReconstruction<PointNT>
00074 {
00075 public:
00076 using SurfaceReconstruction<PointNT>::input_;
00077 using SurfaceReconstruction<PointNT>::tree_;
00078
00079 typedef typename pcl::PointCloud<PointNT>::Ptr PointCloudPtr;
00080
00081 typedef typename pcl::KdTree<PointNT> KdTree;
00082 typedef typename pcl::KdTree<PointNT>::Ptr KdTreePtr;
00083
00085 struct Leaf
00086 {
00087 Leaf () : data_indices (), pt_on_surface (), vect_at_grid_pt () {}
00088
00089 std::vector<int> data_indices;
00090 Eigen::Vector4f pt_on_surface;
00091 Eigen::Vector3f vect_at_grid_pt;
00092 };
00093
00094 typedef boost::unordered_map<int, Leaf, boost::hash<int>, std::equal_to<int>, Eigen::aligned_allocator<int> > HashMap;
00095
00097 GridProjection ();
00098
00102 GridProjection (double in_resolution);
00103
00105 ~GridProjection ();
00106
00110 inline void
00111 setResolution (double resolution)
00112 {
00113 leaf_size_ = resolution;
00114 }
00115
00116 inline double
00117 getResolution () const
00118 {
00119 return (leaf_size_);
00120 }
00121
00131 inline void
00132 setPaddingSize (int padding_size)
00133 {
00134 padding_size_ = padding_size;
00135 }
00136 inline int
00137 getPaddingSize () const
00138 {
00139 return (padding_size_);
00140 }
00141
00146 inline void
00147 setNearestNeighborNum (int k)
00148 {
00149 k_ = k;
00150 }
00151 inline int
00152 getNearestNeighborNum () const
00153 {
00154 return (k_);
00155 }
00156
00161 inline void
00162 setMaxBinarySearchLevel (int max_binary_search_level)
00163 {
00164 max_binary_search_level_ = max_binary_search_level;
00165 }
00166 inline int
00167 getMaxBinarySearchLevel () const
00168 {
00169 return (max_binary_search_level_);
00170 }
00171
00173 inline const HashMap&
00174 getCellHashMap () const
00175 {
00176 return (cell_hash_map_);
00177 }
00178
00179 inline const std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> >&
00180 getVectorAtDataPoint () const
00181 {
00182 return (vector_at_data_point_);
00183 }
00184
00185 inline const std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >&
00186 getSurface () const
00187 {
00188 return (surface_);
00189 }
00190
00191 protected:
00195 void
00196 getBoundingBox ();
00197
00201 bool
00202 reconstructPolygons (std::vector<pcl::Vertices> &polygons);
00203
00213 void
00214 performReconstruction (pcl::PolygonMesh &output);
00215
00226 void
00227 performReconstruction (pcl::PointCloud<PointNT> &points,
00228 std::vector<pcl::Vertices> &polygons);
00229
00235 void
00236 scaleInputDataPoint (double scale_factor);
00237
00243 inline void
00244 getCellIndex (const Eigen::Vector4f &p, Eigen::Vector3i& index) const
00245 {
00246 for (int i = 0; i < 3; ++i)
00247 index[i] = static_cast<int> ((p[i] - min_p_(i)) / leaf_size_);
00248 }
00249
00255 inline void
00256 getCellCenterFromIndex (const Eigen::Vector3i &index, Eigen::Vector4f ¢er) const
00257 {
00258 for (int i = 0; i < 3; ++i)
00259 center[i] =
00260 min_p_[i] + static_cast<float> (index[i]) *
00261 static_cast<float> (leaf_size_) +
00262 static_cast<float> (leaf_size_) / 2.0f;
00263 }
00264
00269 void
00270 getVertexFromCellCenter (const Eigen::Vector4f &cell_center,
00271 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > &pts) const;
00272
00277 inline int
00278 getIndexIn1D (const Eigen::Vector3i &index) const
00279 {
00280
00281 return (index[0] * data_size_ * data_size_ +
00282 index[1] * data_size_ + index[2]);
00283 }
00284
00290 inline void
00291 getIndexIn3D (int index_1d, Eigen::Vector3i& index_3d) const
00292 {
00293
00294 index_3d[0] = index_1d / (data_size_ * data_size_);
00295 index_1d -= index_3d[0] * data_size_ * data_size_;
00296 index_3d[1] = index_1d / data_size_;
00297 index_1d -= index_3d[1] * data_size_;
00298 index_3d[2] = index_1d;
00299 }
00300
00305 void
00306 fillPad (const Eigen::Vector3i &index);
00307
00312 void
00313 getDataPtsUnion (const Eigen::Vector3i &index, std::vector <int> &pt_union_indices);
00314
00321 void
00322 createSurfaceForCell (const Eigen::Vector3i &index, std::vector <int> &pt_union_indices);
00323
00324
00332 void
00333 getProjection (const Eigen::Vector4f &p, std::vector<int> &pt_union_indices, Eigen::Vector4f &projection);
00334
00342 void
00343 getProjectionWithPlaneFit (const Eigen::Vector4f &p,
00344 std::vector<int> &pt_union_indices,
00345 Eigen::Vector4f &projection);
00346
00347
00353 void
00354 getVectorAtPoint (const Eigen::Vector4f &p,
00355 std::vector <int> &pt_union_indices, Eigen::Vector3f &vo);
00356
00364 void
00365 getVectorAtPointKNN (const Eigen::Vector4f &p,
00366 std::vector<int> &k_indices,
00367 std::vector<float> &k_squared_distances,
00368 Eigen::Vector3f &vo);
00369
00374 double
00375 getMagAtPoint (const Eigen::Vector4f &p, const std::vector <int> &pt_union_indices);
00376
00382 double
00383 getD1AtPoint (const Eigen::Vector4f &p, const Eigen::Vector3f &vec,
00384 const std::vector <int> &pt_union_indices);
00385
00391 double
00392 getD2AtPoint (const Eigen::Vector4f &p, const Eigen::Vector3f &vec,
00393 const std::vector <int> &pt_union_indices);
00394
00403 bool
00404 isIntersected (const std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > &end_pts,
00405 std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> > &vect_at_end_pts,
00406 std::vector <int> &pt_union_indices);
00407
00416 void
00417 findIntersection (int level,
00418 const std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > &end_pts,
00419 const std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> > &vect_at_end_pts,
00420 const Eigen::Vector4f &start_pt,
00421 std::vector<int> &pt_union_indices,
00422 Eigen::Vector4f &intersection);
00423
00438 void
00439 storeVectAndSurfacePoint (int index_1d, const Eigen::Vector3i &index_3d,
00440 std::vector<int> &pt_union_indices, const Leaf &cell_data);
00441
00455 void
00456 storeVectAndSurfacePointKNN (int index_1d, const Eigen::Vector3i &index_3d, const Leaf &cell_data);
00457
00458 private:
00460 HashMap cell_hash_map_;
00461
00463 Eigen::Vector4f min_p_, max_p_;
00464
00466 double leaf_size_;
00467
00469 double gaussian_scale_;
00470
00472 int data_size_;
00473
00475 int max_binary_search_level_;
00476
00478 int k_;
00479
00481 int padding_size_;
00482
00484 PointCloudPtr data_;
00485
00487 std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> > vector_at_data_point_;
00488
00490 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > surface_;
00491
00493 boost::dynamic_bitset<> occupied_cell_list_;
00494
00496 std::string getClassName () const { return ("GridProjection"); }
00497
00498 public:
00499 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00500 };
00501 }
00502
00503 #endif // PCL_SURFACE_GRID_PROJECTION_H_
00504