NumPy中是否有“边界框”函数(切片非零值的数组)?

23 投票
3 回答
11126 浏览
提问于 2025-04-16 10:40

我正在处理通过numpy.array()创建的数组,我需要在一个画布上绘制点,模拟一幅图像。因为数组中间部分包含有用的数据,而周围有很多零值,所以我想“修剪”这个数组,去掉那些只包含零的列和行。

所以,我想知道有没有一些numpy自带的函数,或者是一些代码片段,可以用来“修剪”数组,找到一个“边界框”,只保留包含数据的部分。

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

谢谢你的阅读

3 个回答

0

类似这样的:

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

最终得到的数组将是一个一维的布尔数组。你可以从两端开始循环,找到“边界框”。

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]
17

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

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 的非零区域)。

撰写回答