如何判断LSD输出线段的水平/垂直属性并统计两类线段数量
基于LSD输出的水平、垂直线段判断与统计方案
核心判断逻辑
通过计算线段的夹角区分水平/垂直属性,可自定义角度容差兼容存在轻微倾斜的业务场景:
- 水平线段:线段与水平方向夹角小于设定的容差值
- 垂直线段:线段与垂直方向夹角小于设定的容差值
- 可额外增加最小长度过滤规则,剔除噪点产生的无效短线段
修改后可直接运行的代码
import cv2 import math # 自定义线段长度计算函数,如项目中已有可省略 def line_length(x1, y1, x2, y2): return math.hypot(x2 - x1, y2 - y1) # 可调业务参数 ANGLE_TOLERANCE = 5 # 角度容差,单位:度,兼容轻微倾斜的线段 MIN_LENGTH = 10 # 最小有效线段长度,过滤细碎噪点 # 初始化计数器 horizontal_count = 0 vertical_count = 0 # 原有检测逻辑 img = cv2.imread("test/images.jpg") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) thresh = cv2.threshold(gray, 100, 200, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] lsd = cv2.createLineSegmentDetector(0) linesL = lsd.detect(gray)[0] for line in linesL: x1, y1, x2, y2, width = map(int, line[0]) length = line_length(x1, y1, x2, y2) # 跳过过短的无效线段 if length < MIN_LENGTH: continue # 计算线段与水平方向夹角(取0-90度范围内的绝对值) dx = abs(x2 - x1) dy = abs(y2 - y1) angle = math.degrees(math.atan2(dy, dx)) # 判断属性并计数 if angle <= ANGLE_TOLERANCE: horizontal_count += 1 # 可选:给水平线段标注特殊颜色,比如红色 cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 1) elif angle >= 90 - ANGLE_TOLERANCE: vertical_count += 1 # 可选:给垂直线段标注特殊颜色,比如绿色 cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 1) else: # 斜线段可按需保留或跳过 cv2.line(img, (x1, y1), (x2, y2), (0, 0, 0), 1) # 打印统计结果 print(f"水平线段数量:{horizontal_count}") print(f"垂直线段数量:{vertical_count}") cv2.imshow("FLD", img) cv2.waitKey(0) cv2.destroyAllWindows()
参数调整说明
- 角度容差可根据实际场景的线段倾斜情况调整,一般设置在3~10度区间即可
- 最小长度根据图片分辨率和目标线段长度调整,避免噪点被误统计
- 不需要保留斜线段的话,直接删除else分支的绘制逻辑即可

内容的提问来源于stack exchange,提问作者Govind S Kåtýurä
相关产品推荐
相关产品推荐

