[Vision AI] 动态车道线边界提取与几何多边形 IoU 压线侵入判定算法 (#2)
· 阅读需 3 分钟

📌 核心要点 (Key Takeaways)
- 问题痛点:行车记录仪画面中普遍充斥着路面水渍反光、沥青修补裂缝、减速带以及高架桥阴影,极易引发车道线误检;简单的水平/垂直单点坐标判断,无法在车辆变道颠簸时精准界定车轮压线的物理临界点。
- 解决方案:设计基于消失点的梯形 ROI 感兴趣区域掩膜、双向斜率绝对值阈值过滤 ($|slope| > 0.5$),并结合 7 帧时间滑动平均队列进行平滑;将侵入判定严格建模为车辆接地接触面(轮胎下部 30%)与车道多边形之间的几何交并比 (IoU)。
- 落地成效:成功过滤了 95% 以上的路面噪点,并以亚帧级的时间精度精准捕获车辆碾压车道线的瞬间。
1. 动态车道线检测:Canny 边缘与概率霍夫变换 (HoughLinesP)
为了在低清行车记录仪画面中稳定提取车道线,我们精心调优了基于 OpenCV 的图像前处理流水线:
def detect_lanes(frame):
height, width = frame.shape[:2]
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blur, 50, 150)
# 构建基于视线消失点的梯形感兴趣区域 (ROI)
mask = np.zeros_like(edges)
roi_polygon = np.array([[
(int(width * 0.1), height),
(int(width * 0.45), int(height * 0.6)),
(int(width * 0.55), int(height * 0.6)),
(int(width * 0.9), height)
]], np.int32)
cv2.fillPoly(mask, roi_polygon, 255)
masked_edges = cv2.bitwise_and(edges, mask)
# 概率霍夫变换拟合直线线段
lines = cv2.HoughLinesP(
masked_edges,
rho=1,
theta=np.pi / 180,
threshold=20,
minLineLength=20,
maxLineGap=10
)
return lines
2. 斜率几何过滤与多帧时序平滑
霍夫变换检出的原始线段往往夹杂横向路面接缝,我们通过斜率数学约束予以剔除:
直线斜率 m = (y2 - y1) / (x2 - x1)
- 左侧车道线候选:
m < -0.5(负斜率强约束) - 右侧车道线候选:
m > 0.5(正斜率强约束) - 横向路面杂音:
|m| <= 0.5(斑马线、减速带完全剔除)
针对通过初筛的车道线方程参数,使用 deque(maxlen=7) 的定长双端队列维护移动平均值,彻底消除了由于颠簸造成的单帧剧烈晃动。
3. 基于几何多边形 IoU 的车道侵入判定

车辆并非只要车身进入画面就算侵入,真正的交通违法在于轮胎与标线的物理接触。我们将车辆接地部分定义为车辆底部 30% 区域(Footprint):
Footprint = [x_min, y_min + 0.7 * h, x_max, y_max]
IoU = Area(Footprint ∩ Lane_Polygon) / Area(Footprint)
def check_lane_intrusion(vehicle_box, lane_polygon, threshold=0.05):
vx1, vy1, vx2, vy2 = vehicle_box
vh = vy2 - vy1
# 提取车辆物理接地面
footprint = Polygon([(vx1, vy1 + 0.7*vh), (vx2, vy1 + 0.7*vh), (vx2, vy2), (vx1, vy2)])
# 计算空间多边形相交重叠面积比
intersection = footprint.intersection(lane_polygon).area
iou = intersection / footprint.area
return iou > threshold, iou
当 IoU > 0.05 时,系统判定发生压线违章事件,立即激活下游的 YOLOv5 车牌局部检测与超分辨率重建。
4. 下篇预告
在第 3 篇中,我们将深入解析 两阶段分层目标检测架构,展示如何将 YOLOv3 车辆框与精调的 YOLOv5 车牌模型结合,并借助 CSRT 跟踪器 节省 80% 的 GPU 推断开销。
