Python解析Las(点云)格式⽂件
Python解析Las(点云)格式⽂件
tips:
本⽂代码基于python3编写
推荐使⽤laspy或者plcpy包,本⽂做基础研究。
⼀、点云
点云:
在逆向⼯程中通过测量仪器得到的产品外观表⾯的点数据集合也称之为点云,通常使⽤三维坐标测量机所得到的点数量⽐较少,点与点的间距也⽐较⼤,叫稀疏点云;⽽使⽤三维激光扫描仪或照相式扫描仪得到的点云,点数量⽐较⼤并且⽐较密集,叫密集点云。
点云格式:
*.las、*.pcd、*.txt
⼆、Las格式
1. 简介
las⽂件是⼀个⼆进制⽂件,其中定义的数据类型与C语⾔中数据类型⼀致。到⽬前为⽌,las共有6版分别是:
2. Las规范数据类型
数据类型字节
char  1 byte
unsigned char  1 byte
short  2 bytes
unsigned short  2 bytes
long  4 bytes
unsigned long  4 bytes
double8 bytes
3. las⽂件整体构成
las1.0~las1.2las1.3~las1.4
公共头公共头
变长记录域变长记录域
las1.0~las1.2las1.3~las1.4
点数据域点数据域
扩展变长记录域
4. 公共头不同版本构成
las1.0~las1.2las1.3~las1.4
⽂件标识(“LASF”)⽂件标识(“LASF”)
保留字节⽂件ID
GUID数据全球编码
版本信息GUID数据
系统标识版本信息
飞⾏时间系统标识
头部⼤⼩⽂件创建时间
数据偏移头部⼤⼩
变长记录域数⽬数据偏移
点数据格式、长度、数⽬、不同回波点数⽬变长记录域数⽬
X、Y、Z刻度因⼦点数据格式、长度
X、Y、Z偏移值⽼格式点数⽬、不同回波点数⽬
X、Y、Z最⼤最⼩值X、Y、Z刻度因⼦
X、Y、Z偏移值
X、Y、Z最⼤最⼩值
波形数据包记录起始位置
扩展变长记录起始、数⽬
点数⽬、不同回波点数⽬
5. 点记录格式说明
在las1.0版本中定义了点数据格式0,其⼀共20字节数据,在las1.0~las1.4的版本中点数据格式1到5都是在点数据格式0基础上增添字段。具体字段说明可参见不同版本的。
在las1.4版本中增加了点格式6,其⼀共30字节数据,在las1.4版本中点格式7到10都是在点数据格式6基础上增添字段。具体字段说明可参见不同版本的。
备注:
在点格式0~5中Return Number、Number of Returns (given pulse)、Scan Direction Flag、Edge of Flight Line等字段共占1字节数据。
在点格式6~10中Return Number、Number of Returns、 Classification Flags、 Scan Direction Flag、 Edge of Flight Line等字段共占2字节数据。
这些字段的值都是通过位计算获得。
三、Python解析⼆进制
Python解析⼆进制⽂件使⽤内置struct包
1. Python数据类型与C语⾔数据类型对应关系,。
Format    C Type Python字节数x pad byte no value1
c char bytes of length 11
b signed char integer1
B unsigned char integer1
_Bool bool1
h short integer2
H unsigned short integer2
i int integer4
I unsigned int integer4
l long integer4
L unsigned long integer4
q long long integer8
Q unsigned long long integer8
f float float4
d doubl
e float8
s char[]bytes1
p char[]bytes1
P void *integer
2. 简单使⽤struct包
import struct
# 创建float型⼆进制数据
a = struct.pack('f',12.34)
print(f"转换的⼆进制:{a}",)
# 创建char[]类型⼆进制数据
b = struct.pack('4s','test'.encode('utf-8'))
print(f"转换的⼆进制:{b}",)
# 写⼊到⼆进制⽂件
f =open('test.dat','wb+')
f.write(a)
f.write(b)
f.close()
# 读取⼆进制⽂件
f =open('test.dat','rb')
a = f.read(4)
print(f"读取的⼆进制:{a}", a)
a = struct.unpack('f', a)
print(f"转换为Python数据类型:{a}",)
b = f.read(4)
print(f"读取的⼆进制:{b}",)
b = struct.unpack('4s', b)
print(f"转换为Python数据类型:{b}",)
f.close()
四、读取las⽂件并提取XYZ坐标值
1. 读取公共头
新建head.py,定义las1.0~las1.4版本不同的公共头的类,具体实现
class OneZeroHeader(object):
"""
1.0版本
"""
def__init__():
pass
def read_header(f):
pass
class OneOneHeader(object):
"""
1.1版本
"""
def__init__():
pass
def read_header(f):
pass
class OneTwoHeader(object):
"""
1.2版本
"""
def__init__():
pass
def read_header(f):
pass
class OneThreeHeader(object):
"""
1.3版本
"""
def__init__():
pass
def read_header(f):
pass
class OneFourHeader(object):
"""
1.4版本
"""
def__init__():
python怎么读取dat文件pass
def read_header(f):
pass
def get_header(f, version):
"""
根据不同版本读取不同头
"""
if version ==(1,0):
new_header = OneZeroHeader()
elif version ==(1,1):
new_header = OneOneHeader()
elif version ==(1,2):
new_header = OneTwoHeader()
new_header = OneTwoHeader()
elif version ==(1,3):
new_header = OneThreeHeader()
elif version ==(1,4):
new_header = OneFourHeader()
else:
raise Exception("未到对应⽂件版本")
ad_header(f)
return new_header
新建test_read_las.py,读取公共头数据
import struct
from head import get_header
def get_version(f):
version_major, version_minor = struct.unpack('2B', f.read(2))
print(f"las版本:{version_major}.{version_minor}")
return version_major, version_minor
if __name__ =='__main__':
f =open('test.las','rb')
version = get_version(f)
header = get_header(f, version)
print(header.__dict__)
2. 读取点数据
新建point.py,定义不同点格式。由本⽂只需要提取xyz值,所有只需要xyz值,其他数据解析跳过"""
定义点数据0~10格式解析
"""
import struct
class Point(object):
def__init__(self, x_s_f, y_s_f, z_s_f, x_o, y_o, z_o):
self.x_scale_factor = x_s_f
self.y_scale_factor = y_s_f
self.z_scale_factor = z_s_f
self.x_offset = x_o
self.y_offset = y_o
self.z_offset = z_o
def get_offset_bytes(self, point_data_record_format):
"""
根据不同的点格式跳过的字节数
:param point_data_record_format:点格式0~10
:return:
"""
# x,y,z共占12字节
data_format ={
0:8,# 点格式0 共20字节
1:16,# 点格式1 共28字节
2:14,# 点格式2 共26字节
3:22,# 点格式3 共34字节
4:45,# 点格式4 共57字节

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。