【点云处理教程】04 Python 中的点云过滤

news2024/9/22 3:48:42

一、说明

        这是我的“点云处理”教程的第 4 篇文章。“点云处理”教程对初学者友好,我们将在其中简单地介绍从数据准备到数据分割和分类的点云处理管道。

        在本教程中,我们将学习如何使用 Open3D 在 python 中过滤点云以进行下采样和异常值去除。使用 Open3D 进行点云预处理

  • 第1条:点云处理简介
  • 文章2:在Python中从深度图像估计点云
  • 文章3:了解点云:使用Python实现地面检测
  • 文章4:Python中的点云过滤
  • 文章 5 : Python 中的点云分割

二、 简介

        由于所使用的3D扫描仪(如结构光扫描仪)或捕获的场景(包括吸收红外光的材料)的性质,计算或收集的点云有时会产生噪声。另一方面,一些算法和/或计算机视觉技术对噪声很敏感,例如估计表面法线和曲率变化。

        为了降低噪音,使用了滤波技术。一些滤波器还用于降低点云密度,从而减少计算时间。在本文中,我们将看到一些常见的过滤器,即:直通滤波器、统计异常值去除滤波器、半径异常值去除滤波器和下采样滤波器。

2.2  直通滤波器

        直通筛选器对输入数据应用约束,这些约束通常是阈值或间隔。对于点云,如果一个点满足约束,则点通过过滤器,这些约束主要是沿一个或多个轴的间隔。为了降低噪声,间隔通常根据输入设备的性质和状态进行固定:深度数据在间隔内更准确,否则会变得更加嘈杂。直通滤波器不仅可用于滤除噪声输入,还可用于减少数据,例如考虑最近的点。

        在版本 0.7.0 之前,Open3D 支持以下功能:crop_point_cloud(input, min_bound, max_bound)

input是输入点云。

min_bound是点坐标的最小界限。

max_bound是点坐标的最大边界。

返回区间内点的点云。

        例如,要过滤点云以减少沿 Z 轴的噪声,请考虑间隔。对于 X 轴和 Y 轴,我们将边界设置为无穷大,因为我们没有沿着它们进行过滤:[0.8, 3]

from open3d import *
import math
import numpy as np

cropped = crop_point_cloud(pcd, 
                          min_bound=np.array([-math.inf, -math.inf, 0.8]), 
                          max_bound=np.array([math.inf, math.inf, 3]))

        在0.7.0版本之后,可以使用裁剪点云的方法。与前面的函数类似,此方法返回裁剪的点云。为此,我们首先创建一个边界框,其中包含将要考虑的点。此边界框是根据区间边界的组合创建的(请参见)。在这里,我们只沿 Z 轴过滤:仅返回其 z 坐标之间的点。最后,使用创建的边界框对象裁剪输入点云:crop(bounding_box)open3d.geometry.PointCloudbounding_box_points[0.8, 2]

import numpy as np
import open3d as o3d
import math
import itertools

if __name__ == '__main__':
    # Read point cloud:
    pcd = o3d.io.read_point_cloud("../data/depth_2_pcd.ply")

    # Create bounding box:
    bounds = [[-math.inf, math.inf], [-math.inf, math.inf], [0.8, 2]]  # set the bounds
    bounding_box_points = list(itertools.product(*bounds))  # create limit points
    bounding_box = o3d.geometry.AxisAlignedBoundingBox.create_from_points(
        o3d.utility.Vector3dVector(bounding_box_points))  # create bounding box object

    # Crop the point cloud using the bounding box:
    pcd_croped = pcd.crop(bounding_box)

    # Display the cropped point cloud:
    o3d.visualization.draw_geometries([pcd_croped])

生成的点云如下所示:

 
灰色:输入点云。绿色:生成的点云

 

 

