Numpy 点云到图像

Numpy point cloud to image

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

红点是点,黑点是红点投影到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 分量的向量)。虽然这工作正常,但它当然只将最后一个点放在每个给定像素上,即它不是累加的。

非常感谢您的帮助!

由@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.4432s0.0368s。如此整洁的 12 倍加速。

============ 编辑 ============

快速更新:使用手电筒...

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 上,因此 59 倍加速比 python 循环。我还在 GPU 上尝试了 运行,它似乎没有影响速度,我猜 accumulate=True 可能是在 GPU 上使用了某种原子,这会减慢速度.