28 #include <pcl/point_types.h>
29 #include <pcl/point_cloud.h>
30 #include <pcl/io/pcd_io.h>
31 #include <pcl/ModelCoefficients.h>
32 #include <pcl/common/common.h>
33 #include <pcl/common/pca.h>
34 #include <pcl/filters/extract_indices.h>
35 #include <pcl/segmentation/sac_segmentation.h>
36 #include <pcl/segmentation/extract_clusters.h>
42 printf(
"\nUsage: extractObject [options] cloud.pcd\n"
44 " -p #.# plane distance threshold (default 0.02 m)\n"
45 " -a #.# plane angle tolerance from z axis (default PI/6)\n"
46 " -c #.# cluster tolerance (default 0.1 m)\n"
47 " -s # minimum cluster size (default 50 points)\n"
48 " -center_obj center the objects to their local reference\n"
49 " -save_plane save the plane inliers to \"extracted_plane.pcd\"\n");
60 std::string cloudPath =
argv[argc-1];
61 double planeDistanceThreshold = 0.02f;
62 double planeEpsAngle = 3.1416/6.0;
63 double clusterTolerance = 0.1f;
64 int minClusterSize = 50;
65 bool centerObject =
false;
66 bool savePlane =
false;
68 for(
int i=1;
i<argc-1; ++
i)
70 if(strcmp(
argv[
i],
"-p") == 0)
76 if(planeDistanceThreshold < 0.0
f)
87 if(strcmp(
argv[
i],
"-a") == 0)
93 if(planeEpsAngle < 0.0
f)
104 if(strcmp(
argv[
i],
"-c") == 0)
110 if(clusterTolerance <= 0.0
f)
121 if(strcmp(
argv[
i],
"-s") == 0)
126 minClusterSize = std::atoi(
argv[
i]);
127 if(minClusterSize < 1)
138 if(strcmp(
argv[
i],
"-center_obj") == 0)
143 if(strcmp(
argv[
i],
"-save_plane") == 0)
148 printf(
"Unrecognized option : %s\n",
argv[
i]);
152 printf(
"Parameters:\n"
153 " planeDistanceThreshold=%f\n"
154 " planeEpsAngle=%f\n"
155 " clusterTolerance=%f\n"
156 " minClusterSize=%d\n"
159 planeDistanceThreshold,
163 centerObject?
"true":
"false",
164 savePlane?
"true":
"false");
166 printf(
"Loading \"%s\"...", cloudPath.c_str());
167 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
168 pcl::io::loadPCDFile(cloudPath, *cloud);
169 printf(
"done! (%d points)\n", (
int)cloud->size());
172 pcl::ModelCoefficients::Ptr coefficients (
new pcl::ModelCoefficients);
173 pcl::PointIndices::Ptr inliers (
new pcl::PointIndices);
175 pcl::SACSegmentation<pcl::PointXYZRGB> seg;
177 seg.setOptimizeCoefficients (
true);
179 seg.setModelType (pcl::SACMODEL_PLANE);
180 seg.setMethodType (pcl::SAC_RANSAC);
181 seg.setMaxIterations(1000);
182 seg.setDistanceThreshold (planeDistanceThreshold);
183 seg.setAxis(Eigen::Vector3f(0,0,1));
184 seg.setEpsAngle (planeEpsAngle);
186 seg.setInputCloud (cloud);
187 seg.segment (*inliers, *coefficients);
189 printf(
"Plane coefficients: %f %f %f %f\n", coefficients->values[0],
190 coefficients->values[1],
191 coefficients->values[2],
192 coefficients->values[3]);
194 float a = coefficients->values[0];
195 float b = coefficients->values[1];
196 float c = coefficients->values[2];
197 float d = coefficients->values[3];
200 Eigen::Vector3f current(
a,
b,
c);
201 Eigen::Vector3f
target(0.0, 0.0, 1.0);
203 q.setFromTwoVectors(current,
target);
204 Eigen::Matrix4f
trans;
205 trans.topLeftCorner<3,3>() =
q.toRotationMatrix();
207 float planeShift = -
d;
210 pcl::PointCloud<pcl::PointXYZRGB>::Ptr output (
new pcl::PointCloud<pcl::PointXYZRGB> ());
215 pcl::io::savePCDFile(
"extracted_plane.pcd", *output, inliers->indices);
216 printf(
"Saved extracted_plane.pcd (%d points)\n", (
int)inliers->indices.size());
220 printf(
"Plane size = %d points\n", (
int)inliers->indices.size());
224 pcl::ExtractIndices<pcl::PointXYZRGB>
extract;
226 extract.setInputCloud (output);
231 pcl::search::KdTree<pcl::PointXYZRGB>::Ptr kdTree(
new pcl::search::KdTree<pcl::PointXYZRGB>);
232 kdTree->setInputCloud(output);
233 std::vector<pcl::PointIndices> cluster_indices;
234 pcl::EuclideanClusterExtraction<pcl::PointXYZRGB> ec;
235 ec.setClusterTolerance (clusterTolerance);
236 ec.setMinClusterSize (minClusterSize);
237 ec.setMaxClusterSize (200000);
238 ec.setSearchMethod (kdTree);
239 ec.setInputCloud (output);
240 ec.extract (cluster_indices);
242 if(cluster_indices.size() == 0)
244 printf(
"No object found! (minimum cluster size=%d)\n", minClusterSize);
248 for(
unsigned int i=0;
i<cluster_indices.size(); ++
i)
250 pcl::PointCloud<pcl::PointXYZRGB>::Ptr
object (
new pcl::PointCloud<pcl::PointXYZRGB> ());
251 pcl::copyPointCloud(*output, cluster_indices.at(
i), *
object);
262 pcl::io::savePCDFile(
uFormat(
"extracted_object%d.pcd", (
int)
i+1), *
object);
263 printf(
"Saved extracted_object%d.pcd (%d points)\n", (
int)
i+1, (
int)
object->size());