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);
202 Eigen::Quaternion<float> q;
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;
225 extract.setNegative (
true);
226 extract.setInputCloud (output);
227 extract.setIndices(inliers);
228 extract.filter (*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);
259 pcl::transformPointCloud(*
object, *
object, Eigen::Vector3f(-(max[0]+min[0])/2.0
f, -(max[1]+min[1])/2.0
f, -min[2]), Eigen::Quaternion<float>(0,0,0,0));
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());
GLM_FUNC_DECL genType min(genType const &x, genType const &y)
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP transformPointCloud(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const Transform &transform)
void RTABMAP_EXP getMinMax3D(const cv::Mat &laserScan, cv::Point3f &min, cv::Point3f &max)
float UTILITE_EXP uStr2Float(const std::string &str)
Some conversion functions.
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
int main(int argc, char *argv[])
std::string UTILITE_EXP uFormat(const char *fmt,...)