PCL库学习(14)_利用Qt中不同ui界面下的交互来可视化PCL中点云聚类

目标:以PCL中欧式聚类为例,通过触发主界面的“segmentation”->“EuclideanClustering”
在这里插入图片描述然后调用出参数设置界面,最终将结果可视化到显示窗口中。
在这里插入图片描述具体步骤如下:
1.新建.ui:右击“Form Files”->“添加”->“类”->“Qt5GuiClass”。
class name命名为qeuclideancluster,然后就会生成相应的.ui,.h,.cpp文件。
在这里插入图片描述2.构建ui界面及对象名称修改
我这里设置了这样一个简单的参数设定界面
在这里插入图片描述3.设置信号与槽函数声明
在.h中添加:

typedef struct
{
	double clusterTolerance;
	int minSize;
	int maxSize;
}euclideancluster_data;
signals:
	void SendEuclideanClusterData(euclideancluster_data);//用来传递数据的信号
	private slots:
	void EuclideanClusterPressed_ok();//button_ok
	void EuclideanClusterPressed_cancel();

4.在参数设置界面:连接信号与槽,及槽函数定义(在窗口设置界面)
4.1 连接信号与槽:

qeuclideancluster::qeuclideancluster(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	connect(ui.pushButton_euclideancluster_ok, SIGNAL(clicked()), this, SLOT(EuclideanClusterPressed_ok()));
	connect(ui.pushButton_euclideancluster_cancel, SIGNAL(clicked()), this, SLOT(EuclideanClusterPressed_cancel()));
}

4.2 槽函数定义

void qeuclideancluster::EuclideanClusterPressed_ok()
{
	
	euclideancluster_data tmp_data;

	pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;//创建欧式聚类对象
	tmp_data.clusterTolerance = ui.lineEdit_ClusterTolerance->text().toDouble();
	tmp_data.minSize = ui.lineEdit_ClusterMinsize->text().toInt();
	tmp_data.maxSize = ui.lineEdit_ClusterMaxsize->text().toInt();
	emit SendEuclideanClusterData(tmp_data);
}
void qeuclideancluster::EuclideanClusterPressed_cancel()
{
	this->hide();
}

5:在主界面:信号与槽函数声明与定义
5.1 在.h中声明信号与槽函数

	void ReceiveEuclideanclusterData(euclideancluster_data param);
	void euclideancluster();
	qeuclideancluster* euclidean;

5.2 在.cpp中连接信号与槽

	connect(ui.actionEuclideanClustring, SIGNAL(triggered()), this, SLOT(euclideancluster()))

5.3 在.cpp中定义信号与槽

void PCLlab_1::ReceiveEuclideanclusterData(euclideancluster_data param)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr add_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
	tree->setInputCloud(cloud);
	std::vector<pcl::PointIndices> cluster_indices;
	pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
	ec.setClusterTolerance(param.clusterTolerance);
	ec.setMinClusterSize(param.minSize);
	ec.setMaxClusterSize(param.maxSize);

	ec.setSearchMethod(tree);
	ec.setInputCloud(cloud);
	ec.extract(cluster_indices);
	//迭代访问点云索引cluster_indices,直至分割出所有聚类
	typedef std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>  cloudptrlist;//定义一个向量,用于存放各个聚类的指针
	cloudptrlist ptrlist;
	int j = 0;//定义变量j用于存储点云聚类名称
	for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin(); it != cluster_indices.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中
		}
		cloud_cluster->width = cloud_cluster->points.size();
		cloud_cluster->height = 1;
		cloud_cluster->is_dense = true;
		//保存点云文件
		std::stringstream ss;
		ss << "cloud_cluster_D" << j << ".pcd";//保存每一个聚类
		pcl::PCDWriter writer;
		writer.write<pcl::PointXYZ>(ss.str(), *cloud_cluster, false);
		ptrlist.push_back(cloud_cluster);//关键的一句,所有的点云聚类都放到数组向量中去
		j++;
	}

	//随机上色,注意区分点云的ID
	for (int i = 0; i < ptrlist.size(); i++)
	{
		double r = 256 * rand() / (RAND_MAX + 1.0f);
		double g = 256 * rand() / (RAND_MAX + 1.0f);
		double b = 256 * rand() / (RAND_MAX + 1.0f);
		pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> ::Ptr handler_tempt(new pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(r, g, b));
		handler_tempt->setInputCloud(ptrlist[i]);//输入点云
		std::ostringstream oss;
		oss << i;//不同的点云,赋予不同的ID
		viewer->addPointCloud(ptrlist[i], *handler_tempt, "cluster" + oss.str());
		viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cluster" + oss.str());
	}
	viewer->resetCamera();
	ui.qvtkWidget->update();
}
void PCLlab_1::euclideancluster()
{
	euclidean = new qeuclideancluster;
	connect(euclidean , SIGNAL(SendEuclideanClusterData(euclideancluster_data)), this, SLOT(ReceiveEuclideanclusterData(euclideancluster_data)));
	euclidean->show();
}

6:功能展示
在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值