利用pcd文件,使用pcl库实现贪婪三角形化,在paraview查看三角化结果

目录

1.首先在自己的xiaobanjing.pcd格式文件中,利用ransac方法提取出ground.pcd文件,效果不算太好,后期再进行调整。

2.修改自己的/src下的代码和cmakelist.txt文件,使其可以使用pcl的贪婪三角形方法将ground.pcd文件构成三角网结构。

3.然后就是修改CMakeList.txt文件,我的文件内容是这样的

4.然后就是执行编译

5.编译完成之后,查看/data/mesh.vtk。

6.查看VTK文件

补充内容:三角网结构更加明显一点的做法:


1.首先在自己的xiaobanjing.pcd格式文件中,利用ransac方法提取出ground.pcd文件,效果不算太好,后期再进行调整。

        创建工作空间的过程就不进行描述了。就是写好/src和/data。(然后在新建build,并里面执行,这一部分就是等自己的代码和cmakelist.txt写好了执行编译的过程,再去处理)

2.修改自己的/src下的代码和cmakelist.txt文件,使其可以使用pcl的贪婪三角形方法将ground.pcd文件构成三角网结构。

附上代码

/src/ransac代码

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/surface/gp3.h>
#include <pcl/features/normal_3d.h>
#include <pcl/common/concatenate.h>
#include <pcl/search/kdtree.h>
#include <pcl/io/vtk_io.h>  

int main() {
    // 加载点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    if (pcl::io::loadPCDFile<pcl::PointXYZ>("/home/dzz/pcl_project/data/ground.pcd", *cloud) == -1) {
        PCL_ERROR("Couldn't read file ground.pcd \n");
        return -1;
    }

    // 创建一个用于存储分割后的地面点云的指针
    pcl::PointCloud<pcl::PointXYZ>::Ptr ground(new pcl::PointCloud<pcl::PointXYZ>);

    // 创建一个RANSAC分割对象
    pcl::SACSegmentation<pcl::PointXYZ> seg;
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
    seg.setOptimizeCoefficients(true);
    seg.setModelType(pcl::SACMODEL_PLANE);
    seg.setMethodType(pcl::SAC_RANSAC);
    seg.setDistanceThreshold(0.01);
    seg.setInputCloud(cloud);
    seg.segment(*inliers, *coefficients);

    if (inliers->indices.size() == 0) {
        PCL_ERROR("Could not estimate a plane model.\n");
        return -1;
    }

    // 提取地面点云
    pcl::ExtractIndices<pcl::PointXYZ> extract;
    extract.setInputCloud(cloud);
    extract.setIndices(inliers);
    extract.setNegative(false);
    extract.filter(*ground);

    // 使用NormalEstimation计算地面点云的法线
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
    ne.setInputCloud(ground);
    ne.setSearchMethod(tree);
    ne.setKSearch(50);
    ne.compute(*normals);

    // 将位置信息和法线信息合并到cloud_with_normals中
    pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointXYZINormal>);
    pcl::concatenateFields(*ground, *normals, *cloud_with_normals);

    // 初始化GreedyProjectionTriangulation并设置参数
    pcl::GreedyProjectionTriangulation<pcl::PointXYZINormal> gp3;
    gp3.setSearchRadius(1);
    gp3.setMu(3.0);
    gp3.setMaximumNearestNeighbors(150);
    gp3.setMaximumSurfaceAngle(M_PI / 3);
    gp3.setMinimumAngle(M_PI / 18);
    gp3.setMaximumAngle(2 * M_PI / 3);
    gp3.setNormalConsistency(false);

    // 创建搜索树
    pcl::search::KdTree<pcl::PointXYZINormal>::Ptr tree2(new  pcl::search::KdTree<pcl::PointXYZINormal>);
    tree2->setInputCloud(cloud_with_normals);

    // 执行三角化
    //pcl::PolygonMesh triangles;
    //gp3.setInputCloud(cloud_with_normals);
    //gp3.setSearchMethod(tree2);
    //gp3.reconstruct(triangles);
    
    pcl::PolygonMesh triangles;
    gp3.setInputCloud(cloud_with_normals);
    gp3.setSearchMethod(tree2);
    gp3.reconstruct(triangles);

    

    // 可视化
    //pcl::visualization::PCLVisualizer viewer("3D Viewer");
    //viewer.setBackgroundColor(0, 0, 0);
    //viewer.addPointCloud<pcl::PointXYZ>(ground, "ground_cloud");
    //viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "ground_cloud");
    
    // 确保使用的ID与设置属性时使用的ID相匹配
    //std::string mesh_id = "mesh";
    //viewer.addPolygonMesh(triangles, mesh_id);

    // 添加三角网格到可视化窗口,并设置网格的颜色和样式
    //viewer.addPolygonMesh(triangles, "mesh");
    // 设置网格的颜色为红色,提高可视化效果
    //viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.0, 0.0, "mesh");
    // 增加网格的线宽,使其更加明显
    //viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, 2, "mesh");
    
    //可视化2
    pcl::visualization::PCLVisualizer viewer("3D Viewer");
    viewer.setBackgroundColor(0, 0, 0);
    viewer.addPointCloud<pcl::PointXYZ>(cloud, "cloud");

    std::string mesh_id = "mesh_" + std::to_string(std::time(nullptr)); // 生成唯一ID
    viewer.addPolygonMesh(triangles, mesh_id);
    viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.0, 0.0, mesh_id);
    viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, 2, mesh_id);
    
    
    // 保存三角网到VTK文件
    pcl::io::saveVTKFile("/home/dzz/pcl_project/data/mesh.vtk", triangles);

    

        

    while (!viewer.wasStopped()) {
        viewer.spin();
    }

    return 0;
}

