【问题标题】:How can I keep the patch which contain all the elements 1如何保留包含所有元素的补丁 1
【发布时间】:2015-04-15 11:37:03
【问题描述】:
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 x 2 个补丁。现在我想保留这些补丁,如果它的所有元素都是 1,否则将所有元素转换为 0。
  • "否则将所有元素转换为 1。"你的意思是0,对吧?否则你最终会得到一个满是 1 的数组。
  • @OliverW。我的意思是一个子数组或补丁的所有元素,就像在数组补丁中一样。
  • 不,我不知道。到目前为止,我已经看到对您的问题进行了大约 5 次编辑,对于所有这些,我想知道您是如何从该数据集中获得输出的。我建议您根据当前数组 data 再次尝试创建(手动)您想要的数组并将其添加到您的帖子中。

标签: numpy scipy scikit-learn


【解决方案1】:

这是另一种方法,使用来自scipy.ndimageminimum_filtermaximum_filter。 (问题中的描述仍然太模糊 - 无论如何对我来说 - 所以这是基于@OliverW.'s answer中显示的结果。)

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

【讨论】:

  • 谢谢,点赞!我可以知道为什么应该使用 origin=(-1,-1) 吗?
【解决方案2】:

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

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

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

为了完整起见,矩阵的这种交错网格形式也可以通过 correlationnp.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

虽然在边界处发生的事情与以前的方法不同。

【讨论】:

  • @musk 不确定您现在想要什么,您链接的那些问题已经得到解答。他们有什么不清楚的地方?如果您觉得这些问题没有得到满意的回答,也许您可​​以考虑提出一个新问题,并提供输入数据和所需输出数据的良好示例?
  • @musk,我已经编辑了我的答案,也许这最后一个选择正是你的意思?
  • 感谢您使其更易于理解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-14
  • 2012-04-03
  • 1970-01-01
相关资源
最近更新 更多