我的目标是实现一个python函数,通过仅返回每个非重叠网格单元格中具有最高z
值的点来稀释激光雷达点云。
每个网格单元只返回一个点。
我在python中编写了以下函数,但与MATLAB中的类似实现相比,处理样本文件需要更长的时间(大约慢10倍)。
我可以改变功能以加快速度吗?
在函数中,数据是Nx3数组,csize是非重叠网格单元的大小。
def pcthin(data, csize):
md = data
xx = np.arange(np.min(md[:,0]), csize*(np.ceil(max(md[:,0]))/csize), csize)
yy = np.arange(np.min(md[:,1]), csize*(np.ceil(max(md[:,1]))/csize), csize)
X,Y = np.meshgrid(xx,yy, sparse=False, indexing='xy')
thindata = np.zeros_like(data)
k = 0
xf = X.flatten()
yf = Y.flatten()
for x,y in zip(xf,yf):
tf1 = np.logical_and(md[:,0] > x, md[:,0] <= x + csize)
tf2 = np.logical_and(md[:,1] > y, md[:,1] <= y + csize)
tf = np.logical_and(tf1,tf2)
if any(tf):
dtx = md[tf,:]
ix = np.argmax(dtx[:,2])
thindata[k,:] = dtx[ix,:]
k = k + 1
return thindata[0:k+1,:]
答案 0 :(得分:1)
更新有关代码的答案
事情是天真的&#34;对于&#34;循环在Python中很慢,而且你的代码有一个很大的for循环。要获得Python的最大速度,您应该尝试"vectorize" your code或使用numba并尝试使用for循环重写代码,就像编写C ++一样。
旧答案
因此,如果我正确理解您的问题,您可以使用https://github.com/daavoo/pyntcloud
完成此操作加载示例点云:
from pyntcloud import PyntCloud
cloud = PyntCloud.from_file("tests/data/sphere.ply")
看起来像这样:
然后你必须构建一个非重叠单元格的网格(在pyntcloud中称为voxelgrid)。
此处size_x
和size_y
是指定沿每个轴的单元格大小的方式。
voxelgrid_id = cloud.add_structure("voxelgrid", size_x=10, size_y=10)
voxelgrid看起来像这样:
最后,您可以通过选择每个单元格的最高点来获得新的点云:
thinned_cloud = cloud.get_sample(
"voxelgrid_highest",
voxelgrid_id=voxelgrid_id,
as_PyntCloud=True)
看起来像这样:
您可以按如下方式访问新的细化点云的xyz值:
data = thinned_cloud.xyz
这在内部使用pandas.groupby,与您发布的代码相比,这应该是速度提升。但是,如果这仍然不是很快,我会建议您尝试https://numba.pydata.org/
在https://github.com/daavoo/pyntcloud/blob/master/pyntcloud/utils/numba.py
中有一些可能对您有用的示例操作