3D视觉学习计划之点云的滤波

3D视觉学习计划之点云的滤波

前言

点云滤波是一种用于去除点云数据中噪声和异常值的技术。点云数据通常由激光雷达或摄像头等设备采集,由于设备本身的误差或环境因素的影响,采集到的数据中可能会包含一些噪声和异常值。这些噪声和异常值会影响后续的点云处理和分析,因此需要进行滤波处理。
点云滤波的主要方法包括:体素滤波器(Voxel Grid Filter)、半径滤波器(Radius Outlier Removal)、统计滤波器(Statistical Outlier Removal)、直通滤波器和双边滤波等方法,接下来对各种点云滤波方法进行操作。

一、直通滤波器

1.概念
点云滤波中,直通滤波器是一种简单的滤波方法,用于去除点云数据中的离群点。直通滤波器通过设置一个范围,将点云数据中不在该范围内的点过滤掉。这个范围可以是一个固定的数值,也可以是根据点云数据的统计特征动态计算得出的。直通滤波器适用于需要去除点云数据中的离群点,但不需要对点云数据进行过多处理的场景,例如点云数据的可视化等。
2.示例代码
python版本

import open3d as o3d
import numpy as np

# 读取点云数据
pcd = o3d.io.read_point_cloud("/home/cj/chaintwork/pcl/code/filtering/py-test/ism_test_horse.pcd")

# 创建一个AxisAlignedBoundingBox对象
bbox = o3d.geometry.AxisAlignedBoundingBox(min_bound=np.array([0, 0, 0]), max_bound=np.array([1000.0, 1000.0, 1000.0]))

# 进行直通滤波
pass_through = pcd.crop(bbox)
# 检查点云数据中的点数
print(len(pass_through.points))

# 保存输出点云数据
o3d.io.write_point_cloud("1.pcd", pass_through)

# 可视化输出点云数据
o3d.visualization.draw_geometries([pass_through])

在这里插入图片描述
C++版本
代码:

#include <iostream>  // 包含输入输出流库
#include <pcl/io/pcd_io.h>  // 包含点云读写库
#include <pcl/filters/passthrough.h>  // 包含直通滤波库
#include <pcl/visualization/cloud_viewer.h>  // 包含点云可视化库

int main(int argc, char** argv)
{
    // 读取点云数据
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  // 定义点云指针
    if (pcl::io::loadPCDFile<pcl::PointXYZ>("path/to/input.pcd", *cloud) == -1)  // 读取点云数据
    {
        PCL_ERROR("Could not read file\n");  // 输出错误信息
        return -1;  // 返回错误代码
    }

    // 进行直通滤波
    pcl::PassThrough<pcl::PointXYZ> pass;  // 定义直通滤波器
    pass.setInputCloud(cloud);  // 设置输入点云
    pass.setFilterFieldName("x");  // 设置过滤字段
    pass.setFilterLimits(-1.0, 1.0);  // 设置过滤范围
    pcl::PointCloud<pcl::PointXYZ>::Ptr pass_through(new pcl::PointCloud<pcl::PointXYZ>);  // 定义输出点云指针
    pass.filter(*pass_through);  // 进行直通滤波

    // 保存输出点云数据
    pcl::io::savePCDFileASCII("path/to/output.pcd", *pass_through);  // 保存输出点云数据

    // 可视化输出点云数据
    pcl::visualization::CloudViewer viewer("Cloud Viewer");  // 定义点云可视化器
    viewer.showCloud(pass_through);  // 显示输出点云数据
    while (!viewer.wasStopped())  // 循环等待直到可视化窗口关闭
    {
    }

    return 0;  // 返回正常退出代码
}

Pro文件内容:

TEMPLATE = app
CONFIG += console c++14
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += \
        main.cpp

INCLUDEPATH += .\
            /usr/local/include/pcl-1.13 \
            /usr/include/eigen3 \
            /usr/include/vtk-7.1 \
            /usr/include/boost

LIBS += /usr/local/lib/lib* \
        /usr/lib/x86_64-linux-gnu/libpcl_*.so \
        /usr/lib/x86_64-linux-gnu/libvtk*.so \
        /usr/lib/x86_64-linux-gnu/libboost_*.so

结果
在这里插入图片描述

二、体素滤波器

1.概念
体素滤波是点云滤波中的一种方法,也称为体元滤波或体素化滤波。它的原理是将点云数据划分为一个个小的立方体单元,称为体素,然后对每个体素内的点进行处理,以达到滤波的目的。具体来说,体素滤波将每个体素内的点的坐标取平均值,作为该体素的中心点的坐标,从而实现对点云数据的平滑处理。体素滤波的优点是简单易用,可以有效地去除点云数据中的离群点和噪声,但也会导致点云数据的细节丢失。
2.示例代码
python版本

#######体素滤波#########
import open3d as o3d
import numpy as np

# Read point cloud data
pcd = o3d.io.read_point_cloud("/home/cj/chaintwork/pcl/code/filtering/py-test/ism_test_horse.pcd")

# Define the voxel size
voxel_size = 0.05

# Perform voxel downsampling
downsampled = pcd.voxel_down_sample(voxel_size)

# Save the output point cloud data
o3d.io.write_point_cloud("voxel.pcd", downsampled)

# Visualize the output point cloud data
o3d.visualization.draw_geometries([downsampled])

