如何在numpy数组中消除模式?

19

抱歉,标题有点奇怪,我无法想到一个合适的措辞。

假设我有一个数组:

arr = [[0 1 1 1 1 1 1 1 0],
       [0 0 1 1 1 1 1 0 0],
       [0 0 0 1 1 1 0 0 0],
       [0 0 0 0 1 0 0 0 0],
       [0 0 0 0 0 0 0 0 0]]

我希望能够除去与 0 相接触的 1,使其输出如下:

arr = [[0 0 1 1 1 1 1 0 0],
       [0 0 0 1 1 1 0 0 0],
       [0 0 0 0 1 0 0 0 0],
       [0 0 0 0 0 0 0 0 0],
       [0 0 0 0 0 0 0 0 0]] .

我已经尝试了一些方法,例如使用np.roll,但它似乎效率低下(而且有边缘影响)。有没有一种简洁的方法可以做到这一点?


嗯,真的没有合适的标题。点赞让它得到应有的关注 :-) - jjm
你能否遍历数组,检查相邻的0和1,并将它们设置为0? - KSFT
在计算机视觉中,我看到这被称为缩小,我想。肯定有比溶解更好的术语。 - Frames Catherine White
2个回答

22

形态学腐蚀 可以在这里使用。

形态学腐蚀将位于(i, j)处的像素设置为以(i, j)为中心的邻域内所有像素的最小值。来源

data
Out[39]: 
array([[0, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 0, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0]])

structure
Out[40]: 
array([[0, 1, 0],
       [1, 1, 1],
       [0, 1, 0]])

eroded = binary_erosion(data, structure, border_value=1).astype(int)

eroded
Out[42]: 
array([[0, 0, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0]])

@OliverW. 感谢您指出错误。在核心中将中心设置为1是否可以修复它? - M4rtini
1
我认为是的。回想起来,这是“正确”的答案(正确的意思是有人写了它并设法将其纳入主流库),而我不知道它。我仍然对我所想出的东西感到满意,并且运行良好,但你也得到了我的支持 :-) - Oliver W.

12

考虑使用十字形的核进行卷积。

import numpy as np
from scipy.signal import convolve2d
kernel = np.array([[0,1,0], [1,1,1], [0,1,0]])
mask = convolve2d(arr, kernel, boundary='symm', mode='same')
arr[mask!=5] = 0

这种方法对于所有输入都能正确工作:

In [143]: D = np.random.random_integers(0,1, (5,5))

In [144]: D2 = D.copy()

In [145]: mask = convolve2d(D, kernel, boundary='symm', mode='same')

In [146]: D2[mask!=5] = 0

In [147]: binary_erosion(D, kernel2, border_value=1).astype(int)
Out[147]: 
array([[0, 1, 0, 1, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])

In [148]: D2
Out[148]: 
array([[0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])

In [149]: D
Out[149]: 
array([[1, 0, 1, 1, 1],
       [0, 1, 0, 1, 0],
       [0, 1, 0, 1, 0],
       [0, 0, 1, 1, 0],
       [1, 0, 1, 0, 0]])
In [150]: kernel
Out[150]: 
array([[0, 1, 0],
       [1, 1, 1],
       [0, 1, 0]])

In [151]: kernel2
Out[151]: 
array([[0, 1, 0],
       [1, 0, 1],
       [0, 1, 0]])

观察角落,看到不同之处。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接