Numpy过滤器可平滑零区域 [英] Numpy filter to smooth out zero-regions

查看:108
本文介绍了Numpy过滤器可平滑零区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a 2D numpy array of ints 0 and greater, where the values represent region labels. For example,

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(即零区域)的索引采用其邻域中最常见的值.该操作实质上将关闭零区域.我尝试了膨胀,腐蚀,灰色关闭,以及其他

I would like the indices equal to 0 (i.e. zero-regions) to take on the value most-common in their neighborhood. The operation would essentially close the zero-regions. I've tried multiple variations of dilation, erosion, grey-closing, and other morphology operations, but I cannot completely eliminate the zero-regions (without awkwardly blending the other regions). A decent approach could be to define a kernel that convolves only over the zeros, and sets the value with the most common label in the filter area. I'm unsure how to implement this though.

推荐答案

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

One vectorized approach is proposed here. Steps are :

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

  1. Get kernel sized 2D sliding windows, leading to 4D array. We can use skimage's view_as_windows to get those as view and thus avoid creating any extra memory for this.

通过索引到4D数组来选择以零为中心的窗口.这将强制复制.但是,假设零的个数比输入数组中元素的总数要小,那就可以了.

Select the windows which are centered at zeros by indexing into the 4D array. This forces a copy. But assuming number of zeros is a relatively smaller number than the total number of elements in input array, this should be okay.

对于每个选定的窗口,请使用np.bincount进行计数,以适当的偏移量对每个窗口进行偏移.因此,使用bincount并获得不包括零的最大计数.用于最大计数的argmax应该是我们的家伙!

For each of those selected windows, offset each window with a proper offset with the idea of using np.bincount to perform counting. Thus, use bincount and get the max count excluding the zeros. The argmax for the max count should be our guy!

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

Here's the implementation covering those steps -

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

样品运行-

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).

As seen, we are not solving for the boundary cases. If needed to do, use a zero-padded array as the input array, something like this : np.pad(a, (k//2,k//2), 'constant'), with k as the kernel size (=3 for the sample).

这篇关于Numpy过滤器可平滑零区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