2.3 下采样

        下采样点云包括减少点数。例如,它通常用于减少处理步骤的运行时间或选择确切数量的点进行训练。

        Open3D 库提供了三种不同的方法来降低采样点云:

  • random_down_sample(pcd, sampling_ratio):从输入点云中选择随机点。它可用于数据增强,因为每次都会选择不同的点。但是,它对噪音很敏感:可以选择它。n*sampling_ratiopcd
  • uniform_down_sample(every_k_points):根据点的顺序统一选择点。它在每个点选择一个点。始终选择第一个点(标记为 0)。因此,所选点的索引为:0、、2 * 等。如果输入点云是有组织的,则该函数返回均匀的点云;否则,它类似于第一种方法,只是每次都生成相同的输出。every_k_pointsevery_k_pointsevery_k_points
  • voxel_down_sample(voxel_size):创建 3D 体素网格。体素格网将输入划分为一组××体素。每个体素都包含属于 3 个轴的相同间隔的点。然后对属于同一体素的点进行下采样并替换为其质心。此过滤器用于减小点云的大小并使其平滑。但是,这很耗时,因为它在将点云重组为体素后计算质心,并且对异常值很敏感。voxel_sizevoxel_sizevoxel_size

现在,让我们测试所有这些方法并显示生成的点云。为了获得更好的可视化效果,我们分别设置为 、to 和 for 和 。最后,我们应用平移在同一窗口中分别显示所有点云。sampling_ratio0.005every_k_points200voxel_size0.4random_down_sampleuniform_down_samplevoxel_down_sample

import open3d as o3d
import numpy as np

if __name__ == '__main__':
    # Read point cloud:
    pcd = o3d.io.read_point_cloud("../data/depth_2_pcd.ply")

    # Random down-sampling:
    random_pcd = pcd.random_down_sample(sampling_ratio=0.005)

    # Uniform down-sampling:
    uniform_pcd = pcd.uniform_down_sample(every_k_points=200)

    # Voxel down-sampling:
    voxel_pcd = pcd.voxel_down_sample(voxel_size=0.4)

    # Translating point clouds:
    points = np.asarray(random_pcd.points)
    points += [-3, 3, 0]
    random_pcd.points = o3d.utility.Vector3dVector(points)

    points = np.asarray(uniform_pcd.points)
    points += [0, 3, 0]
    uniform_pcd.points = o3d.utility.Vector3dVector(points)

    points = np.asarray(voxel_pcd.points)
    points += [3, 3, 0]
    voxel_pcd.points = o3d.utility.Vector3dVector(points)

    # Display:
    o3d.visualization.draw_geometries([pcd, random_pcd, uniform_pcd, voxel_pcd])

有组织的点云下采样。上图:输入点云。向下,从左到右:随机下采样、均匀下采样和基于体素的下采样。

 

         请注意,该方法生成的点云均匀分布在 3D 空间中。这是因为输入是一个有组织的点云(点在列表中组织)。uniform_down_sample

让我们通过洗牌前一个点云的点来创建无组织的点云,如下所示:

points = np.asarray(pcd.points)
np.random.shuffle(points)
u_pcd= o3d.geometry.PointCloud()
u_pcd.points= o3d.utility.Vector3dVector(points)

        然后与前面的示例类似,我们应用不同的下采样方法并显示结果。可视化窗口如下所示:u_pcd

 
 无组织的点云下采样。上图:输入点云。向下,从左到右:随机下采样、均匀下采样和基于体素的下采样。

 

         在这里,该方法得到的点云在3D空间中分布不均匀。它看起来更像是随机下采样,因为这些点是无组织的。但是,返回相同的点云,因为它将点重组为 3D 网格。uniform_down_samplevoxel_down_sample

2.4. 异常值去除过滤器

  • 半径异常值移除是一种条件过滤器,用于移除给定半径的球体内相邻点数少于给定数量的每个点。Open3D 提供了以下方法:remove_radius_outlier(nb_points, radius)

nb_points是邻居的数量。

radius是球体半径。

返回:过滤点云的元组和内变量索引的列表。

  • 统计异常值移除过滤器可移除距离其相邻点较远的点。对于每个点,计算从它到其所有相邻点的平均距离。然后,如果点的平均距离超出由全局距离平均值和标准差定义的区间,则该点是异常值。Open3D 提供了以下方法: [2]:remove_statistical_outliers(nb_neighbors, std_ratio)

nb_neighbors是邻居的数量。

std_ratio是标准偏差比。

返回:过滤点云的元组和内变量索引的列表。

让我们测试这两种方法并显示生成的点云。为了减少运行时间,我们首先应用下采样。应用异常值去除过滤器后,我们使用 .我们设置反转索引的选择。select_by_index(index, invert)invertTrue

import open3d as o3d
import numpy as np

