计算机视觉:点云的PCD和BIN格式及其转换与可视化

点云PCD格式和BIN格式

点云数据通常以不同的格式存储,其中PCD(Point Cloud Data)和BIN(Binary)是两种常见的格式,用于表示三维点云数据。下面是它们的具体介绍:

PCD 格式(Point Cloud Data)

PCD格式是一种常见的开放式点云数据存储格式,最初由ROS(Robot Operating System)中的PCL(Point Cloud Library)项目引入,现在广泛用于点云数据的存储和共享。

PCD文件通常是文本文件,以ASCII或二进制形式存储。ASCII格式易于阅读和编辑,但文件较大。二进制格式通常更紧凑,适用于大型点云数据。

PCD文件包含点云的几何信息和属性信息,如点的坐标、颜色、法线等。它还可以包含元数据,以描述点云的特性,如坐标系、点云类型等。

PCD格式具有广泛的支持,可以使用各种点云处理工具来读取和写入PCD文件。

BIN 格式(Binary)

BIN格式是一种更底层的点云数据存储格式,通常以二进制形式存储,因此在文件中的数据较紧凑,适用于大型点云数据的存储。

BIN文件通常只包含点云的几何信息,如点的坐标,而不包含额外的属性信息。这使得它适用于在存储和传输时保持数据的紧凑性。

与PCD不同,BIN格式通常不包含元数据,因此在读取时需要额外的信息来解释数据,如点的数量和坐标表示。

PCD到BIN的格式转换

在Kitti数据集中,点云以BIN的格式存储,在项目的实操中经常需要将采集得到的PCD格式点云转换成BIN格式,以方便后续的模型训练或测试。以下代码使用python语言实现了点云从PCD到BIN的格式转换:

默认情况下,PCD格式的点云保存在./pcd文件夹下,生成的BIN格式点云保存在./bin文件夹下。

import numpy as np
import os
import argparse
import pypcd
from tqdm import tqdm

def main():
    ## Add parser
    parser = argparse.ArgumentParser(description="Convert .pcd to .bin")
    parser.add_argument(
        "--pcd_path",
        help=".pcd file path.",
        type=str,
        default="./pcd"
    )
    parser.add_argument(
        "--bin_path",
        help=".bin file path.",
        type=str,
        default="./bin"
    )
    args = parser.parse_args()

    ## Find all pcd files
    pcd_files = []
    for (path, dir, files) in os.walk(args.pcd_path):
        for filename in files:
            # print(filename)
            ext = os.path.splitext(filename)[-1]
            if ext == '.pcd':
                pcd_files.append(path + "/" + filename)

    ## Sort pcd files by file name
    pcd_files.sort()   
    print("Finish to load point clouds!")

    ## Make bin_path directory
    try:
        if not (os.path.isdir(args.bin_path)):
            os.makedirs(os.path.join(args.bin_path))
    except OSError as e:
        if e.errno != errno.EEXIST:
            print ("Failed to create directory!!!!!")
            raise

    ## Converting Process
    print("Converting Start!")
    for pcd_file in tqdm(pcd_files):
        ## Get pcd file
        pc = pypcd.PointCloud.from_path(pcd_file)
	
        ## Generate bin file name
        ## bin_file_name = "{}_{:05d}.bin".format(args.file_name, seq)
		pcd_name = pcd_file.split('/')[2]
		bin_file_name = pcd_name.split('.')[0]+'.'+pcd_name.split('.')[1]+'.bin'
		## print bin_file_name        
		bin_file_path = os.path.join(args.bin_path, bin_file_name)
        
        ## Get data from pcd (x, y, z, intensity, ring, time)
        np_x = (np.array(pc.pc_data['x'], dtype=np.float32)).astype(np.float32)
        np_y = (np.array(pc.pc_data['y'], dtype=np.float32)).astype(np.float32)
        np_z = (np.array(pc.pc_data['z'], dtype=np.float32)).astype(np.float32)
        np_i = (np.array(pc.pc_data['intensity'], dtype=np.float32)).astype(np.float32)/256
        # np_r = (np.array(pc.pc_data['ring'], dtype=np.float32)).astype(np.float32)
        # np_t = (np.array(pc.pc_data['time'], dtype=np.float32)).astype(np.float32)

        ## Stack all data    
        points_32 = np.transpose(np.vstack((np_x, np_y, np_z, np_i)))

        ## Save bin file                                    
        points_32.tofile(bin_file_path)

    
if __name__ == "__main__":
    main()

拷贝代码写入到pcd2bin.py文件中,通过以下命令运行代码:

 # []表示可省略
python pcd2bin.py [--pcd_path=./pcd] [--bin_path=./bin]

点云可视化

可视化的目的是验证格式转换前后,点云是否一样。

PCD格式的点云可以使用诸多软件进行可视化,例如MeshLab等,也可以使用如下的代码对PCD格式的点云进行可视化:

import numpy as np
import open3d as o3d
from open3d import geometry

