【问题标题】:Numpy point cloud to imageNumpy点云图像
【发布时间】:2020-06-24 00:39:11
【问题描述】:

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

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

非常感谢您的帮助!

【问题讨论】:

  • 你很接近。缺少的位是np.bincount。将它与您的 raveled 坐标作为第一个参数,将权重作为第二个参数,将图像大小作为第三个参数一起使用。

标签: python arrays numpy vectorization


【解决方案1】:

感谢@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 上使用了某种原子,这会减慢它的速度。

【讨论】:

  • 不错的实现。在torch代码中,第4行应该是:img.index_put_((yt, xt), pt, accumulate=True)
  • 我正在尝试对已知的内在函数做同样的事情。你能建议一种方法吗? stackoverflow.com/questions/64276915/…
猜你喜欢
  • 1970-01-01
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
  • 2019-07-20
  • 2020-04-22
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多