结果
在这里插入图片描述
C++版本代码

#include <string>
#include <iostream>

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/cloud_viewer.h>

int main(int argc, char** argv)
{
    // 读取点云数据
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PCDReader reader;
    reader.read<pcl::PointXYZ>("/home/cj/chaintwork/pcl/code/filtering/filtering/filter/ism_test_horse.pcd", *cloud);

    // 定义体素大小
    float voxel_size = 0.05;

    // 执行体素滤波
    pcl::VoxelGrid<pcl::PointXYZ> sor;
    sor.setInputCloud(cloud);
    sor.setLeafSize(voxel_size, voxel_size, voxel_size);
    pcl::PointCloud<pcl::PointXYZ>::Ptr downsampled(new pcl::PointCloud<pcl::PointXYZ>);
    sor.filter(*downsampled);

    // 保存输出点云数据
    pcl::io::savePCDFileASCII("output.pcd", *downsampled);

    // 可视化输出点云数据
    pcl::visualization::CloudViewer viewer("Cloud Viewer");
    viewer.showCloud(downsampled);
    while (!viewer.wasStopped())
    {
    }

    return 0;
}

Pro文件同上,结果
在这里插入图片描述

三、半径滤波器

1.概念
半径滤波是点云处理中的一种滤波方法,它可以通过移除点云中距离某个点过远的点来减少噪声。
2.示例代码
python版本

import open3d as o3d

# 读取点云数据
pcd = o3d.io.read_point_cloud("/home/cj/chaintwork/pcl/code/filtering/py-test/ism_test_horse.pcd")

# 定义半径和最小邻居数
radius = 5
min_neighbors = 10

# 执行半径滤波
pcd_filtered, _ = pcd.remove_radius_outlier(nb_points=min_neighbors, radius=radius)

# 保存输出点云数据
o3d.io.write_point_cloud("P_Radius.pcd", pcd_filtered)

# 可视化输出点云数据
o3d.visualization.draw_geometries([pcd_filtered])

结果
在这里插入图片描述

C++版本

#include <iostream>
#include <string>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/cloud_viewer.h>

int main(int argc, char** argv)
{
    // 读取点云数据
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PCDReader reader;
    reader.read<pcl::PointXYZ>("/home/cj/chaintwork/pcl/code/filtering/filtering/filter/ism_test_horse.pcd", *cloud);

    // 定义半径和最小邻居数
    float radius = 5;
    int min_neighbors = 10;

    // 执行半径滤波
    pcl::RadiusOutlierRemoval<pcl::PointXYZ> sor;
    sor.setInputCloud(cloud);
    sor.setRadiusSearch(radius);
    sor.setMinNeighborsInRadius(min_neighbors);
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);
    sor.filter(*filtered);

    // 保存输出点云数据
    pcl::PCDWriter writer;
    writer.write<pcl::PointXYZ>("C_Radius.pcd", *filtered);

    // 可视化输出点云数据
    pcl::visualization::PCLVisualizer viewer("Radius Outlier Removal");
    viewer.addPointCloud<pcl::PointXYZ>(filtered, "filtered cloud");
    while (!viewer.wasStopped())
    {
        viewer.spinOnce();
    }

    return 0;
}

结果
在这里插入图片描述

四、统计滤波器

1.概念
在点云处理中,统计滤波器是一种基于统计学原理的滤波方法,它可以通过计算点云中每个点周围邻居点的统计特征来判断该点是否为离群点,并将其从点云中移除。常见的统计滤波器包括高斯滤波器、均值滤波器、中值滤波器等。
2.代码示例

python版本

import open3d as o3d

# 读取点云数据
pcd = o3d.io.read_point_cloud("/home/cj/chaintwork/pcl/code/filtering/py-test/ism_test_horse.pcd")

# 定义体素大小
voxel_size = 0.05

# 执行统计滤波
pcd_filtered = pcd.voxel_down_sample(voxel_size=voxel_size)

# 保存输出点云数据
o3d.io.write_point_cloud("output.pcd", pcd_filtered)

# 可视化输出点云数据
o3d.visualization.draw_geometries([pcd_filtered])

在这里插入图片描述
C++版本

#include <iostream>
#include <string>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/cloud_viewer.h>

int main(int argc, char** argv)
{
    // 读取点云数据
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile<pcl::PointXYZ>("/home/cj/chaintwork/pcl/code/filtering/filtering/filter/ism_test_horse.pcd", *cloud);

    // 定义统计滤波器

    pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
    sor.setInputCloud(cloud);
    sor.setMeanK(50); // 设置统计滤波器的K值
    sor.setStddevMulThresh(1.0); // 设置统计滤波器的标准差倍数阈值

    // 执行统计滤波
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    sor.filter(*cloud_filtered);

    // 保存输出点云数据
    pcl::io::savePCDFileASCII("output.pcd", *cloud_filtered);

    // 可视化输出点云数据
    pcl::visualization::PCLVisualizer viewer("PointCloud Viewer");
    viewer.setBackgroundColor(0.0, 0.0, 0.0);
    viewer.addPointCloud<pcl::PointXYZ>(cloud_filtered, "cloud");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud");
    viewer.addCoordinateSystem(1.0);
    viewer.initCameraParameters();
    while (!viewer.wasStopped())
    {
        viewer.spinOnce();
    }

    return 0;
}

在这里插入图片描述

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小俊俊的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值