超体聚类+LCCP实现

pcl的官方教程中有实现的代码,但之前一直得不到分割后带标记的点云,输出点云的label全部是0。最后发现,getlabelcloud()函数是可以得到有label且不为0的点云的,但是这个点云不可以使用pcl中的pcl::savePCDFile来保存成pcd文件,这样保存的pcd文件的label都是0,又没找到可视化的工具,所以就新建一个pcl::PointXYZRGB类型的点云,重新对其赋值,进而得到可以用pcl::savePCDFile的点云文件。最终输出4个点云文件,分别是超体聚类后有xyz和label的.txt文件、为了在视觉上更容易区分根据不同label给随机颜色的.pcd文件;以及在LCCP之后,数据类型为xyz和label的.txt文件、为了在视觉上更容易区分根据不同label给随机颜色的.pcd文件。

本来实时性就不够好,为了给不同label的点赋上随机颜色,循环里又套了一个循环,所以运行时间有点长。参数根据数据得更改,代码如下:

//超体聚类+LCCP
#include "stdafx.h"

#include <stdlib.h>  
#include <cmath>  
#include <limits.h>  
#include <boost/format.hpp>  
#include <fstream> 

#include <pcl/console/parse.h>  
#include <pcl/io/pcd_io.h>  
#include <pcl/visualization/pcl_visualizer.h>  
#include <pcl/visualization/point_cloud_color_handlers.h>  
#include <pcl/visualization/cloud_viewer.h>

#include <pcl/filters/passthrough.h>  
#include <pcl/segmentation/supervoxel_clustering.h>  

#include <pcl/segmentation/lccp_segmentation.h>  

#define Random(x) (rand() % x)

typedef pcl::PointXYZRGBA PointT;
typedef pcl::LCCPSegmentation<PointT>::SupervoxelAdjacencyList SuperVoxelAdjacencyList;

