-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathqhull.cpp
105 lines (91 loc) · 3.48 KB
/
qhull.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/***
* Test QHull with PCD and Planar segmentation with Pyramidal extraction of objects
*
* Input: PCD file with an object on a plane (table, ground, etc).
*
*/
#include <pcl/io/pcd_io.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/surface/convex_hull.h>
#include <pcl/segmentation/extract_polygonal_prism_data.h>
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
int
main(int argc, char** argv)
{
// Objects for storing the point clouds.
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr plane(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr convexHull(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr objects(new pcl::PointCloud<pcl::PointXYZ>);
if (argc < 1) {
std::cout << "usage:" << argv[0] << " <pclfile>" << std::endl;
return -1;
}
// Read a PCD file from disk.
if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0)
{
std::cout << "error: could not open pcl file[" << argv[1] << std::endl;
return -2;
}
// Get the plane model, if present.
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
pcl::SACSegmentation<pcl::PointXYZ> segmentation;
segmentation.setInputCloud(cloud);
segmentation.setModelType(pcl::SACMODEL_PLANE);
segmentation.setMethodType(pcl::SAC_RANSAC);
segmentation.setDistanceThreshold(0.01);
segmentation.setOptimizeCoefficients(true);
pcl::PointIndices::Ptr planeIndices(new pcl::PointIndices);
segmentation.segment(*planeIndices, *coefficients);
if (planeIndices->indices.size() == 0)
std::cout << "Could not find a plane in the scene." << std::endl;
else
{
// Copy the points of the plane to a new cloud.
pcl::ExtractIndices<pcl::PointXYZ> extract;
extract.setInputCloud(cloud);
extract.setIndices(planeIndices);
extract.filter(*plane);
std::cout << "Planar segmentation:" << planeIndices->indices.size() << " points" << std::endl;
#define TESTING_ALL 1 //comment out this line to just test PCL/VTK
#ifdef TESTING_ALL
// Retrieve the convex hull.
pcl::ConvexHull<pcl::PointXYZ> hull;
hull.setInputCloud(plane);
// Make sure that the resulting hull is bidimensional.
hull.setDimension(2);
hull.reconstruct(*convexHull);
std::cout << "Convex hull:" << convexHull->points.size() << " points" << std::endl;
// Redundant check.
if (hull.getDimension() == 2)
{
// Prism object.
pcl::ExtractPolygonalPrismData<pcl::PointXYZ> prism;
prism.setInputCloud(cloud);
prism.setInputPlanarHull(convexHull);
// First parameter: minimum Z value. Set to 0, segments objects lying on the plane (can be negative).
// Second parameter: maximum Z value, set to 10cm. Tune it according to the height of the objects you expect.
prism.setHeightLimits(0.0f, 0.1f);
pcl::PointIndices::Ptr objectIndices(new pcl::PointIndices);
prism.segment(*objectIndices);
std::cout << "Prism:" << objectIndices->indices.size() << " points" << std::endl;
// Get and show all points retrieved by the hull.
extract.setIndices(objectIndices);
extract.filter(*objects);
pcl::visualization::CloudViewer viewerObjects("Objects on table");
viewerObjects.showCloud(objects);
while (!viewerObjects.wasStopped())
{
// Do nothing but wait.
}
}
else {
std::cout << "The chosen hull is not planar." << std::endl;
}
#endif
}
}