Python读取点云与可视化
最近开始学习处理点云数据,之前是用LiDAR 360来进行预处理,但软件还是无法实现许多功能,开个贴记录下python对点云的处理过程。
一、点云的读取与索引
点云数据的格式由于不同扫描仪硬件厂商而有多种格式,但一般而言这些格式都可以转换为通用的点云格式,主要包括LAS和ASCII两种形式,其中ASCII中包括了ASC/XYZ/TXT/PTC/PTS/PTX等格式。
以下分别列举关于LAS与TXT(导入了EXECL)的读取方法。
1. 通过pandas包读取
import pandas as pd
df = pd.read_excel("/test3.xlsx")
loc_x = df['x'].values
loc_y = df['y'].values
loc_z = df['z'].values
print(loc_x)
print(loc_y)
print(loc_z)
##如果需要强度等其他信息也一样
2.通过Laspy包读取
Laspy是一个Python的开源库,能够直接读取LAS文件
import laspy
lasfile = "/121n3.las"
#打开并以只读显示
inFile = laspy.file.File(lasfile,mode="r")
#读取x,y,z
x,y,z = inFile.x,inFile.y,inFile.z
#读取分类信息
classfication = inFile.get_raw_classification
#读取回波信息
return_num = inFile.return_num
#读取扫描角度信息
scan_angle_rank = inFile.get_scan_angle_rank
关于点云的索引方式:
为了方便读取海量点云的处理,建立合适空间索引能够帮助我们快速的查找以及筛选点云,目前主要有规则网、kd树和八叉树等索引方式。
from scipy import spatial
#封装x,y,如果要建立三位索引则要封装xyz
lasdata = list(zip(x,y))
#构建kd树
tree = spatial.KDTree(lasdata)
#查找中心点(294110.3305,3640435.33)半径为10m圆内的点云
aa = tree.query_ball_point(np.array([294110.3305,3640435.33]),10)
#显示搜索到的点云
print(z[aa])
X = x[aa]
Y = y[aa]
Z = z[aa]
此外也可以根据其他方式来对点云进行简单的筛选
例如:查找高度大于15m的点云
newdata = pd.DataFrame({"x":X,"y":Y,"z":Z})
sort_data = newdata[newdata["z"]>15]
二、可视化
看到许多大佬用 python-pcl 和 mayavi 来完成可视化,但安装过分麻烦所以用 matplotlib 来完成可视化,相当于建立一个三维的图像,缺点是点云多了就比较卡。
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(12, 10),dpi=80)
ax = fig.add_subplot(111, projection='3d')
X = sort_data["x"]
Y = sort_data["y"]
Z = sort_data["z"]
ax.scatter(X, Y, Z,s= 10,edgecolor="black",marker=".")
plt.show()
结果如下:
此外可以根据可以按高度附着颜色信息以及其他设置
import matplotlib.colors
cmap = plt.cm.get_cmap("rainbow")
norm = matplotlib.colors.Normalize(vmin=min(loc_z), vmax=max(loc_z))
fig = plt.figure(dpi = 150)
ax = fig.add_subplot(111,projection = "3d")
ax.scatter(loc_x, loc_y,loc_z,s= 0.0005*np.array(120-loc_z)**2,color=cmap(norm(df.z.values)),marker=".")
# 加入z轴范围颜色的图例
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
fig.colorbar(sm)
ax.grid(False)
结果如下(换了一个数据):