使用 numpy 在边界框中查找点
Finding points within a bounding box with numpy
我有来自多个点云文件的数百万个 xyz 坐标,我将它们存储在二维 numpy 数组中:[[x1, y1, z1], [x2, y2, z2],..., [xn, yn, zn]]
。
我想过滤由 4 个坐标 [[x1, y1], [x2, y2]]
描述的特定边界框内的所有点,即矩形的左下角坐标和右上角坐标。
我已经找到了下面这段用numpy过滤坐标的代码,这几乎是我想要的。唯一的区别是(如果我没弄错的话)我的二维数组也有 z 坐标。
import random
import numpy as np
points = [(random.random(), random.random()) for i in range(100)]
bx1, bx2 = sorted([random.random(), random.random()])
by1, by2 = sorted([random.random(), random.random()])
pts = np.array(points)
ll = np.array([bx1, by1]) # lower-left
ur = np.array([bx2, by2]) # upper-right
inidx = np.all(np.logical_and(ll <= pts, pts <= ur), axis=1)
inbox = pts[inidx]
outbox = pts[np.logical_not(inidx)]
我将如何修改上面的代码以使其与 xyz 坐标一起工作,以通过用两个 xy 坐标描述的边界框进行过滤?
Select你点的X和Y坐标:
xy_pts = pts[:,[0,1]]
现在,只需在比较中使用 xy_pts
而不是 pts
:
inidx = np.all((ll <= xy_pts) & (xy_pts <= ur), axis=1)
我正在写一个 Python library for working with point clouds,我有这个功能,我认为它应该适合你:
def bounding_box(points, min_x=-np.inf, max_x=np.inf, min_y=-np.inf,
max_y=np.inf, min_z=-np.inf, max_z=np.inf):
""" Compute a bounding_box filter on the given points
Parameters
----------
points: (n,3) array
The array containing all the points's coordinates. Expected format:
array([
[x1,y1,z1],
...,
[xn,yn,zn]])
min_i, max_i: float
The bounding box limits for each coordinate. If some limits are missing,
the default values are -infinite for the min_i and infinite for the max_i.
Returns
-------
bb_filter : boolean array
The boolean mask indicating wherever a point should be keeped or not.
The size of the boolean mask will be the same as the number of given points.
"""
bound_x = np.logical_and(points[:, 0] > min_x, points[:, 0] < max_x)
bound_y = np.logical_and(points[:, 1] > min_y, points[:, 1] < max_y)
bound_z = np.logical_and(points[:, 2] > min_z, points[:, 2] < max_z)
bb_filter = np.logical_and(np.logical_and(bound_x, bound_y), bound_z)
return bb_filter
这是您所问内容的示例:
1000万点:
points = np.random.rand(10000000, 3)
您指定格式的矩形:
rectangle = np.array([[0.2, 0.2],
[0.4, 0.4]])
解压矩形:
min_x = rectangle[:,0].min()
max_x = rectangle[:,0].max()
min_y = rectangle[:,1].min()
max_y = rectangle[:,1].max()
获取框内标记点的布尔数组:
%%timeit
inside_box = bounding_box(points, min_x=min_x, max_x=max_x, min_y=min_y, max_y=max_y)
1 loop, best of 3: 247 ms per loop
这样你就可以使用数组如下:
points_inside_box = points[inside_box]
points_outside_box = points[~inside_box]
我有来自多个点云文件的数百万个 xyz 坐标,我将它们存储在二维 numpy 数组中:[[x1, y1, z1], [x2, y2, z2],..., [xn, yn, zn]]
。
我想过滤由 4 个坐标 [[x1, y1], [x2, y2]]
描述的特定边界框内的所有点,即矩形的左下角坐标和右上角坐标。
我已经找到了下面这段用numpy过滤坐标的代码,这几乎是我想要的。唯一的区别是(如果我没弄错的话)我的二维数组也有 z 坐标。
import random
import numpy as np
points = [(random.random(), random.random()) for i in range(100)]
bx1, bx2 = sorted([random.random(), random.random()])
by1, by2 = sorted([random.random(), random.random()])
pts = np.array(points)
ll = np.array([bx1, by1]) # lower-left
ur = np.array([bx2, by2]) # upper-right
inidx = np.all(np.logical_and(ll <= pts, pts <= ur), axis=1)
inbox = pts[inidx]
outbox = pts[np.logical_not(inidx)]
我将如何修改上面的代码以使其与 xyz 坐标一起工作,以通过用两个 xy 坐标描述的边界框进行过滤?
Select你点的X和Y坐标:
xy_pts = pts[:,[0,1]]
现在,只需在比较中使用 xy_pts
而不是 pts
:
inidx = np.all((ll <= xy_pts) & (xy_pts <= ur), axis=1)
我正在写一个 Python library for working with point clouds,我有这个功能,我认为它应该适合你:
def bounding_box(points, min_x=-np.inf, max_x=np.inf, min_y=-np.inf,
max_y=np.inf, min_z=-np.inf, max_z=np.inf):
""" Compute a bounding_box filter on the given points
Parameters
----------
points: (n,3) array
The array containing all the points's coordinates. Expected format:
array([
[x1,y1,z1],
...,
[xn,yn,zn]])
min_i, max_i: float
The bounding box limits for each coordinate. If some limits are missing,
the default values are -infinite for the min_i and infinite for the max_i.
Returns
-------
bb_filter : boolean array
The boolean mask indicating wherever a point should be keeped or not.
The size of the boolean mask will be the same as the number of given points.
"""
bound_x = np.logical_and(points[:, 0] > min_x, points[:, 0] < max_x)
bound_y = np.logical_and(points[:, 1] > min_y, points[:, 1] < max_y)
bound_z = np.logical_and(points[:, 2] > min_z, points[:, 2] < max_z)
bb_filter = np.logical_and(np.logical_and(bound_x, bound_y), bound_z)
return bb_filter
这是您所问内容的示例:
1000万点:
points = np.random.rand(10000000, 3)
您指定格式的矩形:
rectangle = np.array([[0.2, 0.2],
[0.4, 0.4]])
解压矩形:
min_x = rectangle[:,0].min()
max_x = rectangle[:,0].max()
min_y = rectangle[:,1].min()
max_y = rectangle[:,1].max()
获取框内标记点的布尔数组:
%%timeit
inside_box = bounding_box(points, min_x=min_x, max_x=max_x, min_y=min_y, max_y=max_y)
1 loop, best of 3: 247 ms per loop
这样你就可以使用数组如下:
points_inside_box = points[inside_box]
points_outside_box = points[~inside_box]