检测图像中线条的起点和终点(numpy 数组)

2024-03-09

我有一个像下面这样的图像:

我想要的是获取每个线段的起点和终点的坐标。实际上我的想法是考虑这样一个事实:每个极值点应该只有一个属于其邻域中的线段的点,而所有其他点应该至少有 2 个。不幸的是,该线的厚度不等于一个像素,因此这一推理不成立。


这是一个相当简单的方法:

  • 加载图像并丢弃多余的 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,过滤器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检测图像中线条的起点和终点(numpy 数组) 的相关文章

随机推荐