使用OpenCV实现连通线检测时遇断线与误合并问题如何解决
方案调整说明
你当前的Canny+Hough组合对细弱连通线的适配性较差,可按以下逻辑修改实现需求:
1 替换预处理逻辑,保留线条连通性
先通过二值化+骨架提取把所有粗细不均的线条转换为单像素宽的连通骨架,从根源避免细线段被过滤丢失:
import cv2 import numpy as np # 输入图像预处理 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 自适应阈值二值化,保留细弱线条像素 binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # Zhang-Suen骨架提取,生成单像素连通骨架 size = np.size(binary) skel = np.zeros(binary.shape, np.uint8) element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) done = False while not done: eroded = cv2.erode(binary, element) temp = cv2.dilate(eroded, element) temp = cv2.subtract(binary, temp) skel = cv2.bitwise_or(skel, temp) binary = eroded.copy() zeros = size - cv2.countNonZero(binary) if zeros == size: done = True
2 两种可选输出方案
方案A:调整Hough参数适配骨架
降低检测阈值、放大线间隙允许值,配合小内核形态学运算补间隙,不会导致相邻线条粘连:
lines = cv2.HoughLinesP(skel, rho=1, theta=np.pi / 180, threshold=12, lines=np.array([]), minLineLength=2, maxLineGap=6) hough_img = np.zeros_like(skel) for line in lines: x1,y1,x2,y2 = line[0] cv2.line(hough_img, (x1,y1), (x2,y2), 255, 1) # 小内核闭运算补线间隙,不会触发相邻线粘连 kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (2,2)) result = cv2.morphologyEx(hough_img, cv2.MORPH_CLOSE, kernel, iterations=1) # 统一加粗到目标宽度 result = cv2.dilate(result, np.ones((2,2), np.uint8), iterations=1)
方案B:直接骨架加粗(更适配你的需求)
不需要Hough变换,直接对保留了100%原连通性的骨架做均匀加粗,完全不会出现断线或非预期重叠问题:
# 直接将单像素骨架均匀加粗到2像素宽度 result = cv2.dilate(skel, np.ones((2,2), np.uint8), iterations=1)
内容的提问来源于stack exchange,提问作者ahbutfore
相关产品推荐
相关产品推荐

