如何保留包含所有元素的补丁1

时间:2015-02-14 13:59:53

标签: numpy scipy scikit-learn

from sklearn.feature_extraction.image import extract_patches
import numpy as np

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

patches = extract_patches(data, patch_shape=(2, 2))

如何保留包含所有元素1的补丁?

2 个答案:

答案 0 :(得分:3)

从更正到您的帖子,我相信您可能正在寻找一种方法来检测形状(2,2)的子矩阵的全部位置。不满足该条件的任何地方都应为零,但应优先考虑满足该条件的子矩阵,因为子矩阵可以重叠

在这种情况下,您很可能对该矩阵的交错网格感兴趣,该矩阵在每个2x2子矩阵的中心有一个矩阵,只要该子矩阵的4个元素都是1:

>>> import numpy as np
>>> from sklearn.feature_extraction.image import extract_patches # similar to numpy's stride_tricks
>>> 
>>> data = np.array([[1, 1, 0, 0, 0, 0, 1, 0],
...                  [1, 1, 1, 0, 0, 1, 1, 0],
...                  [1, 1, 0, 1, 1, 0, 0, 0],
...                  [0, 0, 0, 1, 1, 0, 0, 0],
...                  [0, 0, 0, 1, 1, 0, 0, 1],
...                  [1, 1, 0, 0, 0, 0, 1, 0],
...                  [1, 1, 0, 0, 0, 0, 0, 0]])
>>> 
>>> # to take boundary effects into account, append ones to the right and bottom
... # modify this to `np.zeros` if boundaries are to be set to zero
... data2 = np.ones((data.shape[0]+1, data.shape[1]+1))  
>>> data2[:-1,:-1] = data
>>> vert = np.logical_and(data2[:-1,:], data2[1:,])
>>> dual = np.logical_and(vert[:,:-1], vert[:,1:]) # dual is now the "dual" graph/staggered grid of the data2 array
>>> patches = extract_patches(data2, patch_shape=(2, 2))  # could've used numpy stride_tricks too
>>> patches[dual==0] = 0
>>> patches[dual] = 1  # Give precedence to the dual positives
>>> data2[:-1, :-1].astype(np.uint8)
array([[1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0]], dtype=uint8)

为了完整性,矩阵的这种交错网格形式也可以通过关联np.ones((2,2))内核轻松获得。然而,这在计算上更加沉重,因为必须完成更多的工作(乘法和求和)而不是简单的位操作。上述方法在速度方面优于基于相关的方法。 上面交错的网格dual也可以通过以下方式生成:

patches = extract_patches(data, patch_shape=(2, 2))
dual = patches.all(axis=-1).all(axis=-1)

您将获得最终结果:

dual = patches.all(axis=-1).all(axis=-1)
patches[dual==False] = 0
patches[dual] = 1

它与前一种方法的区别在于边界处发生的情况。

答案 1 :(得分:1)

这是另一种方法,使用minimum_filter中的maximum_filterscipy.ndimage。 (问题中的描述仍然过于模糊 - 无论如何 - 对于我来说 - 所以这是基于@OliverW中的结果。答案。)

In [138]: from scipy.ndimage import minimum_filter, maximum_filter

In [139]: data
Out[139]: 
array([[1, 1, 0, 0, 0, 0, 1, 0],
       [1, 1, 1, 0, 0, 1, 1, 0],
       [1, 1, 0, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 0, 0, 1],
       [1, 1, 0, 0, 0, 0, 1, 0],
       [1, 1, 0, 0, 0, 0, 0, 0]])

In [140]: m = minimum_filter(data, size=(2,2), mode='constant', origin=(-1,-1))

In [141]: result = maximum_filter(m, size=(2,2), mode='constant')

In [142]: result
Out[142]: 
array([[1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0]])