许可优化
产品
解决方案
服务支持
关于
软件库
当前位置:服务支持 >  软件文章 >  Open3d数据滤波和点云分割

Open3d数据滤波和点云分割

阅读数 4
点赞 0
article_banner

open3d快速上手

索引滤波

所谓的索引滤波压根就不是滤波,只是根据索引,将点选出而已,总共有两种选取方法,一是选取索引对应的点;二是选取索引之外的点。

import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud("rabbit.pcd")
idx = np.arange(10000)
# 索引对应的点
pIn = pcd.select_by_index(idx)
pIn.paint_uniform_color([1, 0, 0])
# 索引外的点云
pOut = pcd.select_by_index(idx, invert=True)
pOut.paint_uniform_color([0, 1, 0])
o3d.visualization.draw_geometries([pIn, pOut])
python
运行
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

效果为

在这里插入图片描述

统计滤波和邻域滤波

这两中滤波方法都是先得到符合要求的点索引,然后通过索引滤波,将这些点挑选出来,输出输出为滤波后的点云和点的索引号。

# 上接索引滤波的内容

pcd1 = copy.deepcopy(pcd).translate((20, 0, 0))
# 统计滤波,参数分别表示K邻域点的个数和标准差乘数
sPcd, sInd = pcd1.remove_statistical_outlier(6, 2.0)

pcd2 = copy.deepcopy(pcd).translate((40, 0, 0))
# 半径滤波,输入参数为邻域球内最少点数和邻域半径
rPcd, rInd = pcd2.remove_radius_outlier(9, 0.   )

o3d.visualization.draw_geometries([sPcd, rPcd])
python
运行
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

效果如下

在这里插入图片描述

这两种算法的逻辑是一样的,对于某点 x x x,选取距离 x x x最近的一些点,如果这些点的标准差小于设定值,则符合统计滤波的标准;如果均小于邻域半径,则符合半径滤波的标准。

体素滤波

体素滤波则会为点云构建三维体素格网,然后输出格网内的点云质心,所以这种滤波方式没有索引号的概念,其输入参数为体素尺寸。

downpcd = pcd.voxel_down_sample(20)
python
运行
  • 1

DBSCAN聚

DBSCAN,即Density-Based Spatial Clustering of Applications with Noise,基于密度的噪声应用空间聚类。

在DBSCAN算法中,将数据点分为三类:

  1. 核心点:若样本 x i x_i xi ε \varepsilon ε邻域内至少包含了 M M M个点,则为核心点
  2. 边界点:若样本 x i x_i xi ε \varepsilon ε邻域内包含的点数小于 M M M,但在其他核心点的 ε \varepsilon ε邻域内,则为边界点
  3. 噪声:既非核心点也非边界点则为噪声

可见,DBSCAN算法需要两个参数,分别是邻域半径 ε \varepsilon ε和点数 M M M

open3d中,提供了cluster_dbscan接口,

import open3d as o3d
import numpy as np
import matplotlib.pyplot as plt

pcd = o3d.io.read_point_cloud("rabbit.pcd")

eps = 0.5       # 同一聚类中最大点间距
M = 50          # 有效聚类的最小点数
Labels = np.array(pcd.cluster_dbscan(eps, M))
print(np.max(Labels))                   # 得到结果为3
cs = plt.get_cmap("jet")(Labels/3)      # 伪彩映射
cs[labels < 0] = 0  # labels = -1 的簇为噪声,以黑色显示
pcd.colors = o3d.utility.Vector3dVector(cs[:, :3])
o3d.visualization.draw_geometries([pcd])
python
运行
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

结果如图所示

在这里插入图片描述

RANSAC 平面分割

RANSAC,即RANdom SAmple Consensus,随机抽样一致算法。

以平面上的点集举例,假设点集中有一条直线 L L L L L L外的点很少,均为噪声。

那么第一步,随机选取两个点连成一条直线 L ^ \hat L L^,那么这条直线有可能就是 L L L,也有可能是噪声连出来的莫名其妙的一条线。

接下来,随机抽取点集中的一些点,如果随机抽取的大部分点都落在 L L L附近,那么就说明 L ^ \hat L L^有很大的概率就是 L L L;否则说明不太像是 L L L。随着抽取出的直线越来越多,最后可以得到最接近 L L L的直线,从而完成了对点集的分割。

Open3d中,提供了基于RANSAC算法的平面分割接口segment_plane

pcd = o3d.io.read_point_cloud("rabbit.pcd")

d = 0.2             # 内点到平面模型的最大距离
n = 5               # 用于拟合平面的采样点数
nIter = 50          # 最大迭代次数

# 返回模型系数plane和内点索引ids,并赋值
plane, ids = pcd.segment_plane(d, n, nIter)

# 平面方程
[a, b, c, d] = plane

# 平面内点点云
iCloud = pcd.select_by_index(ids)
iCloud.paint_uniform_color([0, 0, 1.0])

# 平面外点点云
oCloud = pcd.select_by_index(ids, invert=True)
oCloud.paint_uniform_color([1.0, 0, 0])

# 可视化平面分割结果
o3d.visualization.draw_geometries([iCloud, oCloud])
python
运行
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

最后得到的结果为

在这里插入图片描述

本来以为平面会出现在兔子的底座上,没想到最后兔子被一分为二了……


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删
相关文章
QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空