当前位置: 首页 > article >正文

OpenCV实战:车辆统计

目录

1. 项目总览

1.1 项目简述

1.2 车辆统计项目所需的知识点

1.3 最终效果

2. 项目实现过程

2.1 加载视频

2.2 降噪和背景去除

2.2.1 安装扩展模块

2.2.2 接口说明

2.2.3 参数说明

2.2.4 代码示例

2.3 形态学处理

2.4 统计逻辑处理

3. 优化与扩展

3.1 优化方案

3.2 扩展功能

4. 总结

5. 资源以及代码下载


1. 项目总览

1.1 项目简述

车辆统计是一项常见的交通监控任务,用于分析道路上的车流量,以优化交通管理。通过OpenCV,可以高效实现车辆检测与计数,适用于道路摄像头监控的实际应用。实现步骤如下:

  • 加载视频。
  • 降噪和背景去除:去除与统计无关的干扰项。
  • 形态学处理:确认车辆位置,以及绘制外接矩形。
  • 实现车辆统计逻辑,绘制检测线以及统计结果。

1.2 车辆统计项目所需的知识点

OpenCV基础:视频的采集、读取与录制_cv2.videocapture cap.read-CSDN博客

OpenCV基础:图像运算-CSDN博客

OpenCV基础:绘制基本图形_opencv画形状-CSDN博客

OpenCV:图像处理中的低通滤波_图像低通滤波-CSDN博客

OpenCV:形态学操作总结-CSDN博客

OpenCV:图像轮廓-CSDN博客

OpenCV:外接矩形-CSDN博客

1.3 最终效果


2. 项目实现过程

2.1 加载视频

此阶段目的是加载视频资源。

代码如下:

import cv2

cap = cv2.VideoCapture('D:\\resource\\filter\\video.mp4')

while True:
    ret, frame = cap.read()
    if (ret == True):
        cv2.imshow('car stats', frame)

    key = cv2.waitKey(1)
    if (key == ord('q')):
        break
    
cap.release()
cv2.destroyAllWindows()

2.2 降噪和背景去除

此阶段的目的是让图像中只留下行驶的车辆,删除与统计项无关的物体。

2.2.1 安装扩展模块

去掉视频背景需要用到bgsegm,安装OpenCV Contrib扩展模块:

pip install opencv-contrib-python

安装过程:

2.2.2 接口说明

 需要使用的接口为:

cv2.bgsegm.createBackgroundSubtractorMOG(history=200, nmixtures=5, backgroundRatio=0.7, noiseSigma=0)

以下是关于此接口的说明:

cv2.bgsegm.createBackgroundSubtractorMOG() 是 OpenCV 提供的一个用于背景建模和背景减除的函数,它实现了经典的 Mixture of Gaussians (MOG) 背景建模算法。该函数属于 OpenCV 的 bgsegm 模块,它是背景分割的一个实现扩展。

函数作用:
背景减除是一种用于检测视频中的前景物体(如行人、车辆等)的技术。cv2.bgsegm.createBackgroundSubtractorMOG() 通过对视频帧序列进行建模,将静态部分(背景)与动态部分(前景)区分开来。


适用场景:

  • 交通监控:检测道路上的车辆和行人。
  • 视频分析:提取动态前景物体,用于后续目标识别或跟踪。
  • 行为分析:在静态背景中分离动态目标,分析其行为。

注意事项:

  • 动态背景:如果背景是动态的(如树叶摆动、水流),算法可能会误检测为前景。
  • 可以尝试调整 history 和 nmixtures 参数,或使用其他更高级的背景建模方法(如 MOG2 或 KNN)。
  • 光照变化:MOG 对光照变化敏感,需适当调整 backgroundRatio 或选择其他鲁棒算法。
  • bgsegm 模块:该模块可能需要在安装 OpenCV 的扩展版本(如 opencv-contrib-python)后才能使用。
2.2.3 参数说明

history:

  • 背景模型中保留的帧数(即时间窗口大小)。
  • 默认值为 200。
  • 数值越大,背景模型的更新速度越慢;数值越小,模型对动态背景的适应速度越快。

nmixtures:

  • 高斯混合模型的高斯分布个数。
  • 默认值为 5。
  • 控制模型的复杂度,较高的值可更好地处理复杂场景。

