当前位置: 首页 > news >正文

PCL—voxel点云网格化

在PCL(Point Cloud Library)中,Voxel(体素) 是一个核心概念,用于将三维点云数据离散化到规则的网格结构中。其意义主要体现在以下几个方面:

1. 点云降采样(Downsampling)

• 数据压缩:点云通常包含大量冗余数据(例如数百万个点),直接处理效率低。通过将点云划分为体素网格,每个体素内的点被合并为一个代表性点(如取中心点或平均值),可显著减少数据量,同时保留整体形状特征。

• 加速计算:降采样后的点云适用于需要快速迭代的场景(如配准、分割、目标检测),可降低算法复杂度。

代码示例。

pcl::VoxelGrid<pcl::PointXYZ> voxel;
voxel.setInputCloud(cloud);
voxel.setLeafSize(0.01f, 0.01f, 0.01f); // 设置体素边长(单位:米)
voxel.filter(*downsampled_cloud);

2. 去噪与平滑

• 统计滤波:结合体素内点的分布统计(如密度、方差),可过滤离群噪点。

• 均匀化分布:体素化可消除点云密度不均的问题(例如激光雷达近处密集、远处稀疏的特性)

3. 特征提取与结构表示

• 几何特征保留:体素化后的规则结构便于计算表面法线、曲率等特征。

• 深度学习输入:体素网格可直接转换为3D卷积神经网络(如VoxelNet)的输入张量,用于分类、分割等任务。

• 八叉树(Octree):基于体素的分层数据结构,支持快速空间查询(如近邻搜索、碰撞检测)

4. 点云配准(Registration)

• 粗配准加速:降采样后的点云可快速计算初始变换(如使用ICP算法的粗略对齐阶段)。

• 多分辨率配准:结合不同体素尺寸的层次化处理,提升配准精度和效率。

5. 三维重建与表面生成

• 隐式曲面重建:体素化后可通过TSDF(Truncated Signed Distance Function)等算法生成连续的表面模型(如用于SLAM或三维打印)。

• 体积渲染:在医学成像或科学可视化中,体素可直接表示密度、颜色等体数据。

6. 存储与索引优化

• 空间索引:体素将无序点云映射到规则网格,便于基于空间位置的快速检索(如查找某区域内的点)。

• 压缩存储:某些格式(如.pcd或.xyz)支持体素化后的紧凑存储。

注意事项

• 体素尺寸选择:过大的体素会丢失细节,过小则无法有效降采样。需根据应用场景和传感器精度调整(例如,激光雷达点云常用0.01-0.1米边长)。

• 权衡效率与精度:体素化是计算效率与几何保真度之间的折中方案,需根据任务需求调整策略。

总结

Voxel化通过将点云从无序散点转换为规则结构,解决了大规模点云处理中的效率、噪声和密度不均等问题,是3D计算机视觉、机器人感知和三维重建中的基础操作。

以下是个代码例子。

//摘自PCL(Point Cloud Library)学习记录(2025) · 语雀
​
/*
 * @Description: 2VoxelGrid滤波器对点云进行下采样    https://www.cnblogs.com/li-yao7758258/p/6445831.html
 * @Author: HCQ
 * @Company(School): UCAS
 * @Email: 1756260160@qq.com
 * @Date: 2020-10-20 10:50:23
 * @LastEditTime: 2020-10-20 11:00:48
 * @FilePath: /pcl-learning/09filters滤波/2VoxelGrid滤波器对点云进行下采样/voxel_grid.cpp
 */
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>

//#include "visual_.h"

int main(int argc, char** argv)
{

    pcl::PCLPointCloud2::Ptr cloud(new pcl::PCLPointCloud2());
    pcl::PCLPointCloud2::Ptr cloud_filtered(new pcl::PCLPointCloud2());

    //点云对象的读取
    pcl::PCDReader reader;

    reader.read("D:/tool_s/PCL/pcl-pcl-1.11.1/test/office1.pcd", *cloud);    //读取点云到cloud中

    std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height
        << " data points (" << pcl::getFieldsList(*cloud) << ").";


    //show//

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz0(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPCLPointCloud2(*cloud, *cloud_xyz0);
    //pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("03D_Viewer"));
    //viewer->setBackgroundColor(0, 0, 0);
    //viewer->addPointCloud<pcl::PointXYZ>(cloud_xyz0, "0sample_cloud");
    //viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "0sample_cloud");
    //viewer->addCoordinateSystem(1.0, "global");
    //
//    showCloud_sn(cloud_xyz0, 0);



    /******************************************************************************
    创建一个voxel叶大小为1cm的pcl::VoxelGrid滤波器,
  **********************************************************************************/
    pcl::VoxelGrid<pcl::PCLPointCloud2> sor;  //创建滤波对象
    sor.setInputCloud(cloud);            //设置需要过滤的点云给滤波对象
    sor.setLeafSize(0.1f, 0.1f, 0.1f);  //设置滤波时创建的体素体积为1cm的立方体(0.01f, 0.01f, 0.01f)
    sor.filter(*cloud_filtered);           //执行滤波处理,存储输出

    std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
        << " data points (" << pcl::getFieldsList(*cloud_filtered) << ").";


    //保存
    //pcl::PCDWriter       writer;   //保存极慢!//
    //writer.write("../table_scene_lms400_downsampled.pcd", *cloud_filtered,
    //    Eigen::Vector4f::Zero(), Eigen::Quaternionf::Identity(), false);

     //pcl::io::savePCDFile("saveName.pcd", *cloud);

    //show//
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPCLPointCloud2(*cloud_filtered, *cloud_xyz);
//    showCloud_s0(cloud_xyz,"001");

    return (0);
}

代码中的visual可视化部分可参考我的另一篇文章:PCL—点云加载、可视化-CSDN博客

相关文章:

  • 软件功能性测试工具有哪些?专业软件测试服务推荐
  • 深入解析嵌入式内核:从架构到实践
  • 2025红明谷writeup
  • 【零基础学python】python基础语法(二)
  • UE4学习笔记 FPS游戏制作15修正可以换枪中可以继续换枪和开火的Bug
  • 大数据Trino面试题及参考答案
  • SQL Server行转列操作及PIVOT运算符
  • react 大屏根据屏幕分辨率缩放
  • Qt 重入和线程安全
  • 【线程安全问题的原因和方法】【java形式】【图片详解】
  • 深入理解 tree 命令行工具:目录结构可视化的利器
  • LeetCode hot 100 每日一题(15)——48.旋转图像
  • python --face_recognition(人脸识别,检测,特征提取,绘制鼻子,眼睛,嘴巴,眉毛)/活体检测
  • vue数据重置
  • RFID测温技术:提升电缆安全监测的理想选择
  • docker pull时报错:https://registry-1.docker.io/v2/
  • 开源链动2+1模式与AI智能名片赋能的S2B2C共享经济新生态
  • 批量配置Linux ~/.bash_profile
  • 医学图像分割数据集肺分割数据labelme格式6299张2类别
  • 数据库基础知识点(系列二)
  • 电话费被私改成48元套餐长达数年,投诉后移动公司退补600元话费
  • 西班牙葡萄牙遭遇史上最严重停电:交通瘫了,通信崩了,民众疯抢物资
  • 柴德赓、纪庸与叫歇碑
  • 稳就业稳经济五方面若干举措将成熟一项出台一项
  • 清华姚班,正走出一支军团
  • 这场迪图瓦纪念拉威尔的音乐会,必将成为乐迷反复品味的回忆