压死程序员的大山
2018-05-01
我记得我曾经专门写过一篇博客讨论为什么程序员的大好时光都被什么消耗了。俗话说得好写程序1小时Debug100年,程序员本来应该像大多数人一样拥有自由充沛的时间,然而就是因为三座大山导致程序员的人生被浪费在了长时间的debug之上。可以说是相当绝望了。
今天一直在做一件很简单的点云生成的工作,我很确定自己完成了点云颜色的添加,也确定自己添加的颜色是符合规范的,然而在Windows下就是显示不出来。刚刚才发现原来是PCL库在Windows下支持的pcd_viewer_release
和Linux下的pcl_viewer
完全是两个不一样的东西。切换了系统之后下图这种狗屎黄的东西终于变成了彩色。
3D点云数据的文件类型——PCD。
想了想还是总结下PCD的文件格式吧
PCD版本
在点云库(PCL)1.0版本发布之前,PCD文件格式有不同的修订号。这些修订号用PCD_Vx来编号(例如,PCD_V5、PCD_V6、PCD_V7等等),代表PCD文件的0.x版本号。然而PCL中PCD文件格式的正式发布是0.7版本(PCD_V7)。
文件头格式
每一个PCD文件包含一个文件头,它确定和声明文件中存储的点云数据的某种特性。PCD文件头必须用ASCII码来编码。PCD文件中指定的每一个文件头字段以及ascii点数据都用一个新行(\n)分开了,从0.7版本开始,PCD文件头包含下面的字段:
VERSION:指定PCD文件版本
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
SIZE:用字节数指定每一个维度的大小。例如:
unsigned char/char has 1 byte unsigned short/short has 2 bytes unsignedint/int/float has 4 bytes double has 8 bytes
TYPE:用一个字符指定每一个维度的类型。现在被接受的类型有:
I –表示有符号类型int8(char)、int16(short)和int32(int); U – 表示无符号类型uint8(unsigned char),uint16(unsigned short),uint32(unsigned int); F –表示浮点类型。
COUNT:指定每一个维度包含的元素数目。例如,x这个数据通常有一个元素,但是像VFH这样的特征描述子就有308个。实际上这是在给每一点引入n维直方图描述符的方法,把它们当做单个的连续存储块。默认情况下,如果没有COUNT,所有维度的数目被设置成1。
WIDTH: 用点的数量表示点云数据集的宽度。根据是有序点云还是无序点云,WIDTH有两层解释:
1)它能确定无序数据集的点云中点的个数(和下面的POINTS一样);
2)它能确定有序点云数据集的宽度(一行中点的数目)。
HEIGHT –用点的数目表示点云数据集的高度。类似于WIDTH ,HEIGHT也有两层解释:
1)它表示有序点云数据集的高度(行的总数);
2)对于无序数据集它被设置成1(被用来检查一个数据集是有序还是无序)。
VIEWPOINT:指定数据集中点云的获取视点。VIEWPOINT有可能在不同坐标系之间转换的时候应用,在辅助获取其他特征时也比较有用,例如曲面法线,在判断方向一致性时,需要知道视点的方位,视点信息被指定为平移(txtytz)+四元数(qwqxqyqz)
POINTS:指定点云中点的总数。从0.7版本开始,该字段就有点多余了,因此有可能在将来的版本中将它移除。
DATA:指定存储点云数据的数据类型。从0.7版本开始,支持两种数据类型:ascii和二进制。
例子
下面贴出了PCD文件的一个片段。把它留给看官以解析这些数据,看看它的组成,玩的愉快!
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F I
COUNT 1 1 1 1
WIDTH 285633
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 285633
DATA ascii
-0.035189189 -0.027352601 0.056000002 8945018
-0.035081081 -0.027352601 0.056000002 9010811
-0.034972973 -0.027352601 0.056000002 9010811
-0.034864865 -0.027352601 0.056000002 9010811
PS:其中rgb这一项中是用一个整型数代表的他是这样算出来的:
int(int(r) << 16) | (int(g) << 8) | int(b) #移位运算