backgroundRatio:

  • 决定背景的高斯模型概率阈值,范围为 0~1。
  • 默认值为 0.7。
  • 较高的值表示更严格的背景建模。

noiseSigma:

  • 添加的高斯噪声标准差,用于处理噪声。
  • 默认值为 0。
  • 较大的值可更好地处理具有较多噪声的场景。

返回值

  • 返回一个背景减除器对象,用于从输入视频中提取前景。
2.2.4 代码示例

以下是降噪和背景去除代码:

import cv2

cap = cv2.VideoCapture('D:\\resource\\filter\\video.mp4')
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()

while True:
    ret, frame = cap.read()
    if (ret == True):
        #转为灰度图
        cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        #高斯降噪
        blur = cv2.GaussianBlur(frame, (3,3), 5)
        #去背景
        mask = bgsubmog.apply(blur)
        cv2.imshow('car stats', mask)

    key = cv2.waitKey(1)
    if (key == ord('q')):
        break
    
cap.release()
cv2.destroyAllWindows()

代码说明:

  • 读取一帧后,先转为灰度图,然后使用高斯降噪;
  • 使用bssegm组件去除背景。 

只去除背景,不进行高斯降噪时:

降噪后,去除背景:

 先降噪,再去背景,画面会干净很多。

2.3 形态学处理

本阶段主要是通过形态学操作确定车辆所在的位置,将车辆的外接矩形画出来。

代码实现:

import cv2

cap = cv2.VideoCapture('D:\\resource\\filter\\video.mp4')
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()

#形态学结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))

while True:
    ret, frame = cap.read()
    if (ret == True):
        #转为灰度图
        cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

        #高斯降噪
        frame_blur = cv2.GaussianBlur(frame, (3,3), 5)

        #去背景
        frame_mask = bgsubmog.apply(frame_blur)

        #形态学操作
        #腐蚀
        frame_erode = cv2.erode(frame_mask, kernel)

        #膨胀
        frame_dilate = cv2.dilate(frame_erode, kernel, iterations=3)

        #闭运算,去除物体内部的孔洞
        frame_close = cv2.morphologyEx(frame_dilate, cv2.MORPH_CLOSE, kernel)
        frame_close = cv2.morphologyEx(frame_close, cv2.MORPH_CLOSE, kernel)

        #查找轮廓、绘制矩形
        contours, _ = cv2.findContours(frame_close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        for (i,con) in enumerate(contours):
            x,y,w,h = cv2.boundingRect(con)
            cv2.rectangle(frame, (x,y), (x+w,y+h), (0,0,255), 2)

        #显示画面
        cv2.imshow('car stats', frame)

    key = cv2.waitKey(1)
    if (key == ord('q')):
        break
    
cap.release()
cv2.destroyAllWindows()

代码说明:

  • 去掉背景之后,进行腐蚀操作,目的是为了进一步减少车辆周围的小噪点;
  • 腐蚀之后车辆会缩小,进行膨胀操作的目的是放大车辆,让车辆更加明显;
  • 然后进行闭运算,目的是去掉膨胀操作后车辆内部出现的孔洞;
  • 最后进行轮廓查找,将车辆的外接矩形画出来。

运行效果:

2.4 统计逻辑处理

以下是统计逻辑的处理,基本已经完成了车辆统计功能,代码如下:

import cv2

# 获取中心点
def center(x, y, w, h):
    x1 = int(w/2)
    y1 = int(h/2)
    cx = x + x1
    cy = y + y1
    return cx, cy

cap = cv2.VideoCapture('D:\\resource\\filter\\video.mp4')
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()

# 形态学结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))

# 定义车辆的宽高
min_w = 90
min_h = 90

# 检测线的位置
line_high = 550

# 线的偏移
offset = 7

# 统计数量
car_count = 0

# 存放有效车辆
cars = []

while True:
    ret, frame = cap.read()
    if (ret == True):
        # 转灰度
        cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

        # 高斯降噪
        frame_blur = cv2.GaussianBlur(frame, (3,3), 5)

        # 去背景
        frame_mask = bgsubmog.apply(frame_blur)

        # 形态学操作
        # 腐蚀
        frame_erode = cv2.erode(frame_mask, kernel)

        # 膨胀
        frame_dilate = cv2.dilate(frame_erode, kernel, iterations=3)

        # 闭运算,去除物体内部的孔洞
        frame_close = cv2.morphologyEx(frame_dilate, cv2.MORPH_CLOSE, kernel)
        frame_close = cv2.morphologyEx(frame_close, cv2.MORPH_CLOSE, kernel)

        # 查找轮廓、绘制矩形
        contours, _ = cv2.findContours(frame_close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        for (i,con) in enumerate(contours):
            x,y,w,h = cv2.boundingRect(con)
            
            # 对车辆的尺寸进行判断
            valid = (w >= min_w) and ( h >= min_h)
            if (not valid):
                continue

            # 有效物体 
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0,0,255), 2)
            cpoint = center(x, y, w, h)
            cars.append(cpoint) 
            cv2.circle(frame, (cpoint), 5, (0,0,255), -1)

            for (x, y) in cars:
                if( (y > line_high - offset) and (y < line_high + offset) ):
                    car_count +=1
                    cars.remove((x, y))

        # 画检测线
        cv2.line(frame, (30, line_high), (1160, line_high), (0, 0, 255), 3)

        # 显示统计数据
        cv2.putText(frame, "Count: " + str(car_count), (900, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,255), 5)

        # 显示画面
        cv2.imshow('car stats', frame)

    key = cv2.waitKey(1)
    if (key == ord('q')):
        break
    
