一般来说,您需要查看scipy.ndimage.label 和scipy.ndimage.find_objects 以提取满足条件的连续区域的边界框。
但是,在这种情况下,您可以使用“普通”numpy 轻松完成。
我假设你在这里有一个nrows x ncols x nbands 数组。 nbands x nrows x ncols 的另一个约定也很常见,所以看看你的数组的形状。
考虑到这一点,您可能会做类似的事情:
mask = im == 0
all_white = mask.sum(axis=2) == 0
rows = np.flatnonzero((~all_white).sum(axis=1))
cols = np.flatnonzero((~all_white).sum(axis=0))
crop = im[rows.min():rows.max()+1, cols.min():cols.max()+1, :]
对于您的 2D 示例,它看起来像:
import numpy as np
im = np.array([[0,0,0,0,0,0],
[0,0,1,1,1,0],
[0,1,1,0,1,0],
[0,0,0,1,1,0],
[0,0,0,0,0,0]])
mask = im == 0
rows = np.flatnonzero((~mask).sum(axis=1))
cols = np.flatnonzero((~mask).sum(axis=0))
crop = im[rows.min():rows.max()+1, cols.min():cols.max()+1]
print crop
让我们稍微分解一下 2D 示例。
In [1]: import numpy as np
In [2]: im = np.array([[0,0,0,0,0,0],
...: [0,0,1,1,1,0],
...: [0,1,1,0,1,0],
...: [0,0,0,1,1,0],
...: [0,0,0,0,0,0]])
好的,现在让我们创建一个满足我们条件的布尔数组:
In [3]: mask = im == 0
In [4]: mask
Out[4]:
array([[ True, True, True, True, True, True],
[ True, True, False, False, False, True],
[ True, False, False, True, False, True],
[ True, True, True, False, False, True],
[ True, True, True, True, True, True]], dtype=bool)
另外,请注意 ~ 运算符在布尔数组上的作用类似于 logical_not:
In [5]: ~mask
Out[5]:
array([[False, False, False, False, False, False],
[False, False, True, True, True, False],
[False, True, True, False, True, False],
[False, False, False, True, True, False],
[False, False, False, False, False, False]], dtype=bool)
考虑到这一点,要找到所有元素都为假的行,我们可以跨列求和:
In [6]: (~mask).sum(axis=1)
Out[6]: array([0, 3, 3, 2, 0])
如果没有元素为真,我们将得到一个 0。
类似地,要找到所有元素都为假的列,我们可以跨行求和:
In [7]: (~mask).sum(axis=0)
Out[7]: array([0, 1, 2, 2, 3, 0])
现在我们需要做的就是找到不为零的第一个和最后一个。 np.flatnonzero 比 nonzero 简单一点,在这种情况下:
In [8]: np.flatnonzero((~mask).sum(axis=1))
Out[8]: array([1, 2, 3])
In [9]: np.flatnonzero((~mask).sum(axis=0))
Out[9]: array([1, 2, 3, 4])
然后,您可以轻松地根据最小/最大非零元素切出区域:
In [10]: rows = np.flatnonzero((~mask).sum(axis=1))
In [11]: cols = np.flatnonzero((~mask).sum(axis=0))
In [12]: im[rows.min():rows.max()+1, cols.min():cols.max()+1]
Out[12]:
array([[0, 1, 1, 1],
[1, 1, 0, 1],
[0, 0, 1, 1]])