You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python提取二值图像已有轮廓的中心线

二值图像轮廓中心线提取Python实现

依赖安装

首先安装所需第三方库:
pip install opencv-python numpy scikit-image

实现方法

方法一:骨架化算法(推荐用于边缘连续的封闭/半封闭轮廓)

原理为逐层剥离前景区域的边缘像素,最终保留单像素宽度的中轴作为中心线,实现逻辑简单,适配大部分场景:

import cv2
import numpy as np
from skimage.morphology import skeletonize

# 读取二值图像,参数0表示以灰度模式读取
binary = cv2.imread("输入二值图路径.png", 0)
# 强制二值化,确保只有0和255两个像素值
_, binary = cv2.threshold(binary, 127, 255, cv2.THRESH_BINARY)
# 转为0-1值域适配骨架化接口
binary_norm = binary // 255
# 提取中心线
skeleton = skeletonize(binary_norm)
# 转回0-255值域用于保存
result = (skeleton * 255).astype(np.uint8)

cv2.imwrite("中心线结果.png", result)

方法二:距离变换+峰值筛选(推荐用于轮廓粗细不均的场景)

通过计算每个前景像素到最近背景像素的距离,距离峰值区域即为中心线位置,可灵活调整阈值适配不同粗细的轮廓:

import cv2
import numpy as np
from skimage.morphology import skeletonize

binary = cv2.imread("输入二值图路径.png", 0)
_, binary = cv2.threshold(binary, 127, 255, cv2.THRESH_BINARY)

# 计算距离变换,DIST_L2表示用欧氏距离
dist = cv2.distanceTransform(binary, cv2.DIST_L2, 5)
# 归一化距离结果到0-1区间
cv2.normalize(dist, dist, 0, 1, cv2.NORM_MINMAX)
# 筛选距离大于最大距离20%的区域作为中心线候选,阈值可自行调整
_, center_candidate = cv2.threshold(dist, 0.2 * dist.max(), 255, cv2.THRESH_BINARY)
center_candidate = center_candidate.astype(np.uint8)
# 细化得到单像素中心线
result = (skeletonize(center_candidate//255) * 255).astype(np.uint8)

cv2.imwrite("中心线结果.png", result)

注意事项

  • 输入二值图需保证轮廓区域为白色(255),背景为黑色(0),如果颜色相反可调用cv2.bitwise_not(binary)翻转后再处理
  • 若已经提前提取到轮廓坐标,可先创建空白画布将轮廓填充为白色前景,再调用上述方法,结果更稳定
  • 阈值参数可根据实际图像的轮廓粗细调整,轮廓越粗阈值可适当调高,避免中心线出现多余分支

内容的提问来源于stack exchange,提问作者Qimin Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 23:27:01