You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自动驾驶车道检测中如何记录前3帧的均值斜率与截距

实现前3帧车道参数的存储与校验修正

我来帮你搞定保存前3帧左右侧均值斜率和截距的需求,这样就能用历史数据来校验当前帧的参数,减少检测误差啦。下面是具体的实现思路和修改后的代码:

核心思路

  • 用collections.deque创建固定长度的队列,专门存储每帧的左右侧斜率、截距数据,队列长度设为3,满了之后自动移除最旧的帧数据。
  • 每帧计算完当前的均值斜率和截距后,把有效数据(非None的情况)加入队列。
  • 当队列积累了足够数据(至少3帧),可以通过历史数据的均值来校验当前帧的参数,比如如果当前帧的斜率和历史均值偏差超过阈值,就用历史值或者加权平均来修正。

修改后的完整代码

import numpy as np
import cv2
import math
from collections import deque

cap = cv2.VideoCapture('video3.mov')

# 初始化存储前3帧数据的队列,每个元素是(left_slope, left_intercept, right_slope, right_intercept)
history_queue = deque(maxlen=3)

while (cap.isOpened()):
    ret, frame = cap.read()
    if not ret:
        break  # 处理视频结束的情况
    
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HLS)
    # HSL color mask
    lower_white = np.uint8([0, 140, 0])
    upper_white = np.uint8([255, 255, 255])
    mask = cv2.inRange(hsv, lower_white, upper_white)
    res = cv2.bitwise_and(frame, frame, mask=mask)
    
    height = np.size(hsv, 0)
    width = np.size(hsv, 1)
    rows, cols = hsv.shape[:2]
    
    bottom_left = [cols * 0, rows * 0.9]
    top_left = [cols * 0.4, rows * 0.7]
    bottom_right = [cols * 1, rows * 0.9]
    top_right = [cols * 0.6, rows * 0.7]
    vertices = np.array([[bottom_left, top_left, top_right, bottom_right]], dtype=np.int32)
    maskzero = np.zeros_like(res)
    cv2.fillPoly(maskzero, vertices, (255,) * maskzero.shape[2])
    maskedimg = cv2.bitwise_and(res, maskzero)
    
    gaussian = cv2.GaussianBlur(maskedimg, (3, 3), 0)
    cannymask = cv2.Canny(gaussian, 150, 250)
    lines = cv2.HoughLinesP(cannymask, rho=1, theta=np.pi / 180, threshold=20, minLineLength=10, maxLineGap=300)
    
    left_slope = []
    right_slope = []
    left_intercept = []
    right_intercept = []
    total_right_length = []
    total_left_length = []
    
    if lines is not None:
        for line in lines:
            for x1, y1, x2, y2 in line:
                if (x2 - x1) != 0:
                    slope = (y2 - y1) / (x2 - x1)
                    intercept = y1 - slope * x1
                    length = np.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2)
                    angle = math.atan2(y2-y1,x2-x1)
                    degree = angle * 180 / np.pi
                    if x2 == x1 or y2 == y1:
                        continue
                    elif slope > 0:
                        if int(degree) in range (27,41):
                            right_slope.append(slope)
                            right_intercept.append(intercept)
                            total_right_length.append(length)
                    elif slope < 0:
                        if int(degree) in range (-62,-31):
                            left_slope.append(slope)
                            left_intercept.append(intercept)
                            total_left_length.append(length)
    
    # 计算当前帧的均值参数
    right_mean_slope = np.mean(right_slope) if len(right_slope) > 0 else None
    right_mean_intercept = np.mean(right_intercept) if len(right_intercept) > 0 else None
    left_mean_slope = np.mean(left_slope) if len(left_slope) > 0 else None
    left_mean_intercept = np.mean(left_intercept) if len(left_intercept) > 0 else None
    
    # 将当前帧的有效参数加入历史队列(只存非None的,或者可以用占位符,这里选存实际有效数据)
    current_frame_data = (left_mean_slope, left_mean_intercept, right_mean_slope, right_mean_intercept)
    history_queue.append(current_frame_data)
    
    # --- 这里是校验修正逻辑,你可以根据需求调整 ---
    # 当队列有至少3帧数据时,计算历史均值来修正当前帧参数
    corrected_left_slope = left_mean_slope
    corrected_left_intercept = left_mean_intercept
    corrected_right_slope = right_mean_slope
    corrected_right_intercept = right_mean_intercept
    
    if len(history_queue) >= 3:
        # 提取历史中的有效左侧斜率和截距
        hist_left_slopes = [data[0] for data in history_queue if data[0] is not None]
        hist_left_intercepts = [data[1] for data in history_queue if data[1] is not None]
        # 提取历史中的有效右侧斜率和截距
        hist_right_slopes = [data[2] for data in history_queue if data[2] is not None]
        hist_right_intercepts = [data[3] for data in history_queue if data[3] is not None]
        
        # 计算历史均值
        hist_left_slope_mean = np.mean(hist_left_slopes) if hist_left_slopes else None
        hist_left_intercept_mean = np.mean(hist_left_intercepts) if hist_left_intercepts else None
        hist_right_slope_mean = np.mean(hist_right_slopes) if hist_right_slopes else None
        hist_right_intercept_mean = np.mean(hist_right_intercepts) if hist_right_intercepts else None
        
        # 示例:如果当前帧参数存在,且和历史均值偏差超过阈值(比如斜率偏差0.1),则用历史均值修正
        slope_threshold = 0.1
        intercept_threshold = 50
        
        if left_mean_slope is not None and hist_left_slope_mean is not None:
            if abs(left_mean_slope - hist_left_slope_mean) > slope_threshold:
                corrected_left_slope = hist_left_slope_mean
                corrected_left_intercept = hist_left_intercept_mean
        
        if right_mean_slope is not None and hist_right_slope_mean is not None:
            if abs(right_mean_slope - hist_right_slope_mean) > slope_threshold:
                corrected_right_slope = hist_right_slope_mean
                corrected_right_intercept = hist_right_intercept_mean
    
    # --- 用修正后的参数计算车道线坐标 ---
    y1 = frame.shape[0]  # bottom of the image
    y2 = y1 * 0.7
    
    right_x1, right_y1, right_x2, right_y2 = 0,0,0,0
    left_x1, left_y1, left_x2, left_y2 = 0,0,0,0
    
    if corrected_right_intercept is not None and corrected_right_slope is not None:
        right_x1 = int((y1 - corrected_right_intercept)/corrected_right_slope)
        right_x2 = int((y2 - corrected_right_intercept)/corrected_right_slope)
        right_y1 = int(y1)
        right_y2 = int(y2)
    
    if corrected_left_intercept is not None and corrected_left_slope is not None:
        left_x1 = int((y1 - corrected_left_intercept)/corrected_left_slope)
        left_x2 = int((y2 - corrected_left_intercept)/corrected_left_slope)
        left_y1 = int(y1)
        left_y2 = int(y2)
    
    cv2.line(frame, (right_x1, right_y1), (right_x2, right_y2), (0, 0, 255), 10)
    cv2.line(frame, (left_x1, left_y1), (left_x2, left_y2), (255, 0,0), 10)
    
    cv2.imshow("New_lines", frame)
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

关键部分说明

  1. 历史队列初始化:用deque(maxlen=3)创建最多存3帧数据的队列,自动维护最新的3帧数据,不用手动处理旧数据的删除。
  2. 数据存入队列:每帧计算完参数后,把当前帧的左右斜率、截距打包存入队列,确保历史数据的完整性。
  3. 校验修正逻辑:当队列满3帧时,提取历史中的有效数据计算均值,然后和当前帧参数对比。如果偏差超过设定的阈值,就用历史均值替换当前参数——你可以根据实际场景调整阈值和修正策略,比如采用加权平均(当前帧权重更高)来平衡实时性和稳定性。
  4. 使用修正后参数绘制车道线:最后用修正后的斜率和截距计算车道线坐标,这样就能得到更平滑、稳定的车道检测结果。

内容的提问来源于stack exchange,提问作者SSR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:42:43