0

我了解矢量化的概念,以及当您想要调整每个单独的元素时如何避免使用循环来遍历元素,但是当我们有一个基于条件的条件时,我无法弄清楚如何做到这一点像素的相邻值。

例如,如果我有一个面具:

mask = np.array([[0,0,0,0],
                 [1,0,0,0],
                 [0,0,0,1], 
                 [1,0,0,0]])

我想通过评估掩码中的相邻组件来更改元素,如下所示:

if sum(mask[j-1:j+2,i-1:i+2].flatten())>1 and mask[j,i]!=1:
    out[j,i]=1

当我特别需要访问相邻元素时,如何对操作进行矢量化?

提前致谢。

完整循环:

import numpy as np

mask = np.array([[0,0,0,0], [1,0,0,0], [0,0,0,1],  [1,0,0,0]])
out = np.zeros(mask.shape)
for j in range(len(mask)):
    for i in range(len(mask[0])):
        if sum(mask[j-1:j+2,i-1:i+2].flatten())>1 and mask[j,i]!=1:
            out[j,i]=1

输出:

[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 0. 0.]]
4

1 回答 1

1

这种“邻域求和”操作通常称为 2D卷积。在您的情况下,由于您没有任何权重,因此可以在 (IMO 有点不好命名) 中有效地实现它scipy.ndimage.uniform_filter,它可以计算邻域的平均值(并且总和只是平均值乘以大小)。

import numpy as np
from scipy.ndimage import uniform_filter

mask = np.array([[0,0,0,0], [1,0,0,0], [0,0,0,1], [1,0,0,0]])
neighbor_sum = 9 * uniform_filter(mask.astype(np.float32), 3, mode="constant")
neighbor_sum = np.rint(neighbor_sum).astype(int)
out = ((neighbor_sum > 1) & (mask != 1)).astype(int)
print(out)

输出(与您的示例不同,但手动查看是正确的,假设您不希望边缘环绕):

[[0 0 0 0]
 [0 0 0 0]
 [1 1 0 0]
 [0 0 0 0]]

如果您确实希望边缘环绕(或其他边缘行为),请mode查看uniform_filter.

于 2021-07-14T09:25:50.687 回答