python实现PCD文件中点云数据存储类型ascii与binary的格式转换

1. PCD格式说明

  • 如果打算用pcl来处理点云的话,那么点云需要先转化为pcd格式。在点云库(PCL)1.0版本发布之前,PCD文件格式有不同的修订号。这些修订号用PCD_Vx来编号(例如,PCD_V5、PCD_V6、PCD_V7等等),代表PCD文件的0.x版本号。然而PCL中PCD文件格式的正式发布是0.7版本(PCD_V7)。下面我以0.7版本为例进行说明:

  • 每一个PCD文件包含一个文件头,它确定和声明文件中存储的点云数据的某种特性。PCD文件头必须用ASCII码来编码。PCD文件中指定的每一个文件头字段以及ascii点数据都用一个新行(\n)分开了。用记事本打开一个pcd文件,可看到如下所示内容:

# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7       
FIELDS x y z
SIZE 4 4 4
TYPE F F F
COUNT 1 1 1
WIDTH 460400
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 460400
DATA ascii
  • 从0.7版本开始,PCD文件头包含下面的字段:
  1. VERSION –指定PCD文件版本

  2. FIELDS –指定一个点可以有的每一个维度和字段的名字。例如:

FIELDS x y z # XYZ data
FIELDS x y z rgb # XYZ + colors
FIELDS x y z normal_xnormal_y normal_z # XYZ + surface normals
FIELDS j1 j2 j3 # moment invariants
  1. SIZE –用字节数指定每一个维度的大小。例如:
unsigned char/char has 1 byte
unsigned short/short has 2 bytes
unsignedint/int/float has 4 bytes
double has 8 bytes
  1. TYPE –用一个字符指定每一个维度的类型。现在被接受的类型有:
I – 表示有符号类型int8(char)、int16(short)和int32(int);
U – 表示无符号类型uint8(unsigned char)、uint16(unsigned short)和uint32(unsigned int);
F – 表示浮点类型。
  1. COUNT –指定每一个维度包含的元素数目。例如,x这个数据通常有一个元素,但是像VFH这样的特征描述子就有308个。实际上这是在给每一点引入n维直方图描述符的方法,把它们当做单个的连续存储块。默认情况下,如果没有COUNT,所有维度的数目被设置成1。

  2. WIDTH –用点的数量表示点云数据集的宽度。根据是有序点云还是无序点云,WIDTH有两层解释:

    • 它能确定无序数据集的点云中点的个数(和下面的POINTS一样);
    • 它能确定有序点云数据集的宽度(一行中点的数目)。

    注意:有序点云数据集,意味着点云是类似于图像(或者矩阵)的结构,数据分为行和列。这种点云的实例包括立体摄像机和时间飞行摄像机生成的数据。有序数据集的优势在于,预先了解相邻点(和像素点类似)的关系,邻域操作更加高效,这样就加速了计算并降低了PCL中某些算法的成本。

  3. HEIGHT –用点的数目表示点云数据集的高度。类似于WIDTH ,HEIGHT也有两层解释:

    • 它表示有序点云数据集的高度(行的总数);
    • 对于无序数据集它被设置成1(被用来检查一个数据集是有序还是无序)。
  4. VIEWPOINT –指定数据集中点云的获取视点。VIEWPOINT有可能在不同坐标系之间转换的时候应用,在辅助获取其他特征时也比较有用,例如曲面法线,在判断方向一致性时,需要知道视点的方位,
    视点信息被指定为平移(txtytz)+四元数(qwqxqyqz)。默认值是:
    VIEWPOINT 0 0 0 1 0 0 0

  5. POINTS –指定点云中点的总数。从0.7版本开始,该字段就有点多余了,因此有可能在将来的版本中将它移除。
    例子:
    POINTS 307200 #点云中点的总数为307200

  6. DATA –指定存储点云数据的数据类型。从0.7版本开始,支持两种数据类型:ascii和二进制。

注意
文件头最后一行(DATA)的下一个字节就被看成是点云的数据部分了,它会被解释为点云数据。以ASCLL码存储的点云数据,每一个点占据一行,“nan”表示不存在或非法的数据。

警告
PCD文件的文件头部分必须以上面的顺序精确指定,也就是如下顺序:
VERSION、FIELDS、SIZE、TYPE、COUNT、WIDTH、HEIGHT、VIEWPOINT、POINTS、DATA
之间用换行隔开。

2. ASCII和binary格式区别

计算机文件基本上分为二种:binary(二进制文件)和 ASCII(也称纯文本文件)

