Существует ли функция "ограничивающего прямоугольника" (срез с ненулевыми значениями) для ndarray в NumPy?
Я имею дело с массивами, созданными с помощью numpy.array(), и мне нужно рисовать точки на холсте, имитирующем изображение. Поскольку вокруг центральной части массива, который содержит значимые данные, много нулевых значений, я бы хотел "обрезать" массив, удалив столбцы, которые содержат только нули, и строки, содержащие только нули.
Итак, я хотел бы знать о некоторой нативной функции numpy или даже фрагменте кода, чтобы "обрезать" или найти "ограничивающий прямоугольник", чтобы разрезать только часть, содержащую данные массива.
(Поскольку это концептуальный вопрос, я не ставил никакого кода, извините, если должен, я очень новичок в публикации на SO.)
Спасибо за прочтение
3 ответа
Код ниже, из этого ответа работает быстрее всего в моих тестах:
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).
Это должно сделать это:
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]
Что-то вроде:
empty_cols = sp.all(array == 0, axis=0)
empty_rows = sp.all(array == 0, axis=1)
Полученные массивы будут одномерными булевыми массивами. Зафиксируйте их с обоих концов, чтобы найти "ограничивающую рамку".