找到立即完全包围 0s 区域的 1s 像素
Find the 1s pixels that immediately and completely enclose an area of 0s
从一个由 0 和 1 组成的二维数组开始,我需要确定哪些 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]]
- 用 1px 的零边框填充矩阵
- 填充矩阵并只保留中心 0 的孤岛
- 用 dilate 扩展那些岛(在反转它们之后)以扩展轮廓 -> B
- 按位与 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]]
从一个由 0 和 1 组成的二维数组开始,我需要确定哪些 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]]
- 用 1px 的零边框填充矩阵
- 填充矩阵并只保留中心 0 的孤岛
- 用 dilate 扩展那些岛(在反转它们之后)以扩展轮廓 -> B
- 按位与 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]]