laserIMUCalibration
pointcloudRegistration.cpp
Go to the documentation of this file.
1 
9 
10 #include <pcl/filters/voxel_grid.h>
11 #include <pcl/filters/fast_bilateral.h>
12 #include <pcl/kdtree/kdtree_flann.h>
13 #include <pcl/surface/mls.h>
14 #include <pcl/features/integral_image_normal.h>
15 #include <pcl/features/normal_3d.h>
16 #include <pcl/features/fpfh.h>
17 #include <pcl/filters/covariance_sampling.h>
18 
19 #include <pcl/registration/ia_ransac.h>
20 #include <pcl/registration/icp_nl.h>
21 #include <pcl/registration/icp.h>
22 
23 Eigen::Matrix4d
24 filter::icp(const pointCloud::Ptr source
25  , const pointCloud::Ptr target
26  , double* fitness_score
27  , const double iterations)
28 {
29  pointCloud::Ptr temp (new pointCloud);
30 
31  Eigen::Matrix4d transformationBetweenScans;
32 
33  pcl::IterativeClosestPoint<pcl::PointNormal, pcl::PointNormal> icp;
34 // icp.setRANSACOutlierRejectionThreshold(1.1);
35 // icp.setRANSACIterations(50);
36 // icp.setMaxCorrespondenceDistance(5);
37  icp.setMaximumIterations(iterations);
38 // icp.setTransformationEpsilon(1e-8);
39 // icp.setEuclideanFitnessEpsilon(0.001);
40 
41  icp.setInputCloud(source);
42  icp.setInputTarget(target);
43  icp.align(*temp);
44 
45  transformationBetweenScans = icp.getFinalTransformation().cast<double>();
46  *fitness_score = icp.getFitnessScore();
47 #ifdef DEBUG
48  std::cout << "Score: " << icp.getFitnessScore() << std::endl;
49 #endif
50 
51  temp.reset();
52  return transformationBetweenScans;
53 }
54 
55 Eigen::Matrix4d
56 filter::icpLM(const pointCloud::Ptr source
57  , const pointCloud::Ptr target
58  , double* fitness_score
59  , const double iterations)
60 {
61  pointCloud::Ptr temp (new pointCloud);
62 
63  Eigen::Matrix4d transformationBetweenScans;
64 
65  pcl::IterativeClosestPointNonLinear<pcl::PointNormal, pcl::PointNormal> icp;
66 // icp.setRANSACOutlierRejectionThreshold(1.1);
67 // icp.setRANSACIterations(50);
68 // icp.setMaxCorrespondenceDistance(5);
69  icp.setMaximumIterations(iterations);
70 // icp.setTransformationEpsilon(1e-8);
71 // icp.setEuclideanFitnessEpsilon(0.001);
72 
73  icp.setInputCloud(source);
74  icp.setInputTarget(target);
75  icp.align(*temp);
76 
77  transformationBetweenScans = icp.getFinalTransformation().cast<double>();
78  *fitness_score = icp.getFitnessScore();
79 #ifdef DEBUG
80  std::cout << "Score: " << icp.getFitnessScore() << std::endl;
81 #endif
82 
83  temp.reset();
84  return transformationBetweenScans;
85 }
86 
87 void
88 filter::downsample(pointCloud::Ptr cloud)
89 {
90  pointCloud::Ptr temp (new pointCloud);
91  pcl::copyPointCloud(*cloud, *temp);
92 
93  pcl::VoxelGrid<pcl::PointNormal> grid;
94  grid.setLeafSize (0.1, 0.1, 0.1);
95  grid.setInputCloud(temp);
96  grid.filter(*cloud);
97 
98  temp.reset();
99 }
100 
101 void
102 filter::bilateralFiltering(pointCloud::Ptr cloud)
103 {
104  pcl::PointCloud<pcl::PointXYZ>::Ptr input (new pcl::PointCloud<pcl::PointXYZ>);
105  pcl::PointCloud<pcl::PointXYZ>::Ptr output (new pcl::PointCloud<pcl::PointXYZ>);
106  pcl::copyPointCloud(*cloud, *input);
107 
108  pcl::FastBilateralFilter<pcl::PointXYZ> bilateral_filter;
109  bilateral_filter.setInputCloud (input);
110  bilateral_filter.setSigmaS (5);
111  bilateral_filter.setSigmaR (0.005f);
112  bilateral_filter.filter (*output);
113 
114  pcl::copyPointCloud(*output, *cloud);
115 
116  input.reset();
117  output.reset();
118 }
119 
120 void
122  pointCloud::Ptr cloud)
123 {
124  pcl::PointCloud<pcl::PointXYZ>::Ptr input (new pcl::PointCloud<pcl::PointXYZ>);
125  pcl::PointCloud<pcl::PointNormal> output;
126  pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
127 
128  pcl::copyPointCloud(*cloud, *input);
129 
130  pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls;
131  mls.setComputeNormals (true);
132  mls.setInputCloud (input);
133  mls.setPolynomialFit (true);
134  mls.setPolynomialOrder (3);
135  mls.setSearchMethod (tree);
136  mls.setSearchRadius (0.03);
137  mls.process(output);
138 
139  pcl::copyPointCloud(output, *cloud);
140 
141  input.reset();
142  tree.reset();
143 }
144 
145 void
147  pointCloud::Ptr cloud)
148 {
149  pointCloud::Ptr temp (new pointCloud);
150  pcl::copyPointCloud(*cloud, *temp);
151 
152 // pcl::IntegralImageNormalEstimation<pcl::PointNormal, pcl::PointNormal> normal_estimation_ii;
153 // normal_estimation_ii.setNormalEstimationMethod (normal_estimation_ii.AVERAGE_DEPTH_CHANGE);
154 // normal_estimation_ii.setMaxDepthChangeFactor (0.01f);
155 // normal_estimation_ii.setDepthDependentSmoothing (true);
156 // normal_estimation_ii.setNormalSmoothingSize (50.0f);
157 // normal_estimation_ii.setInputCloud (temp);
158 // normal_estimation_ii.compute (*cloud);
159 
160  pcl::NormalEstimation<pcl::PointNormal, pcl::PointNormal> norm_est;
161  pcl::search::KdTree<pcl::PointNormal>::Ptr tree (new pcl::search::KdTree<pcl::PointNormal> ());
162  tree->setInputCloud (temp);
163  norm_est.setSearchMethod (tree);
164  norm_est.setKSearch (10);
165  norm_est.setInputCloud (temp);
166  norm_est.compute (*cloud);
167 
168  temp.reset();
169 }
170 
171 void
173  pointCloud::Ptr cloud)
174 {
175  pcl::PointCloud<pcl::PointXYZ>::Ptr temp;
176  pcl::PointCloud<pcl::PointXYZ>::Ptr temp2;
177  pcl::copyPointCloud(*cloud, *temp);
178  pcl::PointCloud<pcl::PointNormal>::Ptr temp3 (new pcl::PointCloud<pcl::PointNormal>);
179 
180  pcl::CovarianceSampling<pcl::PointXYZ, pcl::PointNormal> covariance_sampling;
181  covariance_sampling.setNumberOfSamples (temp->size () / 10);
182  covariance_sampling.setInputCloud (temp);
183  covariance_sampling.setNormals (temp3);
184  covariance_sampling.filter (*temp2);
185 
186  pcl::copyPointCloud(*temp2, *cloud);
187 
188  temp.reset();
189 }
190 
191 pcl::PointCloud<pcl::FPFHSignature33>::Ptr
192 filter::fastPointFeatureHistogram(const pointCloud::Ptr input)
193 {
194  pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfhs (new pcl::PointCloud<pcl::FPFHSignature33>);
195 
196  pcl::FPFHEstimation<pcl::PointNormal, pcl::PointNormal, pcl::FPFHSignature33> fpfh;
197  fpfh.setInputCloud (input);
198  fpfh.setInputNormals (input);
199 
200  pcl::search::KdTree<pcl::PointNormal>::Ptr tree (new pcl::search::KdTree<pcl::PointNormal>);
201  fpfh.setSearchMethod (tree);
202 
203  // Use all neighbors in a sphere of radius 5cm
204  // IMPORTANT: the radius used here has to be larger than the radius used to estimate the surface normals!!!
205  fpfh.setRadiusSearch (0.05);
206 
207  // Compute the features
208  fpfh.compute (*fpfhs);
209 
210  return fpfhs;
211 }
212 
213 Eigen::Matrix4d
215  pointCloud::Ptr source
216  , pcl::PointCloud<pcl::FPFHSignature33>::Ptr source_descriptors
217  , pointCloud::Ptr target
218  , pcl::PointCloud<pcl::FPFHSignature33>::Ptr target_descriptors)
219 {
220  Eigen::Matrix4d initialAligning;
221 
222  pointCloud::Ptr temp (new pointCloud);
223  pcl::copyPointCloud(*source, *temp);
224 
225  pcl::SampleConsensusInitialAlignment<pcl::PointNormal, pcl::PointNormal, pcl::FPFHSignature33> sac;
226  sac.setMinSampleDistance (1);
227  sac.setMaxCorrespondenceDistance (5);
228  sac.setMaximumIterations (20);
229 
230  sac.setInputCloud (source);
231  sac.setSourceFeatures (source_descriptors);
232 
233  sac.setInputTarget (target);
234  sac.setTargetFeatures (target_descriptors);
235 
236  sac.align(*temp);
237  initialAligning = sac.getFinalTransformation().cast<double>();
238 
239  temp.reset();
240 
241  return initialAligning;
242 }
void bilateralFiltering(pointCloud::Ptr organized_cloud)
Use bilateral filtering.
This file implements all the filter and registration methods for point-cloud data using wrappers for ...
Eigen::Matrix4d icpLM(const pointCloud::Ptr source, const pointCloud::Ptr target, double *fitness_score, const double iterations)
Calls the pcl iterativeClosestPoint-algorithm levenberg-marquardt alternative (internally) ...
pcl::PointCloud< pcl::PointNormal > pointCloud
Typedef for shorter call of point-cloud-pointer-type.
Definition: laserNAVCalib.h:25
pcl::PointCloud< pcl::FPFHSignature33 >::Ptr fastPointFeatureHistogram(const pointCloud::Ptr input)
Extracts all (F)PFHs.
void movingLeastSquares(pointCloud::Ptr cloud)
Use moving least squares.
void covarianceDownsampling(pointCloud::Ptr cloud)
Use covariances for downsampling.
void computeSurfaceNormals(pointCloud::Ptr cloud)
Compute the surface normals.
void downsample(pointCloud::Ptr cloud)
Simple Voxel-Grid downsampling.
Eigen::Matrix4d initialAlignment(pointCloud::Ptr source, pcl::PointCloud< pcl::FPFHSignature33 >::Ptr source_descriptors, pointCloud::Ptr target, pcl::PointCloud< pcl::FPFHSignature33 >::Ptr target_descriptors)
Aligns the point-clouds initially using Sample Consensus.
Eigen::Matrix4d icp(const pointCloud::Ptr source, const pointCloud::Ptr target, double *fitness_score, const double iterations)
Calls the pcl iterativeClosestPoint-algorithm.
unsigned int iterations