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.4432s
与 0.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 上使用了某种原子,这会减慢速度.
我有一个看起来像这样的点云:
红点是点,黑点是红点投影到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.4432s
与 0.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 上使用了某种原子,这会减慢速度.