Slice the point cloud and save the slice

       The main idea is to cut and save the point cloud continuously with straight-through filtering given the slice interval. Input point cloud and slice thickness, output individual slices. Below is the code. The program slices according to the z axis. If you want to slice according to the x or y axis, you can change it. The slice thickness is sliceInterval. The code refers to the point cloud slicing algorithm program . I don’t understand the algorithm in the original text. If you understand it, you can leave a message or private chat to teach me. Thank you very much. I didn’t change the name of the saved point cloud. You can set a parameter n to replace bs. The output slice file name will be better.

#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/passthrough.h>
#include <pcl/features/normal_3d.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/centroid.h>
#include <pcl/common/transforms.h>
#include <pcl/common/common.h>
#include <iostream>
#include <pcl/visualization/cloud_viewer.h>
#include<string>
#include<math.h>
using namespace std;
int main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr finallycloud(new pcl::PointCloud<pcl::PointXYZ>);
	string inputPCDName="shiyan.pcd";
	pcl::io::loadPCDFile(inputPCDName, *cloud);
	pcl::PointXYZ minValues;//用于存放三个轴的最小值
	pcl::PointXYZ maxValues;//用于存放三个轴的最大值
	pcl::getMinMax3D(*cloud, minValues, maxValues);//得到输入点云x,y,z三个轴上的最小值最大值
	double zMax = maxValues.z;//点云z轴最大值赋给zMax
	double zMin = minValues.z;
	double sliceInterval = 0.001;
	int sliceNum = floor((zMax - zMin) / sliceInterval) - 1;//算出点云切片数量
	std::cout << "slice number:   " << sliceNum << endl;
	double sliceBeginCoordinate = zMin + (zMax - zMin - sliceNum * sliceInterval) / 2 + sliceInterval / 2;//点云开始位置                                 
	std::cout << "slice Begin Coordinate:   " << sliceBeginCoordinate << endl;
	std::cout << "slice End Coordinate:   " << sliceBeginCoordinate + sliceNum * sliceInterval << endl;


	for (float base = sliceBeginCoordinate; base <= sliceBeginCoordinate + sliceNum * sliceInterval; base = base + sliceInterval) {
		float d = sliceInterval;//点云切片厚度,根据点云的最小距离确定
		float bs = base;
		//-------------------------------------------------保存点云文件命名--------------------------------------------------------------
		std::string pcd_file_name;
		// cout<<"file name input:"<< endl;
		 //cin>>pcd_file_name;
		 //cout<<"slice z label base:"<< endl;
		 //cin>>bs;
		std::string bs_string;
		std::stringstream ss;          //定义流ss
		ss << float(bs);
		ss >> bs_string;
		std::string slice_name = inputPCDName.substr(0, inputPCDName.rfind("."));//取inputPCDName中'.'前面的字符串
		std::string kuohao = "(";
		std::string extension = ").pcd";
		slice_name = slice_name + kuohao;
		slice_name = slice_name + bs_string;
		slice_name = slice_name + extension;//slice_name=slice_name(base).pcd
		//---------------------------------------------------------------------------------------------------------------------------------
		
		//----------------------------------------------------------点云切片---------------------------------------------------------------
		pcl::PassThrough<pcl::PointXYZ> pass;             //直通滤波对象
		pass.setInputCloud(cloud);
		pass.setFilterFieldName("z");
		pass.setFilterLimits(-0.5*d + bs, 0.5*d + bs);
		pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_belt(new pcl::PointCloud<pcl::PointXYZ>);
		pass.filter(*cloud_belt);
		int l_n = cloud_belt->points.size();
		pcl::io::savePCDFile(slice_name, *cloud_belt);
	}
	return(0);
}

Guess you like

Origin blog.csdn.net/mengzhilv11/article/details/126292331