Выделение пикселей в массиве с помощью структурирующего элемента в python 3

#python #python-3.x #numpy #scipy

#python #python-3.x #numpy #scipy

Вопрос:

Я ищу способ выбора «пикселей» в массиве с помощью структурирующего элемента: представьте, что у нас есть этот массив a и этот структурирующий элемент s,

 a=np.array([[ 0,  1,  2,  3,  4,  5,  6],
         [ 7,  8,  9, 10, 11, 12, 13],
         [14, 15, 16, 17, 18, 19, 20],
         [21, 22, 23, 24, 25, 26, 27],
         [28, 29, 30, 31, 32, 33, 34],
         [35, 36, 37, 38, 39, 40, 41],
         [42, 43, 44, 45, 46, 47, 48]])
s=np.array([[0,1,0],
         [1,1,1],
         [0,1,0]])
  

Затем я ищу функцию, которая будет действовать как

 f(a, position=(3,3), structure=s) = [17,23,24,25,31]
  

Похоже, что функции морфологии scipy.ndimage могут делать это внутренне. Обходным решением было бы создать массив np.zeros той же формы, что и a, поместить 1 в интересующую позицию и расширить ее, но это было бы очень ресурсоемким — тем более, что мои массивы не 7 * 7.

Комментарии:

1. Вы можете извлечь только интересующую подматрицу, используя линейную индексацию, а затем применить логическую индексацию. Итак, что-то вроде a[2:5,2:5][s != 0]

Ответ №1:

Вот ответ, использующий view_as_windows (который использует numpy strides под капотом):

 from skimage.util import view_as_windows
def f(a, position, structure):
  return view_as_windows(a,structure.shape)[tuple(np.array(position)-1)][structure.astype(bool)]
  

вывод:

 f(a, position=(3,3), structure=s)
#[17 23 24 25 31]
  

если вы передадите массив position как numpy вместо tuple и structure как логический массив вместо int, ответ будет даже короче, поскольку вам не понадобятся преобразования:

 def f(a, position, structure):
      return view_as_windows(a,structure.shape)[tuple(position-1)][structure]