В общем, вы хотите посмотреть в 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]])
Это предполагает, что регион является известным прямоугольным форма. –
как насчет столбцов с нулевыми значениями? – keksnicoh
Ну, это * будет * быть прямоугольником, поскольку я только хочу удалить полностью пустые строки/столбцы. – Jonline