gpt4 book ai didi

python - 用于平滑零区域的 Numpy 过滤器

转载 作者:行者123 更新时间:2023-11-28 18:19:30 25 4
gpt4 key购买 nike

我有一个 0 和更大整数的 2D numpy 数组,其中的值代表区域标签。例如,

array([[9, 9, 9, 0, 0, 0, 0, 1, 1, 1],
[9, 9, 9, 9, 0, 7, 1, 1, 1, 1],
[9, 9, 9, 9, 0, 2, 2, 1, 1, 1],
[9, 9, 9, 8, 0, 2, 2, 1, 1, 1],
[9, 9, 9, 8, 0, 2, 2, 2, 1, 1],
[4, 4, 4, 4, 0, 2, 2, 2, 1, 1],
[4, 6, 6, 4, 0, 0, 0, 0, 0, 0],
[4, 6, 6, 4, 0, 0, 0, 0, 0, 0],
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5],
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5]])

我希望等于 0 的索引(即零区域)采用其邻域中最常见的值。该操作将实质上关闭零区域。我尝试了膨胀、腐 eclipse 的多种变体,grey-closing , 和其他 morphology operations ,但我不能完全消除零区域(不笨拙地混合其他区域)。一个体面的方法可能是定义一个仅对零进行卷积的内核,并使用过滤器区域中最常见的标签设置值。不过,我不确定如何实现。

最佳答案

此处提出了一种矢量化方法。步骤是:

  1. 获取内核大小的 2D 滑动窗口,从而生成 4D 数组。我们可以用skimage's view_as_windows 将它们作为 View 获取,从而避免创建任何额外的内存。

  2. 通过索引到 4D 数组来选择以零为中心的窗口。这会强制复制。但假设零的数量相对小于输入数组中元素的总数,这应该没问题。

  3. 对于每个选定的窗口,使用 np.bincount 执行计数的想法,将每个窗口偏移一个适当的偏移量。因此,使用 bincount 并获得不包括零的最大计数。最大计数的 argmax 应该是我们的人!

这是涵盖这些步骤的实现 -

from skimage.util import view_as_windows as viewW

def fill_zero_regions(a, kernel_size=3):
hk = kernel_size//2 # half_kernel_size

a4D = viewW(a, (kernel_size,kernel_size))
sliced_a = a[hk:-hk,hk:-hk]
zeros_mask = sliced_a==0
zero_neighs = a4D[zeros_mask].reshape(-1,kernel_size**2)
n = len(zero_neighs) # num_zeros

scale = zero_neighs.max()+1
zno = zero_neighs + scale*np.arange(n)[:,None] # zero_neighs_offsetted

count = np.bincount(zno.ravel(), minlength=n*scale).reshape(n,-1)
modevals = count[:,1:].argmax(1)+1
sliced_a[zeros_mask] = modevals
return a

sample 运行-

In [23]: a
Out[23]:
array([[9, 9, 9, 0, 0, 0, 0, 1, 1, 1],
[9, 9, 9, 9, 0, 7, 1, 1, 1, 1],
[9, 9, 9, 9, 0, 2, 2, 1, 1, 1],
[9, 9, 9, 8, 0, 2, 2, 1, 1, 1],
[9, 9, 9, 8, 0, 2, 2, 2, 1, 1],
[4, 4, 4, 4, 0, 2, 2, 2, 1, 1],
[4, 6, 6, 4, 0, 0, 0, 0, 0, 0],
[4, 6, 6, 4, 0, 0, 0, 0, 0, 0],
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5],
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5]])

In [24]: fill_zero_regions(a)
Out[24]:
array([[9, 9, 9, 0, 0, 0, 0, 1, 1, 1],
[9, 9, 9, 9, 9, 7, 1, 1, 1, 1],
[9, 9, 9, 9, 2, 2, 2, 1, 1, 1],
[9, 9, 9, 8, 2, 2, 2, 1, 1, 1],
[9, 9, 9, 8, 2, 2, 2, 2, 1, 1],
[4, 4, 4, 4, 2, 2, 2, 2, 1, 1],
[4, 6, 6, 4, 4, 2, 2, 2, 1, 0],
[4, 6, 6, 4, 4, 5, 5, 5, 5, 0],
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5],
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5]])

如上所示,我们没有解决边界情况。如果需要这样做,请使用零填充数组作为输入数组,如下所示:np.pad(a, (k//2,k//2), 'constant'),以 k 作为内核大小(=3 为样本)。

关于python - 用于平滑零区域的 Numpy 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46126409/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com