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