8 #include <pcl/features/organized_edge_detection.h>
9 #include <pcl/features/integral_image_normal.h>
10 #include <pcl/features/normal_3d.h>
11 #include <pcl/impl/point_types.hpp>
26 const pcl::PointCloud<pcl::PointXYZ>::Ptr & points,
27 pcl::PointCloud<pcl::PointXYZL>::Ptr & edges)
29 int N_SCANS = m_settings.lines;
32 m_addedPoints.clear();
38 for(
int i = 0; i < N_SCANS; i++){
39 m_lidarScans.push_back(pcl::PointCloud<pcl::PointXYZ>::Ptr(
new pcl::PointCloud<pcl::PointXYZ>()));
44 m_kdTree.setInputCloud(points);
47 int kNN = m_settings.searchK;
49 double radius = m_settings.searchRadius;
53 const int increment = m_settings.skipPoints;
55 double diffX, diffY, diffZ = 0;
56 double diffTotal, diffLeft, diffRight = 0;
57 double tempX, tempY, tempZ = 0;
62 for (
int i = 0; i < (int) points->points.size(); i+=increment)
69 points->points[i].x * points->points[i].x +
70 points->points[i].y * points->points[i].y);
73 if (distance < m_settings.common.limits.distance.min ||
74 distance > m_settings.common.limits.distance.max)
79 double angle = atan(points->points[i].z / distance) * 180 / M_PI;
82 scanID = int((
angle + 15) / 2 + 0.5);
83 if (scanID > (N_SCANS - 1) || scanID < 0) {
86 }
else if (N_SCANS == 32) {
87 scanID = int((
angle + 92.0/3.0) * 3.0 / 4.0);
88 if (scanID > (N_SCANS - 1) || scanID < 0) {
91 }
else if (N_SCANS == 64) {
93 scanID = int((2 -
angle) * 3.0 + 0.5);
95 scanID = N_SCANS / 2 + int((-8.83 -
angle) * 2.0 + 0.5);
98 if (
angle > 2 || angle < -24.33 || scanID > 63 || scanID < 0) {
106 m_kdTree.radiusSearch(
107 points->points[i], radius, pointSearch,
108 pointSquaredDistance) > 0)
119 m_covariance.setZero(3, 3);
122 for(std::size_t j = 0; j < pointSearch.size(); ++j) {
124 diffX = (*points)[pointSearch[j]].x - points->points[i].x;
125 diffY = (*points)[pointSearch[j]].y - points->points[i].y;
126 diffZ = (*points)[pointSearch[j]].z - points->points[i].z;
129 m_covariance(0, 0) += diffX * diffX;
130 m_covariance(1, 0) += diffX * diffY;
131 m_covariance(2, 0) += diffX * diffZ;
132 m_covariance(0, 1) += m_covariance(1, 0);
133 m_covariance(1, 1) += diffY * diffY;
134 m_covariance(2, 1) += diffY * diffZ;
135 m_covariance(0, 2) += m_covariance(2, 0);
136 m_covariance(1, 2) += m_covariance(2, 1);
137 m_covariance(2, 2) += diffZ * diffZ;
141 index = (int)pointSearch.size() - 1;
144 m_covariance = m_covariance / index;
147 auto solver(m_covariance);
148 m_eigenValues = solver.eigenvalues();
149 diffTotal = std::real(m_eigenValues(0) / (m_eigenValues(0) + m_eigenValues(1) + m_eigenValues(2)));
152 pcl::PointXYZL tempPointL;
153 tempPointL.x = points->points[i].x;
154 tempPointL.y = points->points[i].y;
155 tempPointL.z = points->points[i].z;
157 if (diffTotal <= m_settings.common.limits.edgeThreshold &&
158 diffTotal >= -m_settings.common.limits.edgeThreshold)
161 tempPointL.label = 0;
164 tempPointL.label = 1;
168 m_addedPoints.push_back(i);
169 edges->push_back(tempPointL);
186 m_lidarScans[scanID]->push_back(points->points[i]);
190 if (!edges->empty()) {
194 for(
int i = 0; i < N_SCANS; i++) {
197 if(m_lidarScans[i]->points.size() < 131) {
205 std::vector<floam::lidar::Double2d> cloudCurvature;
209 int halfWindow = windowSize / 2;
211 int totalPoints = m_lidarScans[i]->points.size() - windowSize;
215 m_settings.common.limits.sectors = 6;
216 int sectorSize = (int)m_lidarScans[i]->points.size() / m_settings.common.limits.sectors;
218 double diffX, diffY, diffZ;
220 for(
int j = halfWindow; j < (int)(m_lidarScans[i]->points.size() - halfWindow); j += 1) {
229 for (
int k = -halfWindow; k <= halfWindow; k++) {
233 tempX = diffX - (halfWindow * m_lidarScans[i]->points[j].x);
234 tempY = diffY - (halfWindow * m_lidarScans[i]->points[j].y);
235 tempZ = diffZ - (halfWindow * m_lidarScans[i]->points[j].z);
236 diffLeft = tempX * tempX + tempY * tempY + tempZ * tempZ;
239 diffX -= windowSize * m_lidarScans[i]->points[j].x;
240 diffY -= windowSize * m_lidarScans[i]->points[j].y;
241 diffZ -= windowSize * m_lidarScans[i]->points[j].z;
244 diffX += m_lidarScans[i]->points[j + k].x;
245 diffY += m_lidarScans[i]->points[j + k].y;
246 diffZ += m_lidarScans[i]->points[j + k].z;
251 diffTotal = diffX * diffX + diffY * diffY + diffZ * diffZ;
252 diffRight = diffTotal - diffLeft;
254 cloudCurvature.push_back(distance);
259 for(
int j = 0; j < m_settings.common.limits.sectors; j++) {
260 int sectorStart = sectorSize * j;
261 int sectorEnd = sectorSize * (j + 1) - 1;
263 if (j == (m_settings.common.limits.sectors - 1)) {
264 sectorEnd = totalPoints - 1;
267 std::vector<floam::lidar::Double2d> subCloudCurvature(
268 cloudCurvature.begin() + sectorStart,
269 cloudCurvature.begin() + sectorEnd);
272 std::sort(subCloudCurvature.begin(), subCloudCurvature.end(),
275 return a.diffTotal < b.diffTotal;
279 for (
int k = subCloudCurvature.size() - 1; k >= 0; k--) {
281 index = subCloudCurvature[k].id;
283 pcl::PointXYZL tempPointL;
284 tempPointL.x = m_lidarScans[i]->points[index].x;
285 tempPointL.y = m_lidarScans[i]->points[index].y;
286 tempPointL.z = m_lidarScans[i]->points[index].z;
289 if (subCloudCurvature[k].diffTotal <= m_settings.common.limits.edgeThreshold)
292 tempPointL.label = 0;
294 tempPointL.label = 1;
296 edges->push_back(tempPointL);
297 m_addedPoints.push_back(index);
306 const pcl::PointCloud<pcl::PointXYZ>::Ptr & points,
307 pcl::PointCloud<pcl::PointXYZL>::Ptr & edges)
310 pcl::OrganizedEdgeBase <pcl::PointXYZ, pcl::Label> edgeDetector;
311 pcl::PointCloud<pcl::Label>::Ptr labels(
new pcl::PointCloud<pcl::Label> ());
313 std::vector<pcl::PointIndices> indicies;
314 edgeDetector.setInputCloud(points);
317 edgeDetector.setDepthDisconThreshold(0.02
f);
318 edgeDetector.setMaxSearchNeighbors(50);
321 edgeDetector.compute(*labels, indicies);
323 pcl::concatenateFields(*points, *labels, *edges);
329 const pcl::PointCloud<pcl::PointXYZ>::Ptr & points,
330 pcl::PointCloud<pcl::PointNormal>::Ptr & normals)
333 pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normalDetector;
334 pcl::PointCloud<pcl::Normal>::Ptr normalCloud(
new pcl::PointCloud<pcl::Normal> ());
335 normalDetector.setInputCloud(points);
339 pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (
new pcl::search::KdTree<pcl::PointXYZ> ());
340 normalDetector.setSearchMethod (tree);
342 normalDetector.setKSearch (0.03);
345 normalDetector.compute(*normalCloud);
347 pcl::concatenateFields(*points, *normalCloud, *normals);
353 const pcl::PointCloud<pcl::PointXYZ>::Ptr & points,
354 pcl::PointCloud<pcl::PointNormal>::Ptr & normals)
356 pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> normalDetector;
357 pcl::PointCloud<pcl::Normal> normalCloud;
360 normalDetector.setNormalEstimationMethod(normalDetector.AVERAGE_3D_GRADIENT);
362 normalDetector.setMaxDepthChangeFactor(0.02
f);
363 normalDetector.setNormalSmoothingSize(7.0
f);
364 normalDetector.setInputCloud(points);
366 normalDetector.compute(normalCloud);
369 pcl::concatenateFields(*points, normalCloud, *normals);