点云数据处理
一、点云处理简介
1、点云
点云:某个坐标系下的点数据集,每个点包括三维坐标X、Y、Z颜色、分类值、强度值、时间等信息。
点云处理:从点云中提取到我们需要的信息
2、点云采集方式
二、点云可视化操作
1、open3D中的点云的读取和保存
2、Open3d中的mesh的读取和保存
3、自定义可视化
4、修改颜色
5、窗口可视化
import open3d as o3d
ply = o3d.io.read_point_cloud("data/box.ply","auto",True,True)
# 可视化句柄
viewer = o3d.visualization.Visualizer()
viewer.create_window(width=1920, height=1080)
# 界面参数选项
opt = viewer.get_render_option()
# 背景颜色
opt.background_color = [0, 0, 1]
# 点大小
opt.point_size = 1
# 添加坐标系
opt.show_coordinate_frame = True
# 颜色
ply.paint_uniform_color([0, 0, 1])
# 激活界面循环
viewer.add_geometry(ply)
viewer.run()
viewer.destroy_window()
三、常见点云数据处理方法
1、点云去噪

(1)统计滤波 Statistical Outlier Removal(SOR)
import open3d as o3d
# 加载点云
pcd = o3d.io.read_point_cloud("data/box.ply","auto",True,True)
# 统计滤波
k = 20 # K邻域点的个数
μ = 2.0 # 标准差乘数
sor_pcd, idx = pcd.remove_statistical_outlier(k, μ)#当判断点的k近邻的平均距离大于【平均距离+μ*σ】,即判定为噪声点,一般取μ=2或3为极限误差
sor_pcd.paint_uniform_color([1, 0, 1])
# 提取噪声点云
sor_noise_pcd = pcd.select_by_index(idx, invert=True)
sor_noise_pcd.paint_uniform_color([1, 0, 0])
o3d.visualization.draw_geometries([sor_pcd], window_name="SOR")
(2)半径滤波 Radius Outier Removal
import open3d as o3d
# 加载点云
pcd = o3d.io.read_point_cloud("data/box.ply","auto",True,True)
# 半径滤波
MinPts = 5 # 邻域球内的最少点个数,小于该个数为噪声点
R = 0.05 # 邻域半径大小
pc, idx = pcd.remove_radius_outlier(MinPts, R)
pc.paint_uniform_color([0, 0, 1])
ror_noise_pcd = pcd.select_by_index(idx,invert = True)
ror_noise_pcd.paint_uniform_color([1, 0, 0])
o3d.visualization.draw_geometries([pc], window_name="半径滤波")
(3)引导滤波 Guilter Filter
import numpy as np
import open3d as o3d
#guild filter
def guided_filter(pcd, radius, epsilon):
kdtree = o3d.geometry.KDTreeFlann(pcd)
points_copy = np.array(pcd.points)
points = np.asarray(pcd.points)
num_points = len(pcd.points)
for i in range(num_points):
k, idx, _ = kdtree.search_radius_vector_3d(pcd.points[i], radius)
if k < 3:
continue
neighbors = points[idx, :]
mean = np.mean(neighbors, 0)
cov = np.cov(neighbors.T)
e = np.linalg.inv(cov + epsilon * np.eye(3))
A = cov @ e
b = mean - A @ mean
points_copy[i] = A @ points[i] + b
pcd.points = o3d.utility.Vector3dVector(points_copy)
#添加噪声
def add_noise(pcd, sigma):
points = np.asarray(pcd.points)
noise = sigma * np.random.randn(points.shape[0], points.shape[1])
points += noise
pcd = o3d.io.read_point_cloud("data/box.ply","auto",True,True)
add_noise(pcd, 0.004)
o3d.visualization.draw_geometries([pcd],window_name="rawPointCloud")
guided_filter(pcd, 0.01, 0.1)
guided_filter(pcd, 0.01, 0.1)
o3d.visualization.draw_geometries([pcd],window_name="guildFilter")
2、采样方法
(1)随机采样
(2)均匀采样
(3)体素采样
(4)泊松盘采样


评论