Iohannes
发布于 2025-02-20 / 3 阅读 / 0 评论 / 0 点赞

pcd语义地图

语义定义

地面

  • 颜色:白色
  • 标签: dm

正方体

  • 颜色:淡红色
  • 标签: zft

圆柱体

  • 颜色:淡粉色
  • 标签: yzt

球体

  • 颜色:淡紫色
  • 标签: qt

py生成pcd

import numpy as np

# 正方体参数
cube_size = 1.0  # 正方体边长为1米
num_points_per_side = 20  # 每条边上的点数(正方体)
cube_total_points = 6 * num_points_per_side ** 2  # 正方体6个面

# 圆柱体参数
cylinder_radius = 0.5  # 圆柱体半径为0.5米
cylinder_height = 1.5  # 圆柱体高度为1.5米
num_cylinder_points = 100  # 圆柱体每圈的点数
num_cylinder_layers = 20  # 圆柱体的层数
cylinder_total_points = num_cylinder_points * num_cylinder_layers

# 球体参数
sphere_radius = 0.5  # 球体半径为0.5米
num_sphere_points = 50  # 球体每圈的点数
num_sphere_layers = 25  # 球体的层数
sphere_total_points = num_sphere_points * num_sphere_layers

# 地面参数
ground_size = 5.0  # 地面边长扩展到5米
num_ground_points_per_side = 50  # 地面每条边上的点数
ground_height = 0.001  # 地面高度为0.001米
ground_total_points = num_ground_points_per_side ** 2  # 地面点数

# 颜色定义(十六进制)
ground_color = 0xFFFFFF  # 白色(地面)
cube_color = 0xFFB6C1  # 淡红色(正方体)
cylinder_color = 0xFFC0CB  # 淡粉色(圆柱体)
sphere_color = 0xE6E6FA  # 淡紫色(球体)

# 标签定义(整数映射)
label_map = {
    "dm": 0,  # 地面
    "zft": 1,  # 正方体
    "yzt": 2,  # 圆柱体
    "qt": 3   # 球体
}

# 生成点云
points = []

# 生成正方体的点
for face in range(6):
    if face == 0:  # xy平面,z=0.001(底部与地面平行)
        x, y = np.meshgrid(np.linspace(-cube_size / 2, cube_size / 2, num_points_per_side),
                           np.linspace(-cube_size / 2, cube_size / 2, num_points_per_side))
        z = ground_height * np.ones_like(x)  # 正方体底部与地面平行
    elif face == 1:  # xy平面,z=1(顶部)
        x, y = np.meshgrid(np.linspace(-cube_size / 2, cube_size / 2, num_points_per_side),
                           np.linspace(-cube_size / 2, cube_size / 2, num_points_per_side))
        z = cube_size * np.ones_like(x)
    elif face == 2:  # xz平面,y=-0.5
        x, z = np.meshgrid(np.linspace(-cube_size / 2, cube_size / 2, num_points_per_side),
                           np.linspace(ground_height, cube_size, num_points_per_side))
        y = -cube_size / 2 * np.ones_like(x)
    elif face == 3:  # xz平面,y=0.5
        x, z = np.meshgrid(np.linspace(-cube_size / 2, cube_size / 2, num_points_per_side),
                           np.linspace(ground_height, cube_size, num_points_per_side))
        y = cube_size / 2 * np.ones_like(x)
    elif face == 4:  # yz平面,x=-0.5
        y, z = np.meshgrid(np.linspace(-cube_size / 2, cube_size / 2, num_points_per_side),
                           np.linspace(ground_height, cube_size, num_points_per_side))
        x = -cube_size / 2 * np.ones_like(y)
    elif face == 5:  # yz平面,x=0.5
        y, z = np.meshgrid(np.linspace(-cube_size / 2, cube_size / 2, num_points_per_side),
                           np.linspace(ground_height, cube_size, num_points_per_side))
        x = cube_size / 2 * np.ones_like(y)

    # 将网格点展平并添加到点云中
    points.extend(np.vstack((x.flatten(), y.flatten(), z.flatten(), np.full(x.size, cube_color), np.full(x.size, label_map["zft"]))).T)

# 生成地面的点
x, y = np.meshgrid(np.linspace(-ground_size / 2, ground_size / 2, num_ground_points_per_side),
                   np.linspace(-ground_size / 2, ground_size / 2, num_ground_points_per_side))
z = np.full_like(x, ground_height)  # 地面高度为0.001米
points.extend(np.vstack((x.flatten(), y.flatten(), z.flatten(), np.full(x.size, ground_color), np.full(x.size, label_map["dm"]))).T)

# 生成圆柱体的点
theta = np.linspace(0, 2 * np.pi, num_cylinder_points)  # 圆周角度
z_cylinder = np.linspace(0, cylinder_height, num_cylinder_layers)  # 圆柱体高度
for z_val in z_cylinder:
    for angle in theta:
        x_val = 2 + cylinder_radius * np.cos(angle)  # 圆柱体中心在 (2, 0, 0)
        y_val = 0 + cylinder_radius * np.sin(angle)
        points.append([x_val, y_val, z_val, cylinder_color, label_map["yzt"]])

# 生成球体的点
phi = np.linspace(0, np.pi, num_sphere_layers)  # 纬度角度
theta = np.linspace(0, 2 * np.pi, num_sphere_points)  # 经度角度
for p in phi:
    for t in theta:
        x_val = sphere_radius * np.sin(p) * np.cos(t)  # 球体中心在 (0, 2, 0.5)
        y_val = sphere_radius * np.sin(p) * np.sin(t) + 2  # 球体中心在 y=2
        z_val = sphere_radius * np.cos(p) + 0.5  # 球体中心在 z=0.5
        points.append([x_val, y_val, z_val, sphere_color, label_map["qt"]])

# 保存为PCD文件
total_points = cube_total_points + ground_total_points + cylinder_total_points + sphere_total_points
with open("cube_cylinder_sphere_with_ground.pcd", "w") as f:
    f.write("# .PCD v0.7 - Point Cloud Data file format\n")
    f.write("VERSION 0.7\n")
    f.write("FIELDS x y z rgb label\n")  # 添加 label 字段
    f.write("SIZE 4 4 4 4 4\n")  # label 字段大小为 4 字节
    f.write("TYPE F F F I I\n")  # label 字段类型为整数
    f.write("COUNT 1 1 1 1 1\n")
    f.write(f"WIDTH {total_points}\n")
    f.write("HEIGHT 1\n")
    f.write("VIEWPOINT 0 0 0 1 0 0 0\n")
    f.write(f"POINTS {total_points}\n")
    f.write("DATA ascii\n")
    for point in points:
        f.write(f"{point[0]} {point[1]} {point[2]} {int(point[3])} {int(point[4])}\n")

print(f"Generated {total_points} points and saved to cube_cylinder_sphere_with_ground.pcd")

部分pcd文件内容

# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb label
SIZE 4 4 4 4 4
TYPE F F F I I
COUNT 1 1 1 1 1
WIDTH 8150
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 8150
DATA ascii
-0.5 -0.5 0.001 16758465 1
-0.4473684210526316 -0.5 0.001 16758465 1
-0.39473684210526316 -0.5 0.001 16758465 1
-0.34210526315789475 -0.5 0.001 16758465 1
-0.2894736842105263 -0.5 0.001 16758465 1
-0.2368421052631579 -0.5 0.001 16758465 1
-0.1842105263157895 -0.5 0.001 16758465 1
# more data

查看

  1. 打开pcdview,点击Data/Open Point Clouds,选中pcd文件
  2. 左边lay tree,右击文件,选中Render As RGB

评论