代码

 

#include <iostream>
#include <vector>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/search/search.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/passthrough.h>
#include <pcl/segmentation/region_growing.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>

#include <stdio.h>


using namespace pcl::console;
int
main (int argc, char** argv)
{

if(argc<2)
{
std::cout<<".exe xx.pcd -kn 50 -bc 0 -fc 10.0 -nc 0 -st 30 -ct 0.05"<<endl;

return 0;
}//����������С��1���������ʾ
time_t start,end,diff[5],option;//���弸��ʱ�̣����ں����������ÿһ�����ѵ�ʱ��
start = time(0);
int KN_normal=50; //����Ĭ���������
bool Bool_Cuting=false;//����Ĭ���������
float far_cuting=10,near_cuting=0,SmoothnessThreshold=5.0,CurvatureThreshold=0.05;//����Ĭ���������
parse_argument (argc, argv, "-kn", KN_normal);//�������ڷ��������Ƶ�k������Ŀ
parse_argument (argc, argv, "-bc", Bool_Cuting);//�����Ƿ���Ҫֱͨ�˲�
parse_argument (argc, argv, "-fc", far_cuting);//ֱͨ�˲������ֵ
parse_argument (argc, argv, "-nc", near_cuting);//ֱͨ�˲�����Сֵ
parse_argument (argc, argv, "-st", SmoothnessThreshold);//ƽ����ֵ
parse_argument (argc, argv, "-ct", CurvatureThreshold);//������ֵ
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
if ( pcl::io::loadPCDFile <pcl::PointXYZ> (argv[1], *cloud) == -1)
{
std::cout << "Cloud reading failed." << std::endl;
return (-1);
}// ���������������
end = time(0);
diff[0] = difftime (end, start);
PCL_INFO ("\tLoading pcd file takes(seconds): %d\n", diff[0]);
//Noraml estimation step(1 parameter)
//����һ��tree����
pcl::search::Search<pcl::PointXYZ>::Ptr tree = boost::shared_ptr<pcl::search::Search<pcl::PointXYZ> > (new pcl::search::KdTree<pcl::PointXYZ>);//����һ��ָ��kd����������Ĺ���ָ��
pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>);
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimator;//�������߹��ƶ���
normal_estimator.setSearchMethod (tree);//������������
normal_estimator.setInputCloud (cloud);//���÷��߹��ƶ�������㼯
normal_estimator.setKSearch (KN_normal);// �������ڷ��������Ƶ�k������Ŀ
normal_estimator.compute (*normals);//���㲢���������
end = time(0);
diff[1] = difftime (end, start)-diff[0];
PCL_INFO ("\tEstimating normal takes(seconds): %d\n", diff[1]);//������߹�����һ�����˶��ʱ��
//optional step: cutting the part are far from the orignal point in Z direction.2 parameters
pcl::IndicesPtr indices (new std::vector <int>);//����һ������
if(Bool_Cuting)//�ж��Ƿ���Ҫֱͨ�˲�
{

pcl::PassThrough<pcl::PointXYZ> pass;//����ֱͨ�˲�������
pass.setInputCloud (cloud);//�����������
pass.setFilterFieldName ("z");//����ָ�����˵�ά��
pass.setFilterLimits (near_cuting, far_cuting);//����ָ��γ�ȹ��˵ķ�Χ
pass.filter (*indices);//ִ���˲��������˲����������������
}


// ���������㷨��5������
pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;//�������������ָ����
reg.setMinClusterSize (100);//����һ��������Ҫ����С����
reg.setMaxClusterSize (5000);//����һ��������Ҫ��������
reg.setSearchMethod (tree);//������������
reg.setNumberOfNeighbours (10);//然后设置参考的邻域点数,也就是看看周边的多少个点来决定这是一个平面(这个参数至关重要,决定了你的容错率,如果设置的很大,那么从全局角度看某一个点稍微有点歪也可以接受,如果设置的很小则通常检测到的平面都会很小)
reg.setInputCloud (cloud);//�����������
if(Bool_Cuting)reg.setIndices (indices);//ͨ������������ã�ȷ���Ƿ������������.�����Ҫֱͨ�˲���������������Ƶ�����
reg.setInputNormals (normals);//����������Ƶķ�����
reg.setSmoothnessThreshold (20 / 180.0 * M_PI);//平滑阈值,法向量的角度差
reg.setCurvatureThreshold (0.05);//曲率阈值,代表平坦的程度

std::vector <pcl::PointIndices> clusters;//����ÿһ�־��࣬ÿһ�־������滹�о���ĵ�
reg.extract (clusters);//��ȡ����Ľ�����ָ��������ڵ��������������С�
end = time(0);
diff[2] = difftime (end, start)-diff[0]-diff[1]; //���������ָ��㷨���ѵ�ʱ��
PCL_INFO ("\tRegion growing takes(seconds): %d\n", diff[2]);

std::cout << "Number of clusters is equal to " << clusters.size () << std::endl;//�����������������
std::cout << "First cluster has " << clusters[0].indices.size () << " points." << endl;//�����һ�������е������




//保存聚类的点云-------------------------------------------------------------------
int j = 0;
for (std::vector<pcl::PointIndices>::const_iterator it = clusters.begin (); it != clusters.end (); ++it)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZ>);
//�����µĵ������ݼ�cloud_cluster��ֱ���ָ�����о���
for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); pit++)
cloud_cluster->points.push_back(cloud->points[*pit]);
cloud_cluster->width = cloud_cluster->points.size();
cloud_cluster->height = 1;
cloud_cluster->is_dense = true;

std::cout << "PointCloud representing the Cluster: " << cloud_cluster->points.size() << " data points."
<< std::endl;
std::stringstream ss;
ss << "cloud_cluster_" << j << ".pcd";
pcl::io::savePCDFileASCII(ss.str(),*cloud_cluster);
cout<<ss.str()<<"Saved"<<endl;
j++;
}


/***
* But this function doesn't guarantee that different segments will have different
* color(it all depends on RNG). Points that were not listed in the indices array will have red color.
*/
pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud ();
//保存附加颜色的点云
// pcl::io::savePCDFileASCII("colored_pointCloud.pcd",*colored_cloud);
pcl::visualization::PCLVisualizer viewer ("区域增长分割");
// viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,8,"coloredCloud");

viewer.addPointCloud(colored_cloud);
// viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,8);
while (!viewer.wasStopped ())
{
viewer.spinOnce();
}

return (0);
}

可视化

PCL区域增长分割_Cloud

PCL区域增长分割_#include_02