3.然后就是修改CMakeList.txt文件,我的文件内容是这样的

cmake_minimum_required(VERSION 3.0)

# 设置项目名称和版本
project(RANSACSegmentation)

# 指定C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 寻找PCL库
find_package(PCL 1.8 REQUIRED COMPONENTS common io visualization filters segmentation surface)

# 包含PCL库的头文件目录
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

# 添加可执行文件
add_executable(ransac /home/dzz/pcl_project/src/ransac.cpp)

# 链接PCL库到可执行文件
target_link_libraries(ransac ${PCL_LIBRARIES})

# 如果PCL找到了,打印一些信息
message(STATUS "Found PCL libraries: ${PCL_LIBRARIES}")
message(STATUS "Found PCL includes: ${PCL_INCLUDE_DIRS}")

4.然后就是执行编译

在自己的src目录下执行

mkdir build

cd build

cmake ..

make

5.编译完成之后,查看/data/mesh.vtk

6.查看VTK文件

6.1需要安装paraview进行可视化三角网结构。安装链接:Download ParaView

然后下载linux版本,复制到usr/local下,执行解压后安装

6.2安装指导:Paraview安装两种方法(ubuntu系统下)-CSDN博客

6.3打开终端之后,运行paraview。打开终端,输入 Paraiew。就可以打开了。

6.4加载自己mesh.vtk文件,然后修改Wireframe-->surface,就可以显示出来三角网了,但是还是做一些调整使得三角网结构更加的明显一些。

补充内容:三角网结构更加明显一点的做法:

这里如果在/src/ransac下设置三角网的参数比较小的话在可视化里面的三角形比较小和数量少,看起来会比较不明显,所以测试的话可以把这里的参数修改的大一些:

这里我就是把setSearchRadius()里面的参数:1-->0.05

   // 初始化GreedyProjectionTriangulation并设置参数
    pcl::GreedyProjectionTriangulation<pcl::PointXYZINormal> gp3;
    gp3.setSearchRadius(1); //搜索半径
    gp3.setMu(3.0);
    gp3.setMaximumNearestNeighbors(150);
    gp3.setMaximumSurfaceAngle(M_PI / 3);
    gp3.setMinimumAngle(M_PI / 18);
    gp3.setMaximumAngle(2 * M_PI / 3);
    gp3.setNormalConsistency(false);

        --------------------主要是可以调整搜索半径的大小。--------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值