Is there a “bounding box” function (slice with non-zero values) for a ndarray in NumPy?

后端 未结 3 763
隐瞒了意图╮
隐瞒了意图╮ 2020-12-10 11:06

I am dealing with arrays created via numpy.array(), and I need to draw points on a canvas simulating an image. Since there is a lot of zero values around the central part of

相关标签:
3条回答
  • 2020-12-10 11:30

    This should do it:

    from numpy import array, argwhere
    
    A = array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 0, 0, 0, 0],
               [0, 0, 1, 1, 0, 0, 0],
               [0, 0, 0, 0, 1, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
    
    B = argwhere(A)
    (ystart, xstart), (ystop, xstop) = B.min(0), B.max(0) + 1 
    Atrim = A[ystart:ystop, xstart:xstop]
    
    0 讨论(0)
  • 2020-12-10 11:34

    The code below, from this answer runs fastest in my tests:

    def bbox2(img):
        rows = np.any(img, axis=1)
        cols = np.any(img, axis=0)
        ymin, ymax = np.where(rows)[0][[0, -1]]
        xmin, xmax = np.where(cols)[0][[0, -1]]
        return img[ymin:ymax+1, xmin:xmax+1]
    

    The accepted answer using argwhere worked but ran slower. My guess is, it's because argwhere allocates a giant output array of indices. I tested on a large 2D array (a 1024 x 1024 image, with roughly a 50x100 nonzero region).

    0 讨论(0)
  • 2020-12-10 11:53

    Something like:

    empty_cols = sp.all(array == 0, axis=0)
    empty_rows = sp.all(array == 0, axis=1)
    

    The resulting arrays will be 1D boolian arrays. Loop on them from both ends to find the 'bounding box'.

    0 讨论(0)
提交回复
热议问题