Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
octree_pointcloud_voxelcentroid.h
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Willow Garage, Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id: octree_pointcloud_voxelcentroid.h 6119 2012-07-03 18:50:04Z aichim $
37  */
38 
39 #ifndef OCTREE_VOXELCENTROID_H
40 #define OCTREE_VOXELCENTROID_H
41 
42 #include "octree_pointcloud.h"
43 
44 #include "octree_base.h"
45 #include "octree2buf_base.h"
46 
47 namespace pcl
48 {
49  namespace octree
50  {
51 
53 
61 
62  template<typename PointT, typename LeafT = OctreeContainerDataTVector<int> , typename BranchT = OctreeContainerEmpty<int> >
63  class OctreePointCloudVoxelCentroid : public OctreePointCloud<PointT, LeafT, BranchT>
64  {
65 
66  public:
67  // public typedefs for single/double buffering
68 
69  // Eigen aligned allocator
71 
75  OctreePointCloudVoxelCentroid (const double resolution_arg) :
76  OctreePointCloud<PointT, LeafT, BranchT> (resolution_arg)
77  {
78  }
79 
81  virtual
83  {
84  }
85 
90  unsigned int
91  getVoxelCentroids (AlignedPointTVector &voxelCentroidList_arg)
92  {
93 
94  size_t i;
95  unsigned int pointCounter;
96  OctreeKey keyC, keyP;
97  PointT meanPoint;
98  PointT idxPoint;
99 
100  std::vector<int> indicesVector;
101 
102  voxelCentroidList_arg.clear();
103  voxelCentroidList_arg.reserve(this->leafCount_);
104 
105  // serialize leafs - this returns a list of point indices. Points indices from the same voxel are locates next to each other within this vector.
106  this->serializeLeafs (indicesVector);
107 
108  // initializing
109  keyP.x = keyP.y = keyP.z = std::numeric_limits<unsigned int>::max ();
110  meanPoint.x = meanPoint.y = meanPoint.z = 0.0;
111  pointCounter = 0;
112 
113  // iterate over all point indices
114  for (i = 0; i < indicesVector.size (); i++)
115  {
116  idxPoint = this->input_->points[indicesVector[i]];
117 
118  // get octree key for point (key specifies octree voxel)
119  this->genOctreeKeyforPoint (idxPoint, keyC);
120 
121  if (keyC == keyP)
122  {
123  // key addresses same voxel - add point
124  meanPoint.x += idxPoint.x;
125  meanPoint.y += idxPoint.y;
126  meanPoint.z += idxPoint.z;
127 
128  pointCounter++;
129  }
130  else
131  {
132  // voxel key did change - calculate centroid and push it to result vector
133  if (pointCounter > 0)
134  {
135  meanPoint.x /= static_cast<float> (pointCounter);
136  meanPoint.y /= static_cast<float> (pointCounter);
137  meanPoint.z /= static_cast<float> (pointCounter);
138 
139  voxelCentroidList_arg.push_back (meanPoint);
140  }
141 
142  // reset centroid to current input point
143  meanPoint.x = idxPoint.x;
144  meanPoint.y = idxPoint.y;
145  meanPoint.z = idxPoint.z;
146  pointCounter = 1;
147 
148  keyP = keyC;
149  }
150  }
151 
152  // push last centroid to result vector if necessary
153  if (pointCounter > 0)
154  {
155  meanPoint.x /= static_cast<float> (pointCounter);
156  meanPoint.y /= static_cast<float> (pointCounter);
157  meanPoint.z /= static_cast<float> (pointCounter);
158 
159  voxelCentroidList_arg.push_back (meanPoint);
160  }
161 
162  // return size of centroid vector
163  return (static_cast<unsigned int> (voxelCentroidList_arg.size ()));
164  }
165 
171  bool
172  getVoxelCentroidAtPoint (const PointT& point_arg, PointT& voxelCentroid_arg)
173  {
174 
175  size_t i;
176  unsigned int pointCounter;
177  std::vector<int> indicesVector;
178  PointT meanPoint;
179  PointT idxPoint;
180 
181  bool bResult;
182 
183  // get all point indixes from voxel at point point_arg
184  bResult = this->voxelSearch (point_arg, indicesVector);
185 
186  if (bResult)
187  {
188  meanPoint.x = meanPoint.y = meanPoint.z = 0.0;
189  pointCounter = 0;
190 
191  // iterate over all point indices
192  for (i = 0; i < indicesVector.size (); i++)
193  {
194  idxPoint = this->input_->points[indicesVector[i]];
195 
196  meanPoint.x += idxPoint.x;
197  meanPoint.y += idxPoint.y;
198  meanPoint.z += idxPoint.z;
199 
200  pointCounter++;
201  }
202 
203  // calculate centroid
204  voxelCentroid_arg.x = meanPoint.x / static_cast<float> (pointCounter);
205  voxelCentroid_arg.y = meanPoint.y / static_cast<float> (pointCounter);
206  voxelCentroid_arg.z = meanPoint.z / static_cast<float> (pointCounter);
207  }
208 
209  return (bResult);
210  }
211 
217  inline bool
218  getVoxelCentroidAtPoint (const int& pointIdx_arg, PointT& voxelCentroid_arg)
219  {
220 
221  // retrieve point from input cloud
222  const PointT& point = this->input_->points[pointIdx_arg];
223 
224  // get centroid at point
225  return this->getVoxelCentroidAtPoint (point, voxelCentroid_arg);
226 
227  }
228 
229  };
230 
231  }
232 
233 }
234 
235 #define PCL_INSTANTIATE_OctreePointCloudVoxelCentroid(T) template class PCL_EXPORTS pcl::octree::OctreePointCloudVoxelCentroid<T>;
236 
237 #endif
238