这是一个相当简单的方法:
- 加载图像并丢弃多余的 alpha 通道
- 骨架化
- 过滤器寻找具有中心像素集和其他像素集的 3x3 邻域
#!/usr/bin/env python3
import numpy as np
from PIL import Image
from scipy.ndimage import generic_filter
from skimage.morphology import medial_axis
# Line ends filter
def lineEnds(P):
"""Central pixel and just one other must be set to be a line end"""
return 255 * ((P[4]==255) and np.sum(P)==510)
# Open image and make into Numpy array
im = Image.open('lines.png').convert('L')
im = np.array(im)
# Skeletonize
skel = (medial_axis(im)*255).astype(np.uint8)
# Find line ends
result = generic_filter(skel, lineEnds, (3, 3))
# Save result
Image.fromarray(result).save('result.png')
请注意,您可以花费更少的精力获得完全相同的结果:图像魔术师从命令行这样:
convert lines.png -alpha off -morphology HMT LineEnds result.png
或者,如果您希望它们作为数字而不是图像:
convert result.png txt: | grep "gray(255)"
样本输出
134,78: (65535) #FFFFFF gray(255) <--- line end at coordinates 134,78
106,106: (65535) #FFFFFF gray(255) <--- line end at coordinates 106,106
116,139: (65535) #FFFFFF gray(255) <--- line end at coordinates 116,139
196,140: (65535) #FFFFFF gray(255) <--- line end at coordinates 196,140
另一种方法是使用scipy.ndimage.morphology.binary_hit_or_miss https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.binary_hit_or_miss.html并设置你的"Hits"正如下图中的白色像素和你的"Misses"作为黑色像素:
该图来自 Anthony Thyssen 的优秀资料here https://www.imagemagick.org/Usage/morphology/#lineends.
与上述类似,您同样可以使用"Hits" and "Misses"上面的内核OpenCV如上所述here https://docs.opencv.org/trunk/db/d06/tutorial_hitOrMiss.html:
morphologyEx(input_image, output_image, MORPH_HITMISS, kernel);
我怀疑这将是最快的方法。
Keywords:Python,图像,图像处理,线端,线端,形态学,Hit or Miss,HMT,ImageMagick,过滤器。