int main(int argc, char ** argv)
{
	//输入点云  
	pcl::PointCloud<PointT>::Ptr input_cloud_ptr(new pcl::PointCloud<PointT>);
	pcl::PCLPointCloud2 input_pointcloud2;
	if (pcl::io::loadPCDFile("xyzrgb.pcd", input_pointcloud2))
	{
		PCL_ERROR("ERROR: Could not read input point cloud ");
		return (3);
	}
	pcl::fromPCLPointCloud2(input_pointcloud2, *input_cloud_ptr);
	PCL_INFO("Done making cloud\n");

	float voxel_resolution = 0.3f;
	float seed_resolution = 1.2f;
	float color_importance = 0.0f;
	float spatial_importance = 1.0f;
	float normal_importance = 0.0f;
	bool use_single_cam_transform = false;
	bool use_supervoxel_refinement = false;

	unsigned int k_factor = 0;

	pcl::SupervoxelClustering<PointT> super(voxel_resolution, seed_resolution);
	super.setUseSingleCameraTransform(use_single_cam_transform);
	super.setInputCloud(input_cloud_ptr);  
	super.setColorImportance(color_importance);
	super.setSpatialImportance(spatial_importance);
	super.setNormalImportance(normal_importance);
	std::map<uint32_t, pcl::Supervoxel<PointT>::Ptr> supervoxel_clusters;

	PCL_INFO("Extracting supervoxels\n");
	super.extract(supervoxel_clusters);

	PCL_INFO("Getting supervoxel adjacency\n");
	std::multimap<uint32_t, uint32_t> supervoxel_adjacency;
	super.getSupervoxelAdjacency(supervoxel_adjacency);
	
	pcl::PointCloud<pcl::PointXYZL>::Ptr overseg = super.getLabeledCloud();
	ofstream outFile1("过分割3.txt", std::ios_base::out);
	for (int i = 0; i < overseg->size(); i++) {
		outFile1 << overseg->points[i].x << "\t" << overseg->points[i].y << "\t" << overseg->points[i].z << "\t" << overseg->points[i].label << endl;
	}
	int label_max1 = 0;
	for (int i = 0;i< overseg->size(); i++) {
		if (overseg->points[i].label>label_max1)
			label_max1 = overseg->points[i].label;
	}
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr ColoredCloud1(new pcl::PointCloud<pcl::PointXYZRGB>);
	ColoredCloud1->height = 1;
	ColoredCloud1->width = overseg->size();
	ColoredCloud1->resize(overseg->size());
	for (int i = 0; i < label_max1; i++) {
		int color_R = Random(255);
		int color_G = Random(255);
		int color_B = Random(255);
		
		for (int j = 0; j < overseg->size(); j++) {
			if (overseg->points[j].label == i) {
				ColoredCloud1->points[j].x = overseg->points[j].x;
				ColoredCloud1->points[j].y = overseg->points[j].y;
				ColoredCloud1->points[j].z = overseg->points[j].z;
				ColoredCloud1->points[j].r = color_R;
				ColoredCloud1->points[j].g = color_G;
				ColoredCloud1->points[j].b = color_B;
			}
		}
	}
	pcl::io::savePCDFileASCII("过分割3.pcd", *ColoredCloud1);



	//LCCP分割  
	float concavity_tolerance_threshold = 10;
	float smoothness_threshold = 0.1;
	uint32_t min_segment_size = 0;
	bool use_extended_convexity = false;
	bool use_sanity_criterion = false;
	PCL_INFO("Starting Segmentation\n");
	pcl::LCCPSegmentation<PointT> lccp;
	lccp.setConcavityToleranceThreshold(concavity_tolerance_threshold);
	lccp.setSmoothnessCheck(true, voxel_resolution, seed_resolution, smoothness_threshold);
	lccp.setKFactor(k_factor);
	lccp.setInputSupervoxels(supervoxel_clusters, supervoxel_adjacency);
	lccp.setMinSegmentSize(min_segment_size);
	lccp.segment();

	PCL_INFO("Interpolation voxel cloud -> input cloud and relabeling\n");

	pcl::PointCloud<pcl::PointXYZL>::Ptr sv_labeled_cloud = super.getLabeledCloud();
	pcl::PointCloud<pcl::PointXYZL>::Ptr lccp_labeled_cloud = sv_labeled_cloud->makeShared();
	lccp.relabelCloud(*lccp_labeled_cloud);
	SuperVoxelAdjacencyList sv_adjacency_list;
	lccp.getSVAdjacencyList(sv_adjacency_list);
	
	ofstream outFile2("分割后合并3.txt", std::ios_base::out);
	for (int i = 0; i < lccp_labeled_cloud->size();i++) {
		outFile2 << lccp_labeled_cloud->points[i].x << "\t" << lccp_labeled_cloud->points[i].y << "\t" << lccp_labeled_cloud->points[i].z << "\t" << lccp_labeled_cloud->points[i].label << endl;
	}

	int label_max2 = 0;
	for (int i = 0; i< lccp_labeled_cloud->size(); i++) {
		if (lccp_labeled_cloud->points[i].label>label_max2)
			label_max2 = lccp_labeled_cloud->points[i].label;
	}
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr ColoredCloud2(new pcl::PointCloud<pcl::PointXYZRGB>);
	ColoredCloud2->height = 1;
	ColoredCloud2->width = lccp_labeled_cloud->size();
	ColoredCloud2->resize(lccp_labeled_cloud->size());
	for (int i = 0; i < label_max2; i++) {
		int color_R = Random(255);
		int color_G = Random(255);
		int color_B = Random(255);

		for (int j = 0; j < lccp_labeled_cloud->size(); j++) {
			if (lccp_labeled_cloud->points[j].label == i) {
				ColoredCloud2->points[j].x = lccp_labeled_cloud->points[j].x;
				ColoredCloud2->points[j].y = lccp_labeled_cloud->points[j].y;
				ColoredCloud2->points[j].z = lccp_labeled_cloud->points[j].z;
				ColoredCloud2->points[j].r = color_R;
				ColoredCloud2->points[j].g = color_G;
				ColoredCloud2->points[j].b = color_B;
			}
		}
	}
	pcl::io::savePCDFileASCII("分割后合并3.pcd", *ColoredCloud2);
	return 0;
}

  • 6
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 34
    评论
