Как применить маску в форме диска к массиву numpy?

У меня такой массив:

>>> np.ones((8,8)) array([[ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.]]) 

Я создаю маску в форме диска с радиусом 3, таким образом:

 y,x = np.ogrid[-3: 3+1, -3: 3+1] mask = x**2+y**2 <= 3**2 

Это дает:

 >> mask array([[False, False, False, True, False, False, False], [False, True, True, True, True, True, False], [False, True, True, True, True, True, False], [ True, True, True, True, True, True, True], [False, True, True, True, True, True, False], [False, True, True, True, True, True, False], [False, False, False, True, False, False, False]], dtype=bool) 

Теперь я хочу применить эту маску к моему массиву, используя любой элемент в качестве центральной точки. Так, например, с центральной точкой в ​​(1,1), я хочу получить массив вроде:

 >>> new_arr array([[ True, True, True, True, 1., 1., 1., 1.], [ True, True, True, True, True, 1., 1., 1.], [ True, True, True, True, 1., 1., 1., 1.], [ True, True, True, True, 1., 1., 1., 1.], [ 1., True, 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.]]) 

Есть ли простой способ применить эту маску?

Изменить: у меня не должно быть смешанных булевых и плавающих – это вводит в заблуждение.

 >>> new_arr array([[ 255., 255., 255., 255., 1., 1., 1., 1.], [ 255., 255., 255., 255., 255., 1., 1., 1.], [ 255., 255., 255., 255., 1., 1., 1., 1.], [ 255., 255., 255., 255., 1., 1., 1., 1.], [ 1., 255., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1., 1., 1., 1.]]) 

Это больше результат, который мне нужен.

array [mask] = 255

будет маскировать массив с помощью центральной точки (0 + радиус, 0 + радиус).

Тем не менее, я хотел бы иметь возможность размещать любую маску размера в любой точке (y, x) и автоматически ее подгонять.

6 Solutions collect form web for “Как применить маску в форме диска к массиву numpy?”

Я бы сделал это так, где (a, b) является центром вашей маски:

 import numpy as np a, b = 1, 1 n = 7 r = 3 y,x = np.ogrid[-a:na, -b:nb] mask = x*x + y*y <= r*r array = np.ones((n, n)) array[mask] = 255 

Я просто хотел поделиться со всеми немного более продвинутым применением этой техники, с которой мне просто пришлось столкнуться.

Моя проблема заключалась в том, чтобы применить это круговое ядро ​​для вычисления среднего значения всех значений, окружающих каждую точку в 2D-матрице. Сгенерированное ядро ​​может быть передано в общий фильтр scipy следующим образом:

 import numpy as np from scipy.ndimage.filters import generic_filter as gf kernel = np.zeros((2*radius+1, 2*radius+1)) y,x = np.ogrid[-radius:radius+1, -radius:radius+1] mask = x**2 + y**2 <= radius**2 kernel[mask] = 1 circular_mean = gf(data, np.mean, footprint=kernel) 

Надеюсь это поможет!

Для удобства использования:

 def cmask(index,radius,array): a,b = index nx,ny = array.shape y,x = np.ogrid[-a:nx-a,-b:ny-b] mask = x*x + y*y <= radius*radius return(sum(array[mask])) 

Возвращает сумму пикселя в радиусе или возвращает (array [mask] = 2) для любой необходимости.

Вы пытались сделать маску или нули и единицы, а затем использовать умножение массива на элемент? Это канонический путь, более или менее.

Кроме того, вы уверены, что хотите комбинировать числа и булевы в массиве numpy ? NumPy, как следует из названия, лучше всего работает с числами.

Вы можете использовать функцию convilve от scipy, которая имеет преимущество, позволяя вам помещать любую конкретную маску, например ядро, на любое количество заданных координат в вашем массиве:

 import numpy as np from scipy.ndimage.filters import convolve 

Сначала создайте массив координат с координатой, где вы хотите, чтобы маска (ядро) была центрирована, отмечена как 2

 background = np.ones((10,10)) background[5,5] = 2 print(background) [[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 2. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]] 

Создайте свою маску:

 y,x = np.ogrid[-3: 3+1, -3: 3+1] mask = x**2+y**2 <= 3**2 mask = 254*mask.astype(float) print(mask) [[ 0. 0. 0. 254. 0. 0. 0.] [ 0. 254. 254. 254. 254. 254. 0.] [ 0. 254. 254. 254. 254. 254. 0.] [ 254. 254. 254. 254. 254. 254. 254.] [ 0. 254. 254. 254. 254. 254. 0.] [ 0. 254. 254. 254. 254. 254. 0.] [ 0. 0. 0. 254. 0. 0. 0.]] 

Сверните два изображения:

 b = convolve(background, mask)-sum(sum(mask))+1 print(b) [[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 255. 1. 1. 1. 1.] [ 1. 1. 1. 255. 255. 255. 255. 255. 1. 1.] [ 1. 1. 1. 255. 255. 255. 255. 255. 1. 1.] [ 1. 1. 255. 255. 255. 255. 255. 255. 255. 1.] [ 1. 1. 1. 255. 255. 255. 255. 255. 1. 1.] [ 1. 1. 1. 255. 255. 255. 255. 255. 1. 1.] [ 1. 1. 1. 1. 1. 255. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]] 

Заметим, что записи функции свертки не коммутируют, т. Е. Свертывают (a, b)! = Convolve (b, a)

Заметим также, что если ваша точка находится рядом с ребром, алго не воспроизводит ядро ​​в координате. Чтобы обойти это, вы можете наложить фон на самую большую ось вашего ядра, применить свертку, а затем удалить прокладку.

Теперь вы можете сопоставить любое ядро ​​с любым количеством точек в массиве, но обратите внимание, что если два ядра перекрываются, они добавляются при перекрытии. Вы можете установить порог, если вам нужно.

Чтобы получить тот же результат, что и в вашем примере, вы можете сделать что-то вроде этого:

 >>> new_arr = np.array(ones, dtype=object) >>> new_arr[mask[2:, 2:]] = True >>> print new_arr array([[True, True, True, True, 1.0, 1.0, 1.0, 1.0], [True, True, True, True, True, 1.0, 1.0, 1.0], [True, True, True, True, 1.0, 1.0, 1.0, 1.0], [True, True, True, True, 1.0, 1.0, 1.0, 1.0], [1.0, True, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], dtype=object) 
Python - лучший язык программирования в мире.