【问题标题】:Extracting the elements matching the filter提取匹配过滤器的元素
【发布时间】:2015-02-15 10:43:48
【问题描述】:

我想过滤足迹 (3,3) 由 1 组成的索引。

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 , 1 , 1 , 1 , 0 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 0 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 1],
                 [1, 1 , 0 , 0 , 0 , 1 , 1 , 1],
                 [1, 1 , 0 , 0 , 0 , 1 , 1 , 1]])

预期答案如下,不需要的位置设置为0s:

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

【问题讨论】:

    标签: numpy scipy scikit-image


    【解决方案1】:

    这个答案是基于我几个小时前写的a very similar answer

    #from sklearn.feature_extraction.image import extract_patches  # similar to numpy's stride_tricks
    from numpy.lib.stride_tricks import as_strided
    
    data = np.array([[1, 1 , 0 , 0 , 0 , 0 , 1 , 0],
                     [1, 1 , 1 , 0 , 0 , 1 , 1 , 0],
                     [1, 1 , 1 , 1 , 1 , 0 , 0 , 0],
                     [0, 0 , 1 , 1 , 1 , 0 , 0 , 0],
                     [0, 0 , 1 , 1 , 1 , 1 , 0 , 1],
                     [1, 1 , 0 , 0 , 0 , 1 , 1 , 1],
                     [1, 1 , 0 , 0 , 0 , 1 , 1 , 1]])
    patches = as_strided(data, shape=(data.shape[0]-2,data.shape[1]-2, 3, 3), strides=data.strides*2)
    dual = patches.all(axis=-1).all(axis=-1)
    patches[dual==False] = 0
    patches[dual] = 1
    

    结果(data)如您所见。

    其工作方式如下: 函数extract_patches 在数组data 中生成视图,这意味着它不是实际数据的副本,而是使用步幅 生成一个看似不同的数组。在这种情况下,它将生成数组data 的所有可能的 3x3 子矩阵(可以重叠)。然后,通过编写patches.all(axis=-1).all(axis=-1),您首先检查子矩阵的行中的元素是否全部为 True(或在布尔意义上等价于 True,所以不是 0、空列表、空字典、空元组和其他一些特殊情况),从而折叠此数组的一个轴,然后使用第二个 .all(axis=-1) 检查列以查看它们是否全部为真。

    这一段的小例子,直观地阐明:

    >>> A = np.array([
    ... [1, 1, 0],        # -> along this row, not all elements are 1: so `all` along the last axis will return False
    ... [1, 1, 1],        # -> along this row, all elements are 1: so `all` along the last axis (axis=-1) will return True
    ... [1, 1, 1]])
    >>> A.all(axis=-1)
    array([False,  True,  True], dtype=bool)  # so it is done along the last axis, along the rows
    >>> A.all(axis=-1).all(axis=-1)
    False
    

    所以这个数组dual 现在对于每个充满 1 的 3x3 子矩阵都有一个“1”(实际上是真的)。但是,这些子矩阵是重叠的,因此您首先要将补丁全部设置为 0,只要这些 3x3 子矩阵中的任何一个不是全部(这是第一个代码块中的倒数第二行:patches[dual==False] = 0)和 然后您可以在每个最初包含所有子矩阵的 3x3 子矩阵中再次应用这些子矩阵。 替代方法是与 kernel = np.ones((3,3)) 相关联或考虑多个按位运算(如在另一个答案中),但是当数组的维度超过简单的 (2,2) 时,最后一种方法变得非常难以编写。

    【讨论】:

    • @simen,考虑到您引用的链接,我猜您也是用户“musk”(来自我链接的问题)。如果是这样,您可能想请一位 Stackoverflow 版主合并您的帐户。无论如何,您链接到的两个问题都被接受。如果他们没有做你想做的事,你应该更彻底地解释为什么答案没有做你想做的事。类似的情况:你能解释一下为什么我的回答没有完全按照你在原始帖子中的要求吗?
    • 我不再对使用 sklearn 解决我的问题感兴趣。我正在寻找解决它的方法,实现我上面分享的答案。
    • 链接已经链接到这个问题,我很熟悉你对用户 musk 的回答,因为那个问题也和我的问题有关。
    • @simen 在这两个问题中我都提到了使用 numpy 的步幅技巧。我已将答案更新为 only 使用 numpy 库。我希望你现在明白,sklearn 中的extract_patches 相当于 numpy 的 as_strided
    • 既然你的答案也产生了预期的答案,我已经接受了。,再见
    猜你喜欢
    • 2010-09-09
    • 1970-01-01
    • 2013-11-05
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    相关资源
    最近更新 更多