二进制文件:图形文件及文字处理程序等计算机程序,含有特殊的格式及计算机代码;

ASCII文件:可以用任何文字处理程序阅读的简单文本文件;

简单区别:用记事本打开,正常的就是ASCII文件,是乱码的就是二进制文件。

为什么要转换格式?计算机可以直接识别二进制文件,而读取文本文件还需要“翻译”成自己能识别的。传大量文件时,二进制文件形式传输速率自然快上不少。

3. ASCII和binary格式转换

convert.py

#!/usr/bin/env python
# encoding=utf8 

import sys
import logging
import pcl
import re

if __name__ == "__main__":

    if sys.argv.__len__() != 3:
        print "Usage: pyton ./BA.py source.pcd dest.pcd"
        print "Auto adjust the type of file: binary or ascii"
        exit(0)
        
    pcl_src_path = sys.argv[1]
    pcl_dest_path = sys.argv[2]

    p = re.compile("DATA (?P<data_type>\w*)")
    data_type = "unknow"
    with open(pcl_src_path, 'rt') as pcl_src_handle:    
        lines = pcl_src_handle.readlines()            

        for index in range(12):
            m = p.match(lines[index])
            try:
                data_type = m.group("data_type")
                break
            except Exception as e:
                pass

    print data_type

    if data_type == "binary":
        print "Convert binary to ascii"
        B = False
    elif data_type == "ascii":
        print "Convert ascii to binary"
        B = True
    else:
        print "Usage: pyton ./BA.py source.pcd dest.pcd"
        print "Usage: pyton ./BA.py source.pcd ascii.pcd"
        print "Usage: pyton ./BA.py ascii.pcd binary.pcd"

    pcl_file = pcl.PointCloud_PointXYZI()
    pcl_file.from_file(pcl_src_path)
    pcl_file._to_pcd_file(pcl_dest_path, B)

运行代码:

python ./convert.py 1.pcd 2.pcd

注意
若提示缺少python-pcl库:ImportError: No module named pcl,使用如下命令进行安装:

pip install python-pcl

4. 代码注释学习:

#!/usr/bin/env python
# encoding=utf8         # 开头注释,说明源程序所用编码

'''导入模块'''
import sys
import logging
import pcl
import re           

if __name__ == "__main__":          # 作用1:作为脚本直接运行;作用2:被其他脚本调用时,不会执行

    if sys.argv.__len__() != 3:         #判断输入参数的个数
        print "Usage: pyton ./BA.py source.pcd dest.pcd"
        print "Auto adjust the type of file: binary or ascii"
        exit(0)							# 正常运行程序并退出程序


    pcl_src_path = sys.argv[1]		#输入的第一个参数为 原文件路径
    pcl_dest_path = sys.argv[2]		#输入的第二个参数为 输出路径

    p = re.compile("DATA (?P<data_type>\w*)")   #正则表达式(不太懂)
    data_type = "unknow"             
    with open(pcl_src_path, 'rt') as pcl_src_handle:    # rt 读写打开一个文本文件  读写标识
        lines = pcl_src_handle.readlines()            

        for index in range(12):      # 为什么是12? 因为pcd文件前十一行是文件格式信息,后面才是点云信息
            m = p.match(lines[index])
            try:
                data_type = m.group("data_type")
                break
            except Exception as e:
                pass

    print data_type

    if data_type == "binary":
        print "Convert binary to ascii"
        B = False
    elif data_type == "ascii":
        print "Convert ascii to binary"
        B = True
    else:
        print "Usage: pyton ./BA.py source.pcd dest.pcd"
        print "Usage: pyton ./BA.py source.pcd ascii.pcd"
        print "Usage: pyton ./BA.py ascii.pcd binary.pcd"

    pcl_file = pcl.PointCloud_PointXYZI()   # 
    pcl_file.from_file(pcl_src_path)        # 
    pcl_file._to_pcd_file(pcl_dest_path, B)	 # 

参考:

  1. https://blog.csdn.net/ganguowa/article/details/53965304?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158457878519724848329972%2522%252C%2522scm%2522%253A%252220140713.130056874…%2522%257D&request_id=158457878519724848329972&biz_id=0&utm_source=distribute.pc_search_result.none-task#1asc%E6%A0%BC%E5%BC%8F%E7%9A%84%E8%AF%B4%E6%98%8E
  2. https://blog.csdn.net/qq_43642710/article/details/105267949?utm_medium=distribute.pc_relevant_t0.none-task-blog-OPENSEARCH-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-OPENSEARCH-1.control
  • 4
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值