Подтвердить что ты не робот

Есть ли функция "ограничивающей рамки" (срез с ненулевыми значениями) для ndarray в NumPy?

Я имею дело с массивами, созданными с помощью numpy.array(), и мне нужно нарисовать точки на холсте, имитирующем изображение. Поскольку вокруг центральной части массива много значимых значений, содержащих содержательные данные, я хотел бы "обрезать" массив, стирая столбцы, содержащие только нули и строки, содержащие только нули.

Итак, я хотел бы узнать о какой-либо встроенной функции numpy или даже фрагменте кода для "обрезки" или найти "ограничительную рамку" для среза только содержащую данные часть массива.

(так как это концептуальный вопрос, я не поставил никакого кода, извините, если я должен, я очень свежусь к публикации в SO.)

Спасибо за чтение

4b9b3361

Ответ 1

Код ниже, этот ответ работает быстрее всего в моих тестах:

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, имеющее примерно 50 × 100 ненулевую область).

Ответ 2

Это должно сделать это:

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]

Ответ 3

Что-то вроде:

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

Результирующие массивы будут 1D баллианских массивов. Настройте их на обоих концах, чтобы найти "ограничивающий прямоугольник".