我有一个代表 cloud mask for GIS data 的 bool 数据的 MxN numpy 数组.我想通过在所有方向上移动 n 个单元格来扩展蒙版。这是一种去除蒙版中的云阴影(位于云像素旁边)的简单方法。 这些 numpy 数组通常介于 1000x1000 和 10000x10000 像素之间。
我的问题与此类似one但在 2 个维度上。
我的非常简单但效率低下的解决方案如下所示:
def expand_for(arr, shiftx=1, shifty=1):
arr_b = arr.copy().astype(bool)
for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
if(arr[i,j]):
i_min, i_max = max(i-shifty, 0), min(i+shifty+1, arr.shape[0])
j_min, j_max = max(j-shiftx, 0), min(j+shiftx+1, arr.shape[1])
arr_b[i_min:i_max, j_min:j_max] = True
return arr_b
另一种解决方案是:
def shift_array(arr, x, y):
d, u, r, l = max(y, 0), max(-y, 0), max(x, 0), max(-x, 0)
ret = np.pad(arr, ((d, u), (r, l)), mode='constant')
return ret[u or None: -d or None, l or None: -r or None]
def expand_array(arr, shiftx=1, shifty=1):
return np.dstack([shift_array(arr, x, y)
for x in range(-shiftx, shiftx + 1) for y in range(-shifty, shifty + 1)]).any(axis=2)
但是复杂度会随着 shiftx 和 shifty 的大小而增加。
这是我正在尝试做的一个非常简单的例子:
a = np.array([[0,0,0,0,0],
[0,0,0,0,0],
[0,0,1,0,0],
[0,0,0,0,0],
[0,0,0,0,0]])
expand_for(a, 1, 1)
>>> array([[False, False, False, False, False],
[False, True, True, True, False],
[False, True, True, True, False],
[False, True, True, True, False],
[False, False, False, False, False]])
我一直在使用这段代码来生成更复杂的测试数据:
N = 100 # or 1000, 10000...
a = np.random.random((N,N))
a = (a < 0.30)*1
最佳答案
这可以通过应用 dilation 使用 cv2 库来完成到阵列。例如:
import numpy as np
N = 10
# the initial array
a = np.zeros((N, N), dtype='uint8')
a[[2, 4, 9], [2, 4, 7]] = 1
print(a)
这给出:
[[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 1 0 0]]
将每次出现的 1 展开为 1 的 3x3 子数组:
import cv2
kernel = np.ones((3, 3), dtype='uint8')
out = cv2.dilate(a, kernel)
print(out)
结果:
[[0 0 0 0 0 0 0 0 0 0]
[0 1 1 1 0 0 0 0 0 0]
[0 1 1 1 0 0 0 0 0 0]
[0 1 1 1 1 1 0 0 0 0]
[0 0 0 1 1 1 0 0 0 0]
[0 0 0 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 1 1 1 0]
[0 0 0 0 0 0 1 1 1 0]]
如果你希望结果是一个 bool 值数组,那么你可以改变它的数据类型:
out = out.astype('bool')
关于python - 有效地将 2D numpy mask 在所有方向上扩展 n 个单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73798936/