if __name__ == '__main__':
    # Read point cloud:
    pcd = o3d.io.read_point_cloud("../data/depth_2_pcd.ply")
    # Down sampling to reduce the running time:
    pcd = pcd.voxel_down_sample(voxel_size=0.02)

    # Radius outlier removal:
    pcd_rad, ind_rad = pcd.remove_radius_outlier(nb_points=16, radius=0.05)
    outlier_rad_pcd = pcd.select_by_index(ind_rad, invert=True)
    outlier_rad_pcd.paint_uniform_color([1., 0., 1.])

    # Statistical outlier removal:
    pcd_stat, ind_stat = pcd.remove_statistical_outlier(nb_neighbors=20,
                                                 std_ratio=2.0)
    outlier_stat_pcd = pcd.select_by_index(ind_stat, invert=True)
    outlier_stat_pcd.paint_uniform_color([0., 0., 1.])

    # Translate to visualize:
    points = np.asarray(pcd_stat.points)
    points += [3, 0, 0]
    pcd_stat.points = o3d.utility.Vector3dVector(points)

    points = np.asarray(outlier_stat_pcd.points)
    points += [3, 0, 0]
    outlier_stat_pcd.points = o3d.utility.Vector3dVector(points)

    # Display:
    o3d.visualization.draw_geometries([pcd_stat, pcd_rad, outlier_stat_pcd, outlier_rad_pcd])

点云异常值去除。左:半径滤波器。右:统计过滤器。

三、 结论

        为此,我们引入了最著名的点云过滤器。这些过滤器在 Open3D 中实现。它们也在其他一些点云库中实现,例如 PCL。在大多数实时应用中,尤其是对于密集点云,需要过滤和减小点云的大小。下一个教程将讨论点云分割。您将看到,您可以仅使用一些Python库来简单地执行此操作。

四、引用

[1]open3d.geometry.crop_point_cloud

[2]open3d.geometry.PointCloud — Open3D 0.17.0 documentation

柴玛·扎特

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/811842.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【GitOps系列】在 GitOps 工作流中实现蓝绿发布

文章目录 前言蓝绿发布概述手动实现蓝绿发布创建蓝色环境创建蓝色环境 Ingressroute部署绿色环境切换到绿色环境 蓝绿发布自动化安装 Argo Rollout创建 Rollout 对象创建 Service 和 Ingress访问蓝色环境发布自动化 访问 Argo Rollout Dashboard自动化原理结语 前言 在前几篇【…

Netty学习(四)

文章目录 四. 优化与源码1. 优化1.1 扩展序列化算法jdk序列化与反序列化Serializer & AlgorithmConfigapplication.properties MessageCodecSharableMessage(抽象类) 测试序列化测试反序列化测试 1.2 参数调优1)CONNECT_TIMEOUT_MILLIS2&…

最强,自动化测试-自定义日志类及日志封装(实战)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 在自定义日志之前…

【机器学习】习题3.3Python编程实现对数几率回归

参考代码 结合自己的理解,添加注释。 代码 导入相关的库 import numpy as np import pandas as pd import matplotlib from matplotlib import pyplot as plt from sklearn import linear_model导入数据,进行数据处理和特征工程 # 1.数据处理&#x…

Windows系统如何修改文件日期属性

