我会用分水岭式算法来解决这个问题。我在下面描述了方法,但是它是为处理单(多段)线而创建的,因此您需要将图像拆分为单独的线的图像。
玩具示例:
0000000
0111110
0111110
0110000
0110000
0000000
其中0 表示黑色,1 表示白色。
现在我实施的解决方案:
import numpy as np
img = np.array([[0,0,0,0,0,0,0],
[0,255,255,255,255,255,0],
[0,255,255,255,255,255,0],
[0,255,255,0,0,0,0],
[0,0,0,0,0,0,0]],dtype='uint8')
def flood(arr,value):
flooded = arr.copy()
for y in range(1,arr.shape[0]-1):
for x in range(1,arr.shape[1]-1):
if arr[y][x]==255:
if arr[y-1][x]==value:
flooded[y][x] = value
elif arr[y+1][x]==value:
flooded[y][x] = value
elif arr[y][x-1]==value:
flooded[y][x] = value
elif arr[y][x+1]==value:
flooded[y][x] = value
return flooded
ends = np.zeros(img.shape,dtype='uint64')
for y in range(1,img.shape[0]-1):
for x in range(1,img.shape[1]-1):
if img[y][x]==255:
temp = img.copy()
temp[y][x] = 127
count = 0
while 255 in temp:
temp = flood(temp,127)
count += 1
ends[y][x] = count
print(ends)
输出:
[[0 0 0 0 0 0 0]
[0 5 4 4 5 6 0]
[0 5 4 3 4 5 0]
[0 6 5 0 0 0 0]
[0 0 0 0 0 0 0]]
现在结束由上述数组中最大值的位置表示(在这种情况下为6)。
说明:我正在检查所有可能的白色像素。对于每个这样的像素,我都在“泛滥”图像 - 我放置特殊值(127 - 不同于 0 并且不同于 255)然后传播它 - 在每一步中,所有 255 都是邻居(在 von诺伊曼的特殊价值感)本身就成为特殊价值。我正在计算删除所有255 所需的步骤。因为如果你从末端开始(恒速)泛滥,它会比你在任何其他位置有源需要更多的时间,那么泛滥的最大时间是你的生产线的末端。
我必须承认我没有对此进行深入测试,所以我不能保证在特殊情况下正确工作,例如在自相交线的情况下。我也知道我的解决方案的粗糙度,特别是在检测邻居和传播特殊值方面,所以请随时改进它。我假设所有边框像素都是黑色的(没有线条触及图像的“框架”)。