你想要面具的所有 True 元素的点,还是只想要一个骨架?如果是前者..
import skimage as ski
from skimage import io
import numpy as np
mask = ski.io.imread('./mask.png')[:,:,0]/255
mask = mask.astype('bool')
s0,s1 = mask.shape # dimensions of mask
a0,a1 = np.arange(s0),np.arange(s1) # make two 1d coordinate arrays
coords = np.array(np.meshgrid(a0,a1)).T # cartesian product into a coordinate matrix
coords = coords[mask] # mask out the points of interest
如果是后者,您可以使用类似的方式快速获取蒙版中对象的起点和终点(从左到右)
start_mat = np.stack((np.roll(mask,1,axis=1),mask),-1)
start_mask = np.fromiter(map(lambda p: np.alltrue(p==np.array([False,True])),start_mat[mask]),dtype=bool)
starts = coords[start_mask]
end_mat = np.stack((np.roll(mask,-1,axis=1),mask),-1)
end_mask = np.fromiter(map(lambda p: np.alltrue(p==np.array([False,True])),end_mat[mask]),dtype=bool)
ends = coords[end_mask]
这将为您提供对象的粗略轮廓。轮廓点在图形斜率为 0 的任何地方都将丢失。您可能必须为这些区域考虑垂直差异方案。同样的想法也适用于np.roll(...,axis=0)。您可以将滚动行的唯一点与滚动列的点连接起来,以获得完整的轮廓。
平均正确的对来得到骨架并不容易。
这是一个最终的大纲。你绝对可以让这个速度超过 0.4 秒: