21

我正在处理通过 numpy.array() 创建的数组,我需要在模拟图像的画布上绘制点。由于包含有意义数据的数组的中心部分周围有很多零值,我想“修剪”数组,擦除仅包含零的列和仅包含零的行。

所以,我想知道一些本机 numpy 函数,甚至是一个代码片段来“修剪”或找到一个“边界框”来仅对数组中包含数据的部分进行切片。

(因为这是一个概念性的问题,所以我没有放任何代码,如果我应该放,我很抱歉,我很新鲜在 SO 上发帖。)

谢谢阅读

4

3 回答 3

24

这应该这样做:

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]
于 2011-01-26T19:29:00.207 回答
14

下面的代码,来自这个答案,在我的测试中运行得最快:

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]

接受的答案使用argwhere有效但运行速度较慢。我的猜测是,这是因为argwhere分配了一个巨大的索引输出数组。我在一个大型二维数组(1024 x 1024 图像,大约 50x100 非零区域)上进行了测试。

于 2017-06-24T08:12:24.593 回答
0

就像是:

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

结果数组将是一维布尔数组。从两端循环它们以找到“边界框”。

于 2011-01-26T19:11:20.857 回答