【资源说明】 基于lccp与边缘检测的三维点云分割方法c++源码(含项目使用说明+测试数据).zip 主要内容:改善二维实例分割生成的点云,并生成分割点云地图。 测试环境 系统:win10 编译器:MSVC2017 64bit、cmake 3.5 第三方库:pcl 1.9.1、boost 1.6.8、opencv 4.2.0、yaml 0.6.0 实例分割网络:YOLACT++,权重:yolact_plus_resnet50_54_800000 测试数据集 TUM数据集 rgbd_dataset_freiburg1_room序列 百度网盘 链接:https://pan.baidu.com/s/1sMxa3skD_Uix4TYjzioLyQ 提取码:1wpe 使用方法: 编译文件 首先编译yaml_cpp cd yaml_cpp mkdir build cd build cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] .. make 编译本工程 mkdir build cd build cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] .. make 执行命令 "SegmentMap.exe --Dataset" 数据集目录 -t 数据集目录/KeyFrameTrajectory.txt -c 0.2 -s 0.4 -n 0.6 -C 15 -S 0.01" 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
点云超体聚类+LCCP程序是一种将点云分割成多个超体素,并在每个超体素内进行聚类的方法,并使用LCCP算法进行分割的程序。以下是一份基于Python和open3d库实现的点云超体聚类+LCCP程序的代码示例: ```python import open3d as o3d # 读取点云 pcd = o3d.io.read_point_cloud("point_cloud.pcd") # 超体聚类 voxel_size = 0.05 # 超体素大小 pcd = pcd.voxel_down_sample(voxel_size) # 下采样 labels = pcd.cluster_dbscan(eps=0.05, min_points=10) # DBSCAN聚类 max_label = labels.max() print(f"point cloud has {max_label + 1} clusters") # LCCP分割 segmentation = pcd.segment_plane(distance_threshold=0.01, ransac_n=3, num_iterations=1000) segment_labels = np.asarray(segmentation[1]) pcd_normals = pcd.compute_point_cloud_normals(knn=knn) pcd_labels = np.array(labels) pcd_segments = o3d.geometry.PointCloud() for segment_id in np.unique(segment_labels): segment_mask = segment_labels == segment_id segment_pcd = pcd.select_by_index(np.where(segment_mask)[0]) segment_normals = pcd_normals.select_by_index(np.where(segment_mask)[0]) segment_labels = np.array(pcd_labels[np.where(segment_mask)[0]]) lccp = segment_pcd.segment_local_maxima( search_radius=0.2, suppress_radius=0.1, normal_radius=0.1, method=o3d.geometry.SegmentLocalMaximaMethod.LCCP) segments = lccp.get_segmented_point_cloud() segments.normals = segment_normals segments.colors = np.array([segment_id / len(np.unique(segment_labels)) for i in range(len(segments.points))]) pcd_segments += segments # 可视化结果 o3d.visualization.draw_geometries([pcd_segments]) ``` 其中,`read_point_cloud()`函数用于读取点云数据,`voxel_down_sample()`函数用于进行超体素分割的下采样操作,`cluster_dbscan()`函数用于进行DBSCAN聚类,`segment_plane()`函数用于平面分割,`compute_point_cloud_normals()`函数用于计算点云法向量,`select_by_index()`函数用于选取指定索引的点,`segment_local_maxima()`函数用于进行LCCP分割,`get_segmented_point_cloud()`函数用于获取分割结果,`draw_geometries()`函数用于可视化分割结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值