2017-02-20 56 views
3

我在多維點雲數據文件中存儲了數百萬個xyz座標,這些文件存儲在二維numpy數組中:[[x1, y1, z1], [x2, y2, z2],..., [xn, yn, zn]]在numpy邊界框內查找點

我想過濾由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)] 

我怎麼會得modifiy上面的代碼,使其與XYZ座標的工作由兩個x,y座標描述的邊框來過濾?

回答

3

選擇X和貴點的Y座標:

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

現在,只需使用xy_pts,而不是pts的比較:

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

但像這樣我就失去了Z-信息,或沒有?我肯定需要保留這些以備後續計算。 – conste

+0

@conste您將使用原始的3D「pts」來構建「收件箱」。 – DyZ

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(bound_x, bound_y, bound_z) 

    return bb_filter 

這裏是你問一個例子:在格式指定

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]