基于OpenCV实现带像素容差的线条端点垂直连接需求
线条端点垂直连接解决方案
需求说明
- 输入:带线条掩码的灰度PNG图像
- 操作:仅连接端点x坐标相差≤5像素的线条,连接方式为垂直直线
- 规则:仅连接细线条(厚度为1),不连接粗线条(厚度≥2)
示例线条生成代码
def lines(): img = np.zeros((256,256,1), dtype=np.uint8) img = cv2.line(img, (50,50), (128 ,128), color=(255), thickness=1) img = cv2.line(img, (128 ,200), (240 ,250), color=(255), thickness=1) img = cv2.line(img, (96 ,54), (150,164), color=(255), thickness=2)
现有代码存在的问题
- 代码逻辑混乱,可读性差
- 仅支持点连接,无法处理线条图像
- 无容差机制,仅能匹配x坐标完全相同的端点
改进后的实现方案
核心步骤
- 提取线条端点:通过轮廓检测提取图像中线条的端点
- 筛选细线条:根据线条的厚度(外接矩形最小边判断)筛选出厚度为1的线条端点
- 匹配符合容差的端点:找出x坐标相差≤5像素的端点对
- 绘制垂直连接线:在匹配的端点对之间绘制垂直直线
完整代码实现
import cv2 import numpy as np def get_line_endpoints(img): # 提取图像轮廓 contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) endpoints = [] line_thicknesses = [] for cnt in contours: # 通过外接矩形最小边判断线条厚度 x, y, w, h = cv2.boundingRect(cnt) thickness = min(w, h) line_thicknesses.append(thickness) # 提取轮廓首尾点作为线条端点 if len(cnt) >= 2: pt1 = tuple(cnt[0][0]) pt2 = tuple(cnt[-1][0]) endpoints.append((pt1, pt2)) return endpoints, line_thicknesses def connect_lines_with_tolerance(img, tolerance=5): endpoints, thicknesses = get_line_endpoints(img) # 筛选仅保留细线条的端点 thin_line_endpoints = [ep for ep, thick in zip(endpoints, thicknesses) if thick == 1] # 整理所有细线条的端点 all_points = [] for ep_pair in thin_line_endpoints: all_points.extend(ep_pair) # 匹配符合x坐标容差的端点对 connected_pairs = [] for i in range(len(all_points)): x1, y1 = all_points[i] for j in range(i+1, len(all_points)): x2, y2 = all_points[j] if abs(x1 - x2) <= tolerance: # 取x坐标平均值作为垂直线的x位置 line_x = int((x1 + x2) / 2) y_min = min(y1, y2) y_max = max(y1, y2) connected_pairs.append(((line_x, y_min), (line_x, y_max))) # 绘制垂直连接线 result_img = img.copy() for start, end in connected_pairs: cv2.line(result_img, start, end, color=(177), thickness=1) return result_img # 测试示例 if __name__ == "__main__": img = lines() connected_img = connect_lines_with_tolerance(img) cv2.imshow("Original Lines", img) cv2.imshow("Connected Lines", connected_img) cv2.waitKey(0) cv2.destroyAllWindows()
代码说明
get_line_endpoints:提取所有线条的端点和厚度,通过外接矩形最小边判断线条粗细connect_lines_with_tolerance:筛选细线条端点,遍历端点对判断x坐标容差,绘制垂直连接线- 容差参数
tolerance可根据需求调整,默认设置为5像素
内容的提问来源于stack exchange,提问作者Bartłomiej Pałus
相关产品推荐
相关产品推荐

