LCCP点云分割算法代码

参考1

一、代码结构

实现代码 QT窗口
lccp_segmentation.h mainwindow.h
ccp_segmentation.hpp mainwindow.cpp
lccp_segmentation.cpp

二、默认参数

mainwindow.cpp中默认参数;

    if(lineVoxel->text()!=NULL && 
        lineSeed->text()!=NULL){
        voxel_resolution = this->lineVoxel->text().toFloat();
        seed_resolution = this->lineSeed->text().toFloat();
	    color_importance = this->lineColor->text().toFloat();
    }
    else{
        voxel_resolution = 0.0075f;    //粒子距离 = 0.0075f
		seed_resolution = 0.3f;    //晶核距离 = 0.3f
		color_importance = 0.0f;    //颜色容差 = 0.0f
    }

三、主要函数

void mainwindow::lccpSeg()
{   
    clock_t startTime,endTime;
    startTime = clock();
    if(lineVoxel->text()!=NULL && 
        lineSeed->text()!=NULL){
        voxel_resolution = this->lineVoxel->text().toFloat();
        seed_resolution = this->lineSeed->text().toFloat();
	    color_importance = this->lineColor->text().toFloat();
    }
    else{
        voxel_resolution = 0.0075f;
	    seed_resolution = 0.3f;
	    color_importance = 0.0f;
    }
    //输入点云
	pcl::PointCloud::Ptr input_cloud_ptr(new pcl::PointCloud);
	pcl::PCLPointCloud2 input_pointcloud2;
	if (pcl::io::loadPCDFile("milk_cartoon_all_small_clorox.pcd", input_pointcloud2))
	{
		PCL_ERROR("ERROR: Could not read input point cloud ");
		return ;
	}
	pcl::fromPCLPointCloud2(input_pointcloud2, *input_cloud_ptr);
	PCL_INFO("Done making cloud\n");
	    float spatial_importance = 1.0f;
	float normal_importance = 4.0f;
	bool use_single_cam_transform = false;
	bool use_supervoxel_refinement = false;

	unsigned int k_factor = 0;
 
	//voxel_resolution is the resolution (in meters) of voxels used、seed_resolution is the average size (in meters) of resulting supervoxels  
	pcl::SupervoxelClustering super(voxel_resolution, seed_resolution);
	super.setUseSingleCameraTransform(use_single_cam_transform);
	super.setInputCloud(input_cloud_ptr);
	//Set the importance of color for supervoxels. 
	super.setColorImportance(color_importance);
	//Set the importance of spatial distance for supervoxels.
	super.setSpatialImportance(spatial_importance);
	//Set the importance of scalar normal product for supervoxels. 
	super.setNormalImportance(normal_importance);
	std::map::Ptr> supervoxel_clusters;
 
	PCL_INFO("Extracting supervoxels\n");
	super.extract(supervoxel_clusters);
 
	PCL_INFO("Getting supervoxel adjacency\n");
	std::multimap supervoxel_adjacency;
	super.getSupervoxelAdjacency(supervoxel_adjacency);
	pcl::PointCloud::Ptr sv_centroid_normal_cloud = pcl::SupervoxelClustering::makeSupervoxelNormalCloud(supervoxel_clusters);
	//LCCP分割
	float concavity_tolerance_threshold = 20;
	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 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::Ptr sv_labeled_cloud = super.getLabeledCloud();
	pcl::PointCloud::Ptr lccp_labeled_cloud = sv_labeled_cloud->makeShared();
	lccp.relabelCloud(*lccp_labeled_cloud);
	SuperVoxelAdjacencyList sv_adjacency_list;
	lccp.getSVAdjacencyList(sv_adjacency_list);
	 // Configure Visualizer
    pcl::visualization::PCLVisualizer viewer = pcl::visualization::PCLVisualizer ("3D Viewer",false);
    viewer.addPointCloud (lccp_labeled_cloud, "Segmented point cloud");

	renderWindow = vtkSmartPointer::New();
    renderWindow = viewer.getRenderWindow();
    qvtk->SetRenderWindow(renderWindow);
    viewer.setupInteractor(qvtk->GetInteractor(),qvtk->GetRenderWindow());

    qvtk->update();
    qvtk->GetRenderWindow()->Render();
    endTime = clock();
    cout<<"The run time is :" << (double)(endTime-startTime)/CLOCKS_PER_SEC <<"s"<

参考2

Q:源代码得不到分割后带标记的点云!
A:解决:输出点云的label全部是0。最后发现,getlabelcloud()函数是可以得到有label且不为0的点云的,但是这个点云不可以使用pcl中的pcl::savePCDFile来保存成pcd文件,这样保存的pcd文件的label都是0,又没找到可视化的工具,所以就新建一个pcl::PointXYZRGB类型的点云,重新对其赋值,进而得到可以用pcl::savePCDFile的点云文件

Q:终输出4个点云文件:

1.超体聚类后有xyz的.txt文件;

2.超体聚类后有label的.txt文件;

3.根据不同label给随机颜色的.pcd文件

4.在LCCP之后,数据类型为xyz和label的.txt文件

//超体聚类+LCCP
#include "stdafx.h"
 
#include   
#include   
#include   
#include   
#include  
 
#include   
#include   
#include   
#include   
#include 
 
#include   
#include   
 
#include   
 
#define Random(x) (rand() % x)
 
typedef pcl::PointXYZRGBA PointT;
typedef pcl::LCCPSegmentation::SupervoxelAdjacencyList SuperVoxelAdjacencyList;
 
int main(int argc, char ** argv)
{
	//输入点云  
	pcl::PointCloud::Ptr input_cloud_ptr(new pcl::PointCloud);
	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 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::Ptr> supervoxel_clusters;
 
	PCL_INFO("Extracting supervoxels\n");
	super.extract(supervoxel_clusters);
 
	PCL_INFO("Getting supervoxel adjacency\n");
	std::multimap supervoxel_adjacency;
	super.getSupervoxelAdjacency(supervoxel_adjacency);
	
	pcl::PointCloud::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::Ptr ColoredCloud1(new pcl::PointCloud);
	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 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::Ptr sv_labeled_cloud = super.getLabeledCloud();
	pcl::PointCloud::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::Ptr ColoredCloud2(new pcl::PointCloud);
	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;
}

你可能感兴趣的:(qt,均值算法)