winr键,输入powershell,在弹出的命令窗口输入命令,案例如下: file_address E:\_OrderingProject\\PIC1101\ldv1s_0830_ec_result.tiftime_change "07/12/2022 20:42:23" 修改文件创建时间:creationtime $(Get-Item fi…

COMSOL三维Voronoi图泰森多边形3D模型轴压模拟及建模教程

多晶体模型采用三维Voronoi算法生成,试件尺寸为150150300mm棱柱模型,对晶格指定五种不同材料,实现晶格间的差异性。 对试件进行力学模拟,下侧为固定边界,限制z方向的位移,上表面通过给定位移的方式实现轴…

P2P网络NAT穿透原理(打洞方案)

1.关于NAT NAT技术(Network Address Translation,网络地址转换)是一种把内部网络(简称为内网)私有IP地址转换为外部网络(简称为外网)公共IP地址的技术,它使得一定范围内的多台主机只…

某拍房数据采集

某拍房数据采集 某拍房数据采集声明1.逆向目标2.寻找加密位置3.分析加密参数4.python代码书写 某拍房数据采集 声明 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的…

yo!这里是Linux常见命令总结

目录 前言 常见命令 ls指令 pwd指令 cd指令 touch指令 tree指令 mkdir指令&&rmdir指令 rm指令 man指令 cp指令 mv指令 echo指令 cat指令&&tac指令 more指令 less指令 head指令&&tail指令 find指令 grep指令 alias指令&&u…

NAT原理(网络地址转换)

NAT原理 网络地址转换(Network Address Translation,简称NAT) 是一种网络通信协议,它是在网络层上对IP地址进行转换的技术。 NAT技术可以将内部网络中的私有IP地址转换为公共IP地址,以便内部网络中的设备能够访问互…

2023-07-30力扣每日一题

链接: 142. 环形链表 II 题意: 求链表是否有环,并给出入环的点 解: 哈希关联标记或者快慢指针 快慢指针逻辑:设入环前长度a,快慢相遇时指针在b,环长度为c,fast2*slow&#xff…

前端学习--vue2--1-基础配置

写在前面: 好久没写了,做实习每天上班都没啥时间写,1个半月前开始系统学习前端,然后做了半个月主要的前端实习了wk。也行,当复习了,后端也还是搞了点。 本文介绍vue2的一些基础和配置,配置只写…

【C++】——类和对象

目录 面向过程和面向对象的初步认识类的引入类的定义类的访问限定符及封装类的作用域类的实例化this指针类的6个默认成员函数构造函数析构函数 面向过程和面向对象的初步认识 C语言是面向过程的,关注的是过程,分析求解问题的步骤,通过函数调用…

你还不会反射吧,快来吧!!!

首先&#xff1a; 1.加载类&#xff1a; //练习获取字节码对象的3种方式 //Class<Student> studentClass Student.class; //Class<? extends Student> aClass new Student().getClass(); Class<?> clazz Class.forName("TestT.Student"); 2.获…

[C++] 类与对象(上)

目录 1、前言 2、类的引入 3、类的定义 3.1 类的两种定义方式 4、类的访问限定符 5、类的作用域 6、类的实例化 7、类对象模型 7.1 内存对齐规则 7.1 类对象的存储方式 8、this指针 8.1 this指针的特性 8.2 this指针是否可以为空 1、前言 C语言是面向过程的&#…

网络运维基础问题及解答

前言 本篇文章是对于网络运维基础技能的一些常见问题的解答&#xff0c;希望能够为进行期末复习或者对网络运维感兴趣的同学或专业人员提供一定的帮助。 问题及解答 1. 列举 3 种常用字符编码&#xff0c;简述怎样在 str 和 bytes 之间进行编码和解码。 答&#xff1a;常用的…

Python读取多个栅格文件并提取像元的各波段时间序列数据与变化值

本文介绍基于Python语言&#xff0c;读取文件夹下大量栅格遥感影像文件&#xff0c;并基于给定的一个像元&#xff0c;提取该像元对应的全部遥感影像文件中&#xff0c;指定多个波段的数值&#xff1b;修改其中不在给定范围内的异常值&#xff0c;并计算像元数值在每一景遥感影…

【C++】-动态内存管理

作者&#xff1a;小树苗渴望变成参天大树 作者宣言&#xff1a;认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; 文章目录 前言一、C内存管理方式1.1 new/delete操作内置类型 总结 前言 今天再讲一个…

【禁用外键】为什么互联网大厂禁用外键约束?详谈外键的优缺点和使用场景

导航&#xff1a; 【Java笔记踩坑汇总】Java基础进阶JavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线MySQL高级篇设计模式常见面试题源码 目录 一、外键介绍 1.1 概述 1.2 练习 1.2.1 数据准备 1.2.2 验证有外键时&#xff0c;删除记录要维护外键 1.2…

Python批量下载主播照片,实现人脸识别, 进行颜值评分,制作颜值排行榜

昨晚一回家&#xff0c;表弟就神神秘秘的跟我说&#xff0c;发现一个高颜值网站&#xff0c;非要拉着我研究一下她们的颜值高低。 我心想&#xff0c;这还得要我一个个慢慢看&#xff0c;太麻烦了~ 于是反手用Python给他写了一个人脸识别代码&#xff0c;把她们的照片全部爬下…