计算分割后点云质心的结果为:
//****区域增长分割****//
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/segmentation/region_growing.h>
#include <pcl/visualization/cloud_viewer.h>
#include <vector>
#include <string>
#include <pcl/io/ply_io.h>
#include <atlstr.h>//CString头文件
using namespace std;
int main(int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPLYFile<pcl::PointXYZ>("house.ply", *cloud);
//设置默认输入参数
int KN_normal = 50;
//bool Bool_Cuting=false;
float SmoothnessThreshold = 45, CurvatureThreshold = 20;
//法线估计
pcl::search::Search<pcl::PointXYZ>::Ptr tree = 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);//计算并输出法向量
// 区域生长算法的5个参数
pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;//创建区域生长分割对象
reg.setMinClusterSize(100);//设置一个聚类需要的最小点数
reg.setMaxClusterSize(1000000);//设置一个聚类需要的最大点数
reg.setSearchMethod(tree);//设置搜索方法
reg.setNumberOfNeighbours(15);//设置搜索的临近点数目
reg.setInputCloud(cloud);//设置输入点云
//pcl::IndicesPtr indices(new std::vector <int>);//创建一组索引
//if(Bool_Cuting)reg.setIndices (indices);//通过输入参数设置,确定是否输入点云索引
reg.setInputNormals(normals);//设置输入点云的法向量
reg.setSmoothnessThreshold(SmoothnessThreshold / 180.0 * M_PI);//设置平滑阈值
reg.setCurvatureThreshold(CurvatureThreshold);//设置曲率阈值
std::vector <pcl::PointIndices> clusters;
reg.extract(clusters);//获取聚类的结果,分割结果保存在点云索引的向量中。
pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud();//如果点云分割成功,该函数返回有色点云,相同的分割有相同的颜色,但是该函数不保证不同的分割一定会有不同的颜色,即不同的分割也可能会有相同的颜色
pcl::io::savePLYFile("aaa.ply", *colored_cloud); //保存文件
std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> RegionGrow; //用于储存区域增长分割后的点云
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>);
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;
RegionGrow.push_back(cloud_cluster);
}
cout << " RegionGrow.size() = " << RegionGrow.size() << endl;
ofstream fout; //c++输出文件流,支持输出c++的数据类型,如string
fout.open("RGCentroid.txt");
for (int i = 0; i < RegionGrow.size(); i++)
{
//显示分割得到的各片点云
//显示分割得到的各片点云
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color(RegionGrow[i], 255 * (1 - i) * (2 - i) / 2, 255 * i * (2 - i), 255 * i * (i - 1) / 2);
//保存分割得到的各片点云
pcl::io::savePLYFile(to_string(i)+"a.ply",*RegionGrow[i]); //保存文件
//将分割得到的各片点云的质心保存在.txt文件中
Eigen::Vector4f RGCentroid;
pcl::compute3DCentroid(*RegionGrow[i], RGCentroid);//计算点云质心
fout << "Centroid of = " << i << RGCentroid[0] << " " << RGCentroid[1] << " " << RGCentroid[2] << " " << endl;
}
fout.close(); //关闭文件。
return (0);
}