cap.release()
cv2.destroyAllWindows()

代码说明:

  • 在形态学处理之后,将有效物体的外接矩形画出来;
  • 绘制外接矩形的中心点,然后保存坐标;
  • 遍历坐标,判断该坐标是否跨过检测线,满足条件则计数加1;
  • 画检测线与统计结果。

运行结果:


3. 优化与扩展

3.1 优化方案

车辆跟踪:当前方案依赖外接矩形中心点判断,可能存在重复计数的问题。可以引入 卡尔曼滤波KNN 跟踪算法,增强准确性。

3.2 扩展功能

类别识别:引入目标检测模型(如 YOLO 或 Faster R-CNN),区分小车、卡车、摩托车等不同车辆类型。

4. 总结

通过OpenCV相关接口以及统计逻辑处理,可以快速实现车辆计数。以下是关键点:

  • 背景去除:排除背景干扰。
  • 图像预处理:通过降噪和形态学操作增强目标。
  • 轮廓检测与计数:基于矩形中心点穿越计数线进行车辆计数。

此方案适用于普通道路监控场景,结合跟踪算法和深度学习技术可进一步提升性能与适用性。

5. 资源以及代码下载

通过网盘分享的文件:opencv_car_stats.zip
链接: https://pan.baidu.com/s/1GPa1f0OibfgLmjbomvDtWA?pwd=open 提取码: open 


http://www.kler.cn/a/526566.html

相关文章:

  • .NET Core缓存
  • 572. 另一棵树的子树
  • 网站快速收录:利用新闻源的优势
  • java.math 包 中的 BigDecimal 类(详细案例拆解)
  • 网络安全技术简介
  • Vue3 结合 .NetCore WebApi 前后端分离跨域请求简易实例
  • UML状态机图-并发的表示方法
  • 【Linux】makefile、进度条实现
  • 【ArcGIS遇上Python】批量提取多波段影像至单个波段
  • 【Linux】从硬件到软件了解进程
  • 【愚公系列】《循序渐进Vue.js 3.x前端开发实践》035-组合式API的应用
  • AI大模型开发原理篇-5:循环神经网络RNN
  • 计算机网络之计算机网络分层结构
  • 【RocketMQ 存储】- RocketMQ存储类 MappedFile
  • INCOSE需求编写指南-附录 A: 参考文献
  • 鸟瞰欧洲(意境欧洲) 第一季
  • 尚硅谷spring框架视频教程——学习笔记一(IOC、AOP)
  • 【视频+图文详解】HTML基础3-html常用标签
  • 如何在本地部署deepseek-r1模型【详细步骤】
  • Java8_StreamAPI
  • LruCache实现
  • 【gRPC-gateway】option定义规则及HttpBody响应
  • leetcode——翻转二叉树(java)
  • 【网络】3.HTTP(讲解HTTP协议和写HTTP服务)
  • 《Windows 11轻松设置:一键优化系统,提升电脑效率》
  • Three.js实现3D动态心形与粒子背景的数学与代码映射解析