让A
是代表掩码的numpy数组。我想提取与该蒙版相对应的边界,即使除边界外的所有内容均为零。
例如:
In [22]: A
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)
所需的输出是:
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)
此外,A
中的掩码也可能是非线性的。
所以,我的问题是,获得此边界的最有效方法是什么?
编辑1: 我所说的非线性是什么? 考虑其中有一个人的图像。此人对应的遮罩是非线性的。
答案 0 :(得分:4)
获得轮廓的一个技巧是使用带有3x3个数组的二进制膨胀作为否定掩码上的内核,并在其和输入之间寻找通用的。对于4-connected
边界,它将是全1的数组,对于8-connected
,它将是一个加号的1的数组-
from scipy.ndimage.morphology import binary_dilation
k = np.ones((3,3),dtype=int) # for 4-connected
k = np.zeros((3,3),dtype=int); k[1] = 1; k[:,1] = 1 # for 8-connected
out = binary_dilation(a==0, k) & a
样品运行-
输入数组:
In [384]: a
Out[384]:
array([[0, 0, 0, 0, 0, 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, 0, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
In [385]: from scipy.ndimage.morphology import binary_dilation
解决4个连接:
In [386]: k = np.ones((3,3),dtype=int)
In [390]: binary_dilation(a==0, k) & a
Out[390]:
array([[0, 0, 0, 0, 0, 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, 0, 1, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
解决8联结问题:
In [411]: k = np.zeros((3,3),dtype=int); k[1] = 1; k[:,1] = 1
In [412]: k
Out[412]:
array([[0, 1, 0],
[1, 1, 1],
[0, 1, 0]])
In [413]: binary_dilation(a==0, k) & a
Out[413]:
array([[0, 0, 0, 0, 0, 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, 0, 1, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
我们也可以使用binary_erosion
:
from scipy.ndimage.morphology import binary_erosion
out = a-binary_erosion(a,k)