PCLFiltering.cpp
Go to the documentation of this file.
1 
35 #ifdef LVR2_USE_PCL
36 
38 #include <pcl/pcl_config.h>
39 
40 namespace lvr2
41 {
42 
43 
44 PCLFiltering::PCLFiltering( PointBufferPtr loader )
45 {
46 
47  // Check if we have RGB data
48  size_t numPoints = loader->numPoints();
49  m_useColors = loader->hasColors();
50 
51  m_pointCloud = pcl::PointCloud<pcl::PointXYZRGB>::Ptr (new pcl::PointCloud<pcl::PointXYZRGB>);
52 
53 
54  // Get data from loader object
55  FloatChannelOptional points = loader->getFloatChannel("points");
56  UCharChannelOptional colors = loader->getUCharChannel("colors");
57 
58  size_t numColors = 0;
59  if(colors)
60  {
61  numColors = (*colors).numElements();
62  }
63 
64  if(m_useColors)
65  {
66  assert(numColors == numPoints);
67  }
68 
69 
70  // Parse to PCL point cloud
71  std::cout << timestamp << "Creating PCL point cloud for filtering" << std::endl;
72  std::cout << timestamp << "Point cloud has " << numPoints << " points" << std::endl;
73  m_pointCloud->resize(numPoints);
74  float x, y, z;
75  for(size_t i = 0; i < numPoints; i++)
76  {
77  x = (*points)[i][0];
78  y = (*points)[i][1];
79  z = (*points)[i][2];
80 
81  if(m_useColors)
82  {
83 // // Pack color information
84  uint8_t r = (*colors)[i][0];
85  uint8_t g = (*colors)[i][1];
86  uint8_t b = (*colors)[i][2];
87 
88 // uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
89 // m_pointCloud->points[i].rgb = *reinterpret_cast<float*>(&rgb);
90 
91  m_pointCloud->points[i] = pcl::PointXYZRGB(r,g,b);
92  }
93 
94  m_pointCloud->points[i].x = x;
95  m_pointCloud->points[i].y = y;
96  m_pointCloud->points[i].z = z;
97  }
98 
99  m_pointCloud->width = numPoints;
100  m_pointCloud->height = 1;
101 
102  // Create an empty kdtree representation, and pass it to the normal estimation object.
103  // Its content will be filled inside the object, based on the given input dataset
104  // (as no other search surface is given).
105  m_kdTree = pcl::search::KdTree<pcl::PointXYZRGB>::Ptr( new pcl::search::KdTree<pcl::PointXYZRGB> );
106  m_kdTree->setInputCloud (m_pointCloud);
107 }
108 
109 void PCLFiltering::applyMLSProjection(float searchRadius)
110 {
111  pcl::MovingLeastSquares<pcl::PointXYZRGB, pcl::PointNormal> mls;
112  pcl::PointCloud<pcl::PointNormal> mls_points;
113 
114  // Set Parameters
115  mls.setInputCloud(m_pointCloud);
116  mls.setPolynomialFit(true);
117  mls.setSearchMethod(m_kdTree);
118  mls.setSearchRadius(searchRadius);
119 
120  std::cout << timestamp << "Applying MSL projection" << std::endl;
121 
122  // Reconstruct
123  mls.process(mls_points);
124 
125  std::cout << timestamp << "Filtered cloud has " << mls_points.size() << " points" << std::endl;
126  std::cout << timestamp << "Saving result" << std::endl;
127 
128  // Save filtered points
129  m_pointCloud->resize(mls_points.size());
130  float x, y, z;
131  for(size_t i = 0; i < mls_points.size(); i++)
132  {
133  m_pointCloud->points[i].x = mls_points.points[i].x;
134  m_pointCloud->points[i].y = mls_points.points[i].y;
135  m_pointCloud->points[i].z = mls_points.points[i].z;
136  }
137 
138  m_pointCloud->height = 1;
139  m_pointCloud->width = mls_points.size();
140 
141 }
142 
143 void PCLFiltering::applyOutlierRemoval(int meank, float thresh)
144 {
145  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZRGB>);
146 
147  std::cout << timestamp << "Applying outlier removal" << std::endl;
148 
149  // Create the filtering object
150  pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> sor;
151  sor.setInputCloud (m_pointCloud);
152  sor.setMeanK (meank);
153  sor.setStddevMulThresh (thresh);
154  sor.filter (*cloud_filtered);
155 
156  std::cout << timestamp << "Filtered cloud has " << cloud_filtered->size() << " points" << std::endl;
157  std::cout << timestamp << "Saving result" << std::endl;
158 
159  m_pointCloud->width = cloud_filtered->width;
160  m_pointCloud->height = cloud_filtered->height;
161  m_pointCloud->points.swap (cloud_filtered->points);
162 }
163 
164 PointBufferPtr PCLFiltering::getPointBuffer()
165 {
166  PointBufferPtr p( new PointBuffer );
167 
168  floatArr points(new float[3 * m_pointCloud->size()]);
170 
171  if(m_useColors)
172  {
173  colors = ucharArr(new unsigned char[3 * m_pointCloud->size()]);
174  }
175 
176  for(int i = 0; i < m_pointCloud->size(); i++)
177  {
178  size_t pos = 3 * i;
179  points[pos ] = m_pointCloud->points[i].x;
180  points[pos + 1] = m_pointCloud->points[i].y;
181  points[pos + 2] = m_pointCloud->points[i].z;
182 
183  if(m_useColors)
184  {
185  colors[pos ] = m_pointCloud->points[i].r;
186  colors[pos + 1] = m_pointCloud->points[i].g;
187  colors[pos + 2] = m_pointCloud->points[i].b;
188 // std::cout << (int)m_pointCloud->points[i].r << " "
189 // << (int)m_pointCloud->points[i].g << " "
190 // << (int)m_pointCloud->points[i].b << " " << std::endl;
191  }
192  }
193 
194  p->setPointArray(points, m_pointCloud->size());
195 
196  if(m_useColors)
197  {
198  p->setColorArray(colors, m_pointCloud->size());
199  }
200 
201  return p;
202 }
203 
204 PCLFiltering::~PCLFiltering()
205 {
206  // TODO Auto-generated destructor stub
207 }
208 
209 } /* namespace lvr2 */
210 
211 #endif
static Timestamp timestamp
A global time stamp object for program runtime measurement.
Definition: Timestamp.hpp:116
boost::shared_array< unsigned char > ucharArr
Definition: DataStruct.hpp:137
UCharChannel::Optional UCharChannelOptional
Definition: Channel.hpp:96
std::shared_ptr< PointBuffer > PointBufferPtr
boost::shared_array< float > floatArr
Definition: DataStruct.hpp:133
SharedPointer p
FloatChannel::Optional FloatChannelOptional
Definition: Channel.hpp:88


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Mon Feb 28 2022 22:46:08