[Vision AI] 動的車線境界抽出および幾何学的IoU車線侵犯判定アルゴリズム (#2)
· 約2分

📌 Key Takeaways (要約)
- 課題: ドラレコ映像は路面反射、アスファルトの亀裂、影によって誤検出が多発し、単純な座標判定では車線変更の瞬間を正確に捉えられません。
- 解決策: 消失点基準の台形ROIマスク、傾きフィルタリング(|slope| > 0.5)、および7フレーム移動平均キューを採用しました。侵犯判定は車両接地領域(下部30%)と車線ポリゴン間の幾何学的IoU(> 0.05)で定式化しました。
- 成果: 路面ノイズを95%以上除外しながら、車線侵犯の瞬間をサブフレーム単位で安定して検出することに成功しました。
1. 動的車線検出: Cannyと確率的ハフ変換
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)
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)
return cv2.HoughLinesP(masked_edges, 1, np.pi/180, 20, minLineLength=20, maxLineGap=10)
2. 傾きフィルタリングと平滑化
線分の傾き m = (y2 - y1) / (x2 - x1) を評価:
- 左車線:
m < -0.5 - 右車線:
m > 0.5 - 路面ノイズ(横線):
|m| <= 0.5は即座に棄却
さらに deque(maxlen=7) を用いてフレーム間の揺れ(ジッター)を除去します。
3. 幾何学的IoU侵犯判定

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 を超えた段階で侵犯フラグを有効化し、ナンバープレート検出器を起動します。
4. 次回予告
第3編では、階層的物体検出(YOLOv3 + YOLOv5プレート専用モデル)と、GPU負荷を大幅に削減するCSRT追跡器の統合について解説します。
