文章目录
- 一、简介
- 二、实现代码
- 三、实现效果
- 参考资料
一、简介
SOR滤波过程相对简单,其原理是通过查询点与邻域点集之间的距离统计判断来进行过滤离群点。假设一个点的邻近点集符合正太分布,因此我们可以通过计算出该点到它所有临近点的平均距离meanD和标准差 σ \sigma σ,理论上来讲大部分邻近点应在meanD+ 3 σ 3\sigma 3σ范围内(这里我们指定的是k倍的 σ \sigma σ),因此大于该阈值的点就可以被定义为是离散点而被删除。
二、实现代码
SOR滤波删除了与点云平均值相比远离其邻居的点。它有两个输入参数,其中:
- nb_neighbors:它指定为了计算给定点的平均距离要考虑多少个邻居。
- std_ratio:它允许基于点云平均距离的标准偏差设置阈值水平。
SOR.py
#*******************导入相关库***********************
import open3d as o3d
import numpy as np
from tkinter import filedialog
import matplotlib as mpl
import matplotlib.pyplot as plt
import sys
#*******************定义基础函数***********************
def draw_geometries(result,batch):
if batch:
for i in range(len(result)):
o3d.visualization.draw_geometries([result[i]], "result", 800, 600 #一个一个进行显示
, 50, 50, False, False, True)
else:
o3d.visualization.draw_geometries(result, "result", 800, 600
, 50, 50, False, False, True)
#主程序
if __name__ == "__main__":
#*******************获取数据************************
#对话框设置
use_dialog = True #是否使用对话框,True为使用,False为不使用
#读取数据
if use_dialog:
filePath = filedialog.askopenfilename(title='请选择一个文件', filetypes=[(
"点云文件", ".ply .pcd"), ('All Files', ' *')], defaultextension='.ply', multiple=False)
if len(filePath) == 0: #空路径
print("未选择点云文件!")
sys.exit()
pcd = o3d.io.read_point_cloud(filePath)
else:
#如果没有使用对话框
demo_crop_data = o3d.data.DemoCropPointCloud()
filePath = demo_crop_data.point_cloud_path #指定点云文件的路径
pcd = o3d.io.read_point_cloud(filePath)
#******************点云SOR滤波*********************
cl, ind = pcd.remove_statistical_outlier(nb_neighbors=20,std_ratio=2.0)
inlier_cloud = pcd.select_by_index(ind)
outlier_cloud = pcd.select_by_index(ind, invert=True) #剔除点
outlier_cloud.paint_uniform_color([1, 0, 0])
finalPC = inlier_cloud + outlier_cloud #合并点云
#********************可视化************************
draw_geometries([pcd,finalPC],True)
三、实现效果
参考资料
[1]Meshlab&Open3D SOR滤波
[2]http://www.open3d.org/docs/release/tutorial/geometry/pointcloud_outlier_removal.html#Statistical-outlier-removal