我试图沿阵列中由1表示的形状的边界获得点的ndarray。我尝试使用scipy.spatial.ConvexHull
,但凸包形成的边界没有考虑到形状中间的洞(我也需要在洞周围的边界)。这是我试图从数组创建的那种边界。我怎样才能解释形状上的洞?
import numpy as np
from skimage.measure import label, regionprops
import matplotlib.pyplot as plt
from scipy.spatial import Voronoi, voronoi_plot_2d, ConvexHull
arr = np.array([
[1,1,1,1,1,1,0,0,0,1,0],
[1,1,1,1,1,1,0,0,0,1,0],
[1,1,0,0,0,1,1,1,1,1,0],
[1,1,0,1,1,1,1,1,0,0,0],
[1,1,1,1,1,1,0,0,0,0,0],
[0,1,1,1,1,0,0,0,0,0,0],])
coords = []
for x in range(arr.shape[0]):
for y in range(arr.shape[1]):
if arr[x][y] > 0:
tile = [x,y]
coords.append(tile)
# print("tile", tile)
coords = np.array(coords)
# print(coords)
hull = ConvexHull(coords)
plt.plot(coords[:,0], coords[:,1], 'o')
for simplex in hull.simplices:
plt.plot(coords[simplex, 0], coords[simplex, 1], 'k-')
plt.plot(coords[hull.vertices,0], coords[hull.vertices,1], 'r--', lw=2)
plt.plot(coords[hull.vertices[0],0], coords[hull.vertices[0],1], 'ro')
这有点hacky,但如果你用正确的内核(v4或v8)卷积零,你得到外部部分加上边界,所以如果你用内部部分进行and
操作,你只能获得边界。这是一个例子:
import numpy as np
from scipy.signal import convolve2d
arr = np.array([
[1,1,1,1,1,1,0,0,0,1,0],
[1,1,1,1,1,1,0,0,0,1,0],
[1,1,0,0,0,1,1,1,1,1,0],
[1,1,0,1,1,1,1,1,0,0,0],
[1,1,1,1,1,1,0,0,0,0,0],
[0,1,1,1,1,0,0,0,0,0,0],
])
# v4 example,
kernel = np.array([
[0,1,0],
[1,0,1],
[0,1,0],
])
# you have to zero pad first in order to get the edges
padded = np.pad(arr, ((1, 1), (1, 1)), 'constant', constant_values=0)
# the `astype(bool)` is for normalization
# the `and` operation in this case is the elementwise product
frontier = convolve2d(1-padded, kernel, mode='valid').astype(bool) * arr