我正在处理通过 numpy.array() 创建的数组,我需要在模拟图像的画布上绘制点。由于包含有意义数据的数组的中心部分周围有很多零值,我想“修剪”数组,擦除仅包含零的列和仅包含零的行。
所以,我想知道一些本机 numpy 函数,甚至是一个代码片段来“修剪”或找到一个“边界框”来仅对数组中包含数据的部分进行切片。
(因为这是一个概念性的问题,所以我没有放任何代码,如果我应该放,我很抱歉,我很新鲜在 SO 上发帖。)
谢谢阅读
这应该这样做:
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]
下面的代码,来自这个答案,在我的测试中运行得最快:
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 非零区域)上进行了测试。
就像是:
empty_cols = sp.all(array == 0, axis=0)
empty_rows = sp.all(array == 0, axis=1)
结果数组将是一维布尔数组。从两端循环它们以找到“边界框”。