Numpy点云转图像

6

我有一个点云数据,大致像这样:

The point cloud

图中红色点表示原始点云,黑色点表示将红色点云在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分量的向量。虽然这很好用,但它当然只将最后一个点放在给定像素上,即它不是累加的。
非常感谢您的帮助!

3
你很接近了。缺失的部分是 np.bincount。将其与您的展平坐标作为第一个参数,权重作为第二个参数,图像大小作为第三个参数一起使用。 - Paul Panzer
1个回答

7

感谢@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.4432秒,而向量化只需要0.0368秒。因此速度提高了12倍。
============ 编辑 ============
快速更新:使用torch...
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上进行,比使用Python循环快了59倍。我也尝试在GPU上运行,但速度似乎没有提升。我猜测在accumulate=True的情况下,它可能在GPU上使用某种原子操作来降低速度。


2
不错的实现。在 Torch 代码中,第四行应该是:img.index_put_((yt, xt), pt, accumulate=True) - Victor Zuanazzi
我正在尝试用已知的内参进行相同的操作。你能否提供一种方法来实现这个目标?https://stackoverflow.com/questions/64276915/projection-image-of-known-intrinsics-to-a-point-cloud - user1241241
这个被低估了太多了 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接