使用Python+open3d+pyvista方式渲染点云并将标注信息一同渲染,可以通过此方法查看标注信息是否正确。
import os
import pyvista as pv
import numpy as np
import open3d as o3d
import pandas as pd
from scipy.spatial.transform import Rotation as R
def show_pcd(pcd_path, csv_path):
# 检查文件路径是否存在
if not os.path.exists(pcd_path):
raise FileNotFoundError(f"点云文件路径不存在: {pcd_path}")
if not os.path.exists(csv_path):
raise FileNotFoundError(f"CSV文件路径不存在: {csv_path}")
# 读取点云数据
pcd = o3d.io.read_point_cloud(pcd_path)
if pcd is None:
raise ValueError(f"无法读取点云文件: {pcd_path}")
# 将 open3d 点云转换为 pyvista 点云
pcd_np = np.asarray(pcd.points)
pcd_pv = pv.PolyData(pcd_np)
# 读取真值数据(CSV文件包含边界框信息)
ground_truth_df = pd.read_csv(csv_path)
if ground_truth_df is None:
raise ValueError(f"无法读取CSV文件: {csv_path}")
# 创建可视化窗口
plotter = pv.Plotter()
plotter.set_background('black')
plotter.add_mesh(pcd_pv, point_size=3.0)
# 在原点添加一个蓝色的点
plotter.add_mesh(pv.PolyData(np.array([[0, 0, 0]])), color='blue', point_size=10.0)
# 设置视图中心为原点
plotter.camera.focal_point = (0, 0, 0)
# 绘制3D边界框
for index, row in ground_truth_df.iterrows():
# 读取边界框信息
center = np.array([row['center_x'], row['center_y'], row['center_z']])
extent = np.array([row['size_length'], row['size_width'], row['size_height']])
rotation = R.from_euler('xyz', [row['roll'], row['pitch'], row['yaw']], degrees=False).as_matrix()
# 创建 4x4 变换矩阵
transform_matrix = np.eye(4)
transform_matrix[:3, :3] = rotation
transform_matrix[:3, 3] = center
# 创建边界框
bounding_box = pv.Cube(center=(0, 0, 0), x_length=extent[0], y_length=extent[1], z_length=extent[2])
bounding_box.transform(transform_matrix)
# 提取边框线
edges = bounding_box.extract_all_edges()
plotter.add_mesh(edges, color='red', line_width=2)
# 分层颜色显示点云
colors = np.zeros((pcd_np.shape[0], 3))
for i, point in enumerate(pcd_np):
x, y, _ = point
if x >= 0 and y >= 0:
colors[i] = [0.5, 0, 0] # 淡红色
elif x < 0 <= y:
colors[i] = [0, 0.5, 0] # 淡绿色
elif x < 0 and y < 0:
colors[i] = [0, 0, 0.5] # 淡蓝色
else:
colors[i] = [0.5, 0.5, 0] # 淡黄色
pcd_pv['colors'] = colors
plotter.add_mesh(pcd_pv, scalars='colors', rgb=True, point_size=3.0)
# 可视化预标注的点云
plotter.show()
if __name__ == '__main__':
show_pcd('/Users/zhd/xxx.pcd', '/Users/zhd/xxx.csv') # 其中pcd为点云文件,csv为真值文件
评论区