python - 动态改变 scipys ndimage 过滤器中的过滤器大小

标签 python numpy image-processing filtering moving-average

已关注 How exactly does the “reflect” mode for scipys ndimage filters work?Numpy Two-Dimensional Moving Average ,我有一个二维数组:

a
=> 
np.array([[ 0.,   1.,   2.,   3.,   4.],
       [  5.,   6.,   7.,   8.,   9.],
       [ 10.,  11.,  12.,  13.,  14.],
       [ 15.,  16.,  17.,  18.,  19.],
       [ 20.,  21.,  22.,  23.,  24.]])

当我使用 mode=constant3x3 过滤器大小时:

uniform_filter(a, size=3, mode='constant')

结果是:

=> 
array([[  1.33333333,   2.33333333,   3.        ,   3.66666667,          2.66666667],
       [  3.66666667,   6.        ,   7.        ,   8.        ,          5.66666667],
       [  7.        ,  11.        ,  12.        ,  13.        ,          9.        ],
       [ 10.33333333,  16.        ,  17.        ,  18.        ,         12.33333333],
       [  8.        ,  12.33333333,  13.        ,  13.66666667,          9.33333333]])

我了解这个过滤器的内部工作原理,因为我在上面发布的链接中已经对此进行了很好的解释。

我的问题是,对于数组中的每个位置,是否可以将其总和除以值大于零的元素总数?

例如,在我的数组中位置 [0,0] 的元素为 0 的元素之和 (0, 0, 0, 0, 0, 1 , 0, 5, 6) 将除以 3 (仅位置 [0,1] = 1、[1,0] = 5 和 [1,1] = 6 的值大于零)而不是 9。在数组的位置 [0,1] 中,我将除以 5。在位置 [0,2],我除以 6,在位置 [1,2],我除以 9

在这种情况下,我的答案应该是;

=> 
array([[ 4.0 ,  4.2 ,  4.5 ,  5.5 ,  6.0  ],
       [ 6.60,  6.75,  7.0 ,  8.0 ,  8.5  ],
       [ 10.5,  11. ,  12. ,  13. ,  13.5 ],
       [ 15.5,  16. ,  17. ,  18. ,  18.5 ],
       [ 18.0,  18.5,  19.5,  20.5,  21.0 ]])

最佳答案

这是一种方法 -

from scipy.ndimage.filters import uniform_filter
from scipy.signal import convolve2d

size = 3       
kernel = np.ones((size,size),dtype=int)  
nonzero_count = convolve2d(a!=0, kernel,'same')
windowed_sum = uniform_filter(a, size=size, mode='constant')*size**2
out = windowed_sum/nonzero_count

步骤:

  • 沿着输入数组的行和列获取形状为:(size,size) 的滑动窗口中的非零数。 为此,我们可以使用带有所有1内核且形状与内核相同的2D卷积。或者,我们也可以使用 uniform_filter 获得非零计数: uniform_filter((a!=0).astype(float), size=size, mode='constant')*size**2 .

  • 通过重新使用 uniform_filter 输出的平均值并按 size**2 缩放来获取滑动总和。或者,我们可以再次使用 2D 卷积,并使用 convolve2d(a, kernel,'same')

  • 最后,将这些总和除以非零计数,这就是所需的输出。

样本输入、中间输出和最终输出 -

In [51]: a
Out[51]: 
array([[  0.,   1.,   2.,   3.,   4.],
       [  5.,   6.,   7.,   8.,   9.],
       [ 10.,  11.,  12.,  13.,  14.],
       [ 15.,  16.,  17.,  18.,  19.],
       [ 20.,  21.,  22.,  23.,  24.]])

In [53]: nonzero_count
Out[53]: 
array([[3, 5, 6, 6, 4],
       [5, 8, 9, 9, 6],
       [6, 9, 9, 9, 6],
       [6, 9, 9, 9, 6],
       [4, 6, 6, 6, 4]])

In [54]: windowed_sum
Out[54]: 
array([[  12.,   21.,   27.,   33.,   24.],
       [  33.,   54.,   63.,   72.,   51.],
       [  63.,   99.,  108.,  117.,   81.],
       [  93.,  144.,  153.,  162.,  111.],
       [  72.,  111.,  117.,  123.,   84.]])

In [55]: out
Out[55]: 
array([[  4.  ,   4.2 ,   4.5 ,   5.5 ,   6.  ],
       [  6.6 ,   6.75,   7.  ,   8.  ,   8.5 ],
       [ 10.5 ,  11.  ,  12.  ,  13.  ,  13.5 ],
       [ 15.5 ,  16.  ,  17.  ,  18.  ,  18.5 ],
       [ 18.  ,  18.5 ,  19.5 ,  20.5 ,  21.  ]])

关于python - 动态改变 scipys ndimage 过滤器中的过滤器大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45277152/

相关文章:

python - oct2py 没有看到 OCTAVE_EXECUTABLE 环境变量 (Windows)

python - 实现 numpy.sin(x)/x 的最佳方法,其中 x 可能包含 0

java - 使用Java优化内存中的JPG图像

python - 在 connexion/flask 应用程序中,如何伪造端点正文中带有参数的发布请求?

python - 将 psycopg2 DictRow 查询转换为 Pandas 数据框

python - 按另一个矩阵排序在一种情况下有效,但在另一种情况下失败

python - 如何将tensorflow placerholder变量转换为numpy数组?

image - 连接二值图像中的不相交边

javascript - 使用 JavaScript 在 Canvas 中操作图像亮度

python - 如何正确使用 Python-Twitter 库中的 GetStreamFilter?