Point cloud cutting code implementation

Purpose

Cut the point cloud files under the folder into point cloud blocks in the x and y dimensions according to the custom step (step), and re-save the new point cloud file and dilute it.

Environment configuration

c++ pcl library

Code

cutting part

#include<iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/point_types.h>
#include<cmath>
#include<unordered_map>
#include<vector>
#include<dirent.h>

using namespace std;

unordered_map<string , pcl::PointCloud<pcl::PointXYZ>>umap;
//切割点云
void division(string filename , int batch){
    
    
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    string pwdfilename = "../input/" + filename;
    if(pcl::io::loadPCDFile<pcl::PointXYZ>(pwdfilename,*cloud) == -1){
    
    
        PCL_ERROR("can't open pcd file");
        return;
    }
    int a ,b;
    for (size_t i = 0; i < cloud->size(); ++i) {
    
    
        a = floor(cloud->points[i].x / batch);
        b = floor(cloud->points[i].y / batch);
        string cloudname = "x"+to_string(a)+"_y"+to_string(b);
        umap[cloudname].push_back({
    
    cloud->points[i].x , cloud->points[i].y , cloud->points[i].z});
    }
}
int main(int argc, char *argv[])
{
    
    
    int batch  = stoi(argv[1]);	//输入batch每个点云块的大小
    cout << "batch size = " << batch << endl;
	string PATH = argv[2];		//输入原点云文件夹的路径
	
	//读取文件夹下所有文件
    struct dirent *ptr;
    DIR *dir;
    dir = opendir(PATH.c_str());
    vector<string>files;
    while ((ptr=readdir(dir)) != NULL){
    
    
        if(ptr->d_name[0] == '.') continue;
        files.push_back(ptr->d_name);
    }
    closedir(dir);
    for (int i = 0; i < files.size(); ++i)
    {
    
    
        cout << files[i] << endl;
        division(files[i] , batch);
    }
    //切割后的点云保存到输出路路径
    for(auto it : umap){
    
    
        pcl::io::savePCDFileASCII("/home/houyiliang/pointclouds_cut/output/"+it.first + ".pcd" , it.second);
    }
    return 0;
}

diluted part

在这里插入代码片#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
using namespace std;

void filter(string filename , float leafsize){
    
    
  pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());
  pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ());
  // 填入点云数据
  pcl::PCDReader reader;
  // 把路径改为自己存放文件的路径
  string pwdfilename = "../output/" + filename;
  reader.read (pwdfilename, *cloud); // 记住要事先下载这个数据集!
  std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height 
       << " data points (" << pcl::getFieldsList (*cloud) << ").";
  // 创建滤波器对象
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
  sor.setInputCloud (cloud);
  sor.setLeafSize (leafsize, leafsize, leafsize);// 单位:m
  sor.filter (*cloud_filtered);
  std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height 
       << " data points (" << pcl::getFieldsList (*cloud_filtered) << ")." << endl;
  pcl::PCDWriter writer;
  string outputfilename = "../output_filter/" + filename + "_filter.pcd";
  writer.write (outputfilename, *cloud_filtered, 
         Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), false);

}
main (int argc, char** argv)
{
    
    
    float leafsize  = atof(argv[1]);	//稀释块大小
    struct dirent *ptr;
    DIR *dir;
    string PATH = argv[2];		//输出路径
    dir = opendir(PATH.c_str());
    vector<string>files;
    while ((ptr=readdir(dir)) != NULL){
    
    
        if(ptr->d_name[0] == '.') continue;//linux下跳过.开头的文件
        files.push_back(ptr->d_name);
    }
    cout <<  "total " << files.size() << endl;
    for (int i = 0; i < files.size(); ++i)
    {
    
    
        cout << files[i] << endl;
        filter(files[i] , leafsize);
    }

    closedir(dir);
  return (0);
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(cut)

find_package(PCL REQUIRED)
include_directories(${
    
    PCL_INCLUDE_DIRS})
link_directories(${
    
    PCL_LIBRARY_DIRS})

add_definitions(${
    
    PCL_DEFINITIONS})

add_executable(pointclouds_cut pointclouds_cut.cpp)
target_link_libraries (pointclouds_cut ${
    
    PCL_LIBRARIES})

add_executable(filter_pointclouds filter_pointclouds.cpp)
target_link_libraries (filter_pointclouds ${
    
    PCL_LIBRARIES})

implement

to cut

 ./pointclouds_cut 50 ../input/ ../outpt/

Parameter interpretation: argv [
1]: 50 means that x , y are cut with 50 (m)

dilution

 ./pointclouds_cut 0.2 ../output_filter/ ../output/

Parameter interpretation:
argv[1]:0.2 diluting block size
argv[2]: .../output/ path of the point cloud to be diluted (here, the path of the segment cloud after cutting is to be diluted, so it is the output path of the cutting part)
argv [3]: …/output_filter/ The output path of the diluted point cloud

renderings

Original point cloud image
insert image description here
after cutting
insert image description here

Guess you like

Origin blog.csdn.net/qq_43200940/article/details/127803572