PCL区域增长分割

91 篇文章 100 订阅

代码

 

#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);
}

可视化

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tech沉思录

点赞加投币,感谢您的资瓷~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值