焦小花同学

PCL:点云处理的终极解决方案,机器视觉必备

Image

等你来关注!

PCL:点云处理的终极解决方案,机器视觉必备

点云,简单来说就是一堆在三维空间里的点,它们能描述物体的形状、大小、甚至纹理。PCL(Point Cloud Library)是一个专注于点云处理的开源库,如果你需要在机器视觉中处理点云数据,它绝对是个好帮手。接下来,我们聊聊 PCL 的一些基础知识和开发技巧。

点云的读取与可视化

Image

处理点云的第一步是搞清楚怎么读数据。PCL 支持多种点云格式,比如 PCD 和 PLY。以下是读取一个点云文件并简单可视化的代码:

#include <pcl/io/pcd_io.h>

#include <pcl/visualization/cloud_viewer.h>

int main() {

// 创建点云对象

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

// 读取 PCD 文件

if (pcl::io::loadPCDFile<pcl::PointXYZ>(“example.pcd”, *cloud) == -1) {

PCL_ERROR(“读取文件失败!\n”);

return -1;

}

// 创建可视化窗口

pcl::visualization::CloudViewer viewer(“点云可视化”);

viewer.showCloud(cloud);

// 防止窗口直接关闭

while (!viewer.wasStopped()) {}

return 0;

}

这个例子干了三件事:加载点云文件、创建可视化窗口、把点云显示出来。运行后,你会看到一个窗口,里面就是你的三维点云模型。 小提醒:文件路径要对!不然你会看到一堆报错,让人头疼。

点云滤波:让数据更精致

Image

点云数据通常很“脏”,可能有噪点、冗余点。滤波就是清理这些数据的过程。PCL 提供了很多滤波算法,比如体素网格降采样。看代码:

#include <pcl/filters/voxel_grid.h>

void downsamplePointCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud) {

pcl::VoxelGrid<pcl::PointXYZ> voxelFilter;

voxelFilter.setInputCloud(cloud);

voxelFilter.setLeafSize(0.01f, 0.01f, 0.01f);// 设置体素大小

pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud(new pcl::PointCloud<pcl::PointXYZ>);

voxelFilter.filter(*filteredCloud);

std::cout << “降采样后点数:” << filteredCloud->size() << std::endl;

}

这个代码的核心是 VoxelGrid,它会把原始点云切成很多小格子,每个格子只保留一个点。结果?点云数据量大大减少,但仍保留了大致形状。 温馨提示:体素大小别太大,不然你的点云可能会变成“马赛克”。

点云分割:提取你要的部分

Image

很多时候,点云里有很多你根本不需要的部分,比如背景或噪声。分割能帮你把有用的部分提取出来。比如平面提取:

#include <pcl/segmentation/sac_segmentation.h>

#include <pcl/filters/extract_indices.h>

void segmentPlane(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud) {

pcl::SACSegmentation<pcl::PointXYZ> seg;

seg.setModelType(pcl::SACMODEL_PLANE);

seg.setMethodType(pcl::SAC_RANSAC);

seg.setDistanceThreshold(0.01);

pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);

pcl::PointIndices::Ptr inliers(new pcl::PointIndices);

seg.setInputCloud(cloud);

seg.segment(*inliers, *coefficients);

if (inliers->indices.empty()) {

std::cerr << “没找到平面!” << std::endl;

return;

}

pcl::ExtractIndices<pcl::PointXYZ> extract;

extract.setInputCloud(cloud);

extract.setIndices(inliers);

extract.setNegative(false);// 保留平面点

pcl::PointCloud<pcl::PointXYZ>::Ptr planeCloud(new pcl::PointCloud<pcl::PointXYZ>);

extract.filter(*planeCloud);

std::cout << “平面点数:” << planeCloud->size() << std::endl;

}

这段代码用 RANSAC 算法提取平面。RANSAC 是个很聪明的算法,它能在一堆数据里找到符合某种模型的部分,哪怕有噪声。 小陷阱:距离阈值太小会漏掉很多点,太大又会把不相关的点也算进去。调参数很重要!

写在后面

Image

PCL 是个强大的工具箱,能让点云处理变得高效而优雅。从读取到滤波,再到分割,这只是冰山一角。点云处理的世界很大,我觉得越学越上瘾,甚至有点停不下来。

E

N

D

Image

Image

分享

Image

收藏

Image

在看

点赞