我有一个点云,看起来像这样:

红点是点,黑点是投影到xy平面的红点。虽然在图中它是不可见的,但是每个点也有一个值,当点被移动到xy平面时,这个值被添加到给定的像素中。点由numpy (np)数组表示,如下所示:
points=np.array([[x0,y0,z0,v0],[x1,y1,z1,v1],...[xn,yn,zn,vn]])将这些点放入某些图像的明显方法是通过一个简单的循环,如下所示:
image=np.zeros(img_size)
for point in points:
#each point = [x,y,z,v]
image[tuple(point[0:2])] += point[3]这很好,但速度很慢。因此,我想知道是否有某种方式使用矢量化、切片和其他聪明的numpy/python技巧来加快速度,因为实际上,对于大点云,我不得不这样做很多次。我想出了一些使用np.put的方法
def points_to_image(xs, ys, vs, img_size):
img = np.zeros(img_size)
coords = np.stack((ys, xs))
#put the 2D coordinates into linear array coordinates
abs_coords = np.ravel_multi_index(coords, img_size)
np.put(img, abs_coords, ps)
return img(在这种情况下,点被预先分割成包含x、y和v分量的向量)。虽然这样做很好,但它当然只将最后一点放在每个给定的像素上,即它不是加性的。
非常感谢你的帮助!
发布于 2020-03-12 01:01:19
@Paul Panzer提供:
def points_to_image(xs, ys, ps, img_size):
coords = np.stack((ys, xs))
abs_coords = np.ravel_multi_index(coords, img_size)
img = np.bincount(abs_coords, weights=ps, minlength=img_size[0]*img_size[1])
img = img.reshape(img_size)在我的机器上,循环版本采用0.4432s和0.0368s,使用矢量化。所以一次干净的12x加速。
============编辑============
快速更新:使用火炬。
def points_to_image_torch(xs, ys, ps, sensor_size=(180, 240)):
xt, yt, pt = torch.from_numpy(xs), torch.from_numpy(ys), torch.from_numpy(ps)
img = torch.zeros(sensor_size)
img.index_put_((yt, xt), pt, accumulate=True)
return img我一路走到0.00749。这仍然发生在CPU上,所以59x加速比python循环。我也试过在GPU上运行它,它似乎在速度上没有什么不同,我想在accumulate=True上它可能是在GPU上使用某种原子来减缓速度。
https://stackoverflow.com/questions/60646028
复制相似问题