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

OpenCV如何检测轮廓位置 识别车辆驶出车道并绘制红色轮廓

车道车辆越线轮廓绘制实现方案

核心修改逻辑

  • 提前加载黑白车道掩码图转成单通道灰度格式,移出循环避免重复读取损耗性能,其中白色像素对应车道区域、黑色像素对应非车道区域
  • 对每个符合面积阈值的车辆轮廓,计算其外接矩形中心坐标(也可采样多个轮廓点提升判断精度)
  • 判断坐标对应掩码的像素值,若像素值低于127即处于黑色非车道区域,轮廓用红色绘制,否则用绿色绘制

完整可运行代码

import cv2
import numpy as np

def frameDiffer(path):
    cap = cv2.VideoCapture(path)
    ret,oldFrame = cap.read()
    if not ret:
        print("视频读取失败")
        return
    oldGrayFrame = cv2.cvtColor(oldFrame, cv2.COLOR_BGR2GRAY)
    # 提前加载车道掩码和绘制底图
    Roi = cv2.imread('blackAndWhiteRoad.jpg')
    road_mask = cv2.cvtColor(Roi, cv2.COLOR_BGR2GRAY)
    mask_h, mask_w = road_mask.shape[:2]

    while ret:
        ret, newFrame = cap.read()
        if not ret:
            break
        newGrayFrame = cv2.cvtColor(newFrame, cv2.COLOR_BGR2GRAY)
        result = cv2.absdiff(newGrayFrame,oldGrayFrame)
        if np.max(result)>10 :
            result = cv2.threshold(result, 30, 255, cv2.THRESH_BINARY)[1]
            result = cv2.GaussianBlur(result,(7,7),4)
    
            contours,_ = cv2.findContours(result,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
            for cnt in contours:
                if cv2.contourArea(cnt)>150:
                    # 计算轮廓重心
                    M = cv2.moments(cnt)
                    if M["m00"] == 0:
                        continue
                    cX = int(M["m10"] / M["m00"])
                    cY = int(M["m01"] / M["m00"])
                    # 坐标越界直接跳过
                    if not (0<=cX<mask_w and 0<=cY<mask_h):
                        continue
                    # 判断是否处于非车道区域
                    if road_mask[cY, cX] < 127:
                        draw_color = (0,0,255) # 越线标红
                    else:
                        draw_color = (0,255,0) # 正常标绿
                    cv2.drawContours(Roi,[cnt],-1,draw_color,2)

            cv2.imshow('result',cv2.resize(Roi,(960,600)))
            cv2.imshow('newFrame',cv2.resize(newFrame,(960,600)))
    
        oldGrayFrame = newGrayFrame
    
        if cv2.waitKey(1)==ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()

可选精度优化

如果需要避免重心刚好落在车道但车身大部分越线的误判,可以采样轮廓上的多个点做判断,替换原有重心判断逻辑即可:

sample_count = min(5, len(cnt))
out_cnt = 0
for i in range(0, len(cnt), max(1, len(cnt)//sample_count)):
    x,y = cnt[i][0]
    if 0<=x<mask_w and 0<=y<mask_h and road_mask[y,x]<127:
        out_cnt +=1
# 超过一半采样点在非车道区域则判定为越线
draw_color = (0,0,255) if out_cnt >= sample_count//2 else (0,255,0)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 19:36:01