无权限

Derrick博客站

点云数据处理

一、点云处理简介

1、点云

点云:某个坐标系下的点数据集,每个点包括三维坐标X、Y、Z颜色、分类值、强度值、时间等信息。
点云处理:从点云中提取到我们需要的信息

2、点云采集方式

 

二、点云可视化操作

1、open3D中的点云的读取和保存

import open3d as o3d

plv = o3d.io.read_point_cloud("data/box.ply")
o3d.visualization.draw_geometries([plv])
o3d.io.write_point_cloud("data/cpy_box.ply", plv)

2、Open3d中的mesh的读取和保存

import open3d as o3d

plv_mesh = o3d.io.read_triangle_mesh("data/bunny10k.ply")
o3d.visualization.draw_geometries([plv_mesh])
o3d.io.write_triangle_mesh("data/cpy_bunny10k.ply",plv_mesh)

 

3、自定义可视化

import open3d as o3d

plv = o3d.io.read_point_cloud("data/box.ply")
o3d.visualization.draw_geometries([plv],window_name="box",width=1920,height=1080,point_show_normal=False)

4、修改颜色

import open3d as o3d

ply = o3d.io.read_point_cloud("data/box.ply","auto",True,True)
ply.paint_uniform_color([0, 0, 1])
o3d.visualization.draw_geometries([ply],window_name="box",width=1920,height=1080,point_show_normal=False)

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、点云去噪

图片#636px #443px #B
(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)随机采样

import open3d as o3d

#random sample 随机采样
pcd =o3d.io.read_point_cloud("data/box.ply","auto",True,True)
o3d.visualization.draw_geometries([pcd])
pcd = pcd.random_down_sample(0.2)
o3d.visualization.draw_geometries([pcd])
#0.2是采样比例,即保留20%的点

(2)均匀采样

 #uniform sample 均匀采样
pcd =o3d.io.read_point_cloud("data/box.ply","auto",True,True)
o3d.visualization.draw_geometries([pcd])
pcd = pcd.uniform_down_sample(50)#每隔50个点采样一次
o3d.visualization.draw_geometries([pcd])

(3)体素采样

 #voxel sample 体素采样
pcd =o3d.io.read_point_cloud("data/box.ply","auto",True,True)
o3d.visualization.draw_geometries([pcd])
pcd = pcd.voxel_down_sample(voxel_size=0.01)
o3d.visualization.draw_geometries([pcd])

(4)泊松盘采样

#泊松盘采样
mesh = o3d.io.read_triangle_mesh("data/bunny10k.ply")
pcd = mesh.sample_points_poisson_disk(number_of_points=100, init_factor=5)
o3d.visualization.draw_geometries([pcd])

 

评论

快捷导航

把好文章收藏到微信

打开微信,扫码查看

关闭

还没有账号?立即注册