4

从 0 和 1 的 2d 数组开始,我需要确定哪些 1 形成一个联合围栏,完全包围一个或多个相邻的 0。如果它们在侧面或对角线上接触,则这些 0 被认为是相邻的。栅栏也必须存在于相邻的对角线上。

这是二维数组,我想要的是表示围栏的 1,然后其他所有内容都应该为零。这是一个简单的案例,实际上数组是一个 png 图像,我想要其中可能存在的所有栅栏。

ndimage 是需要的模块吗?请有任何建议。

array=
[[1,1,1,1,1,1],  
 [1,1,0,0,1,1],  
 [1,1,0,1,1,1],  
 [1,1,1,1,1,1],  
 [0,0,1,1,0,0]] 

answer=
[[0,1,1,1,1,0],  
 [0,1,0,0,1,0],  
 [0,1,0,1,1,0],  
 [0,1,1,1,0,0],  
 [0,0,0,0,0,0]] 

4

1 回答 1

1

遵循JeromeMark建议的方法:

  1. 用 1px 的零边框填充矩阵
  2. 淹没矩阵并仅保留中心 0 的岛屿
  3. 用 dilate 扩展这些岛(在反转它们之后)以扩展轮廓 - > B
  4. 按位 AND 它与 A 只取回轮廓并删除初始填充
from collections import deque as queue
from scipy import ndimage
import numpy as np
from skimage.segmentation import flood_fill

A = np.array([[1,1,1,1,1,1],  
              [1,1,0,0,1,1],  
              [1,1,0,1,1,1],  
              [1,1,1,1,1,1],  
              [0,0,1,1,0,0]])
A = np.pad(A, pad_width=1, mode='constant', constant_values=0)
print("A after padding")
print(A)

A = flood_fill(A, (0, 0), 1)
print("A after flooding")
print(A)

# you can also use cv2.dilate if you want to avoid ndimage
struct2 = ndimage.generate_binary_structure(2, 2)
B = ndimage.binary_dilation(1-A, structure=struct2).astype(A.dtype)
print("B")
print(B)

print("result")
res = B & A
print(res[1:-1, 1:-1]) # remove padding

输出:

A after padding
[[0 0 0 0 0 0 0 0]
 [0 1 1 1 1 1 1 0]
 [0 1 1 0 0 1 1 0]
 [0 1 1 0 1 1 1 0]
 [0 1 1 1 1 1 1 0]
 [0 0 0 1 1 0 0 0]
 [0 0 0 0 0 0 0 0]]
A after BFS
[[1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1]
 [1 1 1 0 0 1 1 1]
 [1 1 1 0 1 1 1 1]
 [1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1]]
B
[[0 0 0 0 0 0 0 0]
 [0 0 1 1 1 1 0 0]
 [0 0 1 1 1 1 0 0]
 [0 0 1 1 1 1 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]]
result
[[0 1 1 1 1 0]
 [0 1 0 0 1 0]
 [0 1 0 1 1 0]
 [0 1 1 1 0 0]
 [0 0 0 0 0 0]]
于 2022-01-14T00:48:27.883 回答