【问题标题】:Finding points within a bounding box with numpy使用 numpy 在边界框中查找点
【发布时间】:2017-07-10 04:59:40
【问题描述】:

我有来自多个点云文件的数百万个 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 坐标描述的边界框进行过滤?

【问题讨论】:

    标签: python numpy coordinates point-clouds


    【解决方案1】:

    选择您的点的 X 和 Y 坐标:

    xy_pts = pts[:,[0,1]]
    

    现在,只需在比较中使用xy_pts 而不是pts

    inidx = np.all((ll <= xy_pts) & (xy_pts <= ur), axis=1)
    

    【讨论】:

    • 但是像这样我会丢失 z 信息吗?我肯定需要保留这些以供以后计算。
    • @conste 您将使用原始 3D pts 来构造 inbox
    【解决方案2】:

    我正在写一个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]
    

    【讨论】:

    • 我目前正在处理一个类似的问题,我喜欢你的回答。但是,您的代码似乎确实提供了一个与轴平行的边界框。您对如何获得最小边界框有任何提示或解决方案吗?
    • 3D边界框通常有8个坐标。
    猜你喜欢
    • 1970-01-01
    • 2013-06-03
    • 2016-01-08
    • 1970-01-01
    • 2018-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    相关资源
    最近更新 更多