def main():

    #创建窗口对象
    vis = o3d.visualization.Visualizer()
    #设置窗口标题
    vis.create_window(window_name="kitti")
    #设置点云大小
    vis.get_render_option().point_size = 1
    #设置颜色背景为黑色
    opt = vis.get_render_option()
    opt.background_color = np.asarray([0, 0, 0])
    #################################################################################################
    #读取点云文件,创建点云对象
    pcd = o3d.io.read_point_cloud("./test.pcd")
    #设置点的颜色为白色
    pcd.paint_uniform_color([1,1,1])
    #将点云加入到窗口中
    vis.add_geometry(pcd)

    vis.run()
    vis.destroy_window()
    
if __name__=="__main__":
    main()

使用如下代码对生成的BIN格式点云进行可视化:

import numpy as np
import mayavi.mlab
 
# lidar_path换成自己的.bin文件路径
pointcloud = np.fromfile(str("./test.bin"), dtype=np.float32, count=-1).reshape([-1, 4])
 
x = pointcloud[:, 0]  # x position of point
y = pointcloud[:, 1]  # y position of point
z = pointcloud[:, 2]  # z position of point
 
r = pointcloud[:, 3]  # reflectance value of point
d = np.sqrt(x ** 2 + y ** 2)  # Map Distance from sensor
 
degr = np.degrees(np.arctan(z / d))
 
vals = 'height'
if vals == "height":
    col = z
else:
    col = d
 
fig = mayavi.mlab.figure(bgcolor=(0, 0, 0), size=(640, 500))
mayavi.mlab.points3d(x, y, z,
                     col,  # Values used for Color
                     mode="point",
                     colormap='spectral',  # 'bone', 'copper', 'gnuplot'
                     # color=(0, 1, 0),   # Used a fixed (r,g,b) instead
                     figure=fig,
                     )
 
mayavi.mlab.show()**加粗样式**

若出现module 'pypcd' has no attribute 'PointCloud'的报错,可以尝试将

import pypcd

修改为

from pypcd import pypcd
  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现激光雷达点云pcd障碍物识别并用open3d可视化,可以按照以下步骤进行: 1. 安装open3d和numpy库: ```python pip install open3d numpy ``` 2. 读取pcd文件: ```python import open3d as o3d pcd = o3d.io.read_point_cloud("example.pcd") ``` 3. 对点云进行下采样,以加快处理速度: ```python downpcd = pcd.voxel_down_sample(voxel_size=0.05) ``` 4. 对下采样后的点云进行平滑处理,以去除噪声: ```python downpcd.estimate_normals() downpcd.paint_uniform_color([1, 0.706, 0]) o3d.visualization.draw_geometries([downpcd]) ``` 5. 对处理后的点云进行聚类,找出障碍物: ```python with o3d.utility.VerbosityContextManager( o3d.utility.VerbosityLevel.Debug) as cm: labels = np.array(downpcd.cluster_dbscan(eps=0.5, min_points=10, print_progress=True)) max_label = labels.max() print(f"point cloud has {max_label + 1} clusters") colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1)) colors[labels < 0] = 0 downpcd.colors = o3d.utility.Vector3dVector(colors[:, :3]) o3d.visualization.draw_geometries([downpcd]) ``` 6. 可以将障碍物的点云保存成独立的pcd文件: ```python for i in range(max_label + 1): indices = np.where(labels == i)[0] cloud_cluster = downpcd.select_down_sample(indices) o3d.io.write_point_cloud(f"cluster{i}.pcd", cloud_cluster) ``` 7. 最后,可以用open3d可视化显示障碍物识别结果: ```python o3d.visualization.draw_geometries([downpcd]) ``` 完整代码如下: ```python import numpy as np import open3d as o3d import matplotlib.pyplot as plt # 读取pcd文件 pcd = o3d.io.read_point_cloud("example.pcd") # 对点云进行下采样 downpcd = pcd.voxel_down_sample(voxel_size=0.05) # 对下采样后的点云进行平滑处理 downpcd.estimate_normals() downpcd.paint_uniform_color([1, 0.706, 0]) o3d.visualization.draw_geometries([downpcd]) # 对处理后的点云进行聚类,找出障碍物 with o3d.utility.VerbosityContextManager( o3d.utility.VerbosityLevel.Debug) as cm: labels = np.array(downpcd.cluster_dbscan(eps=0.5, min_points=10, print_progress=True)) max_label = labels.max() print(f"point cloud has {max_label + 1} clusters") colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1)) colors[labels < 0] = 0 downpcd.colors = o3d.utility.Vector3dVector(colors[:, :3]) o3d.visualization.draw_geometries([downpcd]) # 将障碍物的点云保存成独立的pcd文件 for i in range(max_label + 1): indices = np.where(labels == i)[0] cloud_cluster = downpcd.select_down_sample(indices) o3d.io.write_point_cloud(f"cluster{i}.pcd", cloud_cluster) # 用open3d可视化显示障碍物识别结果 o3d.visualization.draw_geometries([downpcd]) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI Player

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值