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

基于OpenCV从摄像头画面检测道路虚线的问题求助

道路实线与虚线检测问题:静态图片有效,摄像头实时流失效

我正在研发自动驾驶车辆,需要实现从道路画面中区分实线与虚线的功能。尝试过轮廓检测与填充方法,但未取得效果。此前在Stack Overflow找到一段代码,直接读取图片时效果良好,但接入摄像头后完全失效,相关代码如下:

原始静态图片处理代码

import cv2
import numpy as np

img=cv2.imread('test.jpg')

kernel1 = np.ones((3,5),np.uint8)
kernel2 = np.ones((9,9),np.uint8)

imgGray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgBW=cv2.threshold(imgGray, 230, 255, cv2.THRESH_BINARY_INV)[1]

img1=cv2.erode(imgBW, kernel1, iterations=1)
img2=cv2.dilate(img1, kernel2, iterations=3)
img3 = cv2.bitwise_and(imgBW,img2)
img3= cv2.bitwise_not(img3)
img4 = cv2.bitwise_and(imgBW,imgBW,mask=img3)
imgLines= cv2.HoughLinesP(img4,15,np.pi/180,10, minLineLength = 440, 
maxLineGap = 15)

for i in range(len(imgLines)):
    for x1,y1,x2,y2 in imgLines[i]:
        cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)

cv2.imshow('Final Image with dotted Lines detected', img)

接入摄像头的尝试代码

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while True:
    ret, img = cap.read()

    kernel1 = np.ones((3, 5), np.uint8)
    kernel2 = np.ones((9, 9), np.uint8)

    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    imgBW = cv2.threshold(imgGray, 230, 255, cv2.THRESH_BINARY_INV)[1]

    img1 = cv2.erode(imgBW, kernel1, iterations=1)
    img2 = cv2.dilate(img1, kernel2, iterations=3)
    img3 = cv2.bitwise_and(imgBW, img2)
    img3 = cv2.bitwise_not(img3)
    img4 = cv2.bitwise_and(imgBW, imgBW, mask=img3)
    imgLines = cv2.HoughLinesP(img4, 15, np.pi / 180, 10, 
    minLineLength=440, maxLineGap=15)

    for i in range(len(imgLines)):
        for x1, y1, x2, y2 in imgLines[i]:
            cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

    cv2.imshow('img', img)

    if cv2.waitKey(1) & 0xFF == ord('q'):
         break

cap.release()
cv2.destroyAllWindows()

问题原因及修复方案

核心问题

  1. 固定阈值不适应实时场景:静态图片的阈值230是针对特定光照设置的,摄像头实时画面光照变化大,固定阈值会导致二值化完全失效。
  2. HoughLinesP参数过于严苛:minLineLength=440和maxLineGap=15是针对静态图片的分辨率和线条长度设置的,摄像头画面分辨率、拍摄距离变化会导致检测不到线条。
  3. 未处理摄像头读取失败情况:cap.read()可能返回ret=False,直接处理会引发报错。
  4. 形态学操作参数未适配实时画面:静态图的核大小和迭代次数不一定适合动态的实时流场景。

修复后的代码

import cv2
import numpy as np

cap = cv2.VideoCapture(0)
# 可选:设置摄像头分辨率,匹配静态图的分辨率
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

while True:
    ret, img = cap.read()
    if not ret:
        break

    kernel1 = np.ones((3, 5), np.uint8)
    kernel2 = np.ones((7, 7), np.uint8)

    # 改用自适应阈值,适配光照变化
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 自适应阈值:邻域大小11,常数2,处理光照不均
    imgBW = cv2.adaptiveThreshold(imgGray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                  cv2.THRESH_BINARY_INV, 11, 2)

    img1 = cv2.erode(imgBW, kernel1, iterations=1)
    img2 = cv2.dilate(img1, kernel2, iterations=2)  # 减少迭代次数,避免过度膨胀
    img3 = cv2.bitwise_and(imgBW, img2)
    img3 = cv2.bitwise_not(img3)
    img4 = cv2.bitwise_and(imgBW, imgBW, mask=img3)

    # 调整HoughLinesP参数,适配实时画面
    imgLines = cv2.HoughLinesP(img4, 1, np.pi/180, threshold=30,
                               minLineLength=80, maxLineGap=20)

    # 处理imgLines为空的情况,避免报错
    if imgLines is not None:
        for line in imgLines:
            x1, y1, x2, y2 = line[0]
            cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

    cv2.imshow('Dotted Lines Detection', img)

    if cv2.waitKey(1) & 0xFF == ord('q'):
         break

cap.release()
cv2.destroyAllWindows()

关键优化点

  • 改用自适应阈值替代固定阈值:cv2.adaptiveThreshold根据局部区域计算阈值,能应对不同光照下的道路标线。
  • 调整HoughLinesP参数:降低minLineLength、调整threshold和maxLineGap,适配实时画面中线条的实际长度。
  • 增加异常处理:判断ret是否为True、imgLines是否为空,避免程序崩溃。
  • 调整形态学操作参数:缩小膨胀核大小和迭代次数,防止过度处理丢失虚线细节。
  • 可选操作:统一摄像头与静态图的分辨率,减少参数适配成本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 06:24:52