首页 > 其他分享 >基于OpenCv的车辆检测&计数

基于OpenCv的车辆检测&计数

时间:2024-12-28 09:56:34浏览次数:9  
标签:视频 计数 检测 frame cv2 ret OpenCv 车辆 line

项目描述:在截取一段公路上车流量视频,通过OpenCv识别经过的车辆并进行计数统计。

汽车视频素材MP4

 本项目实践目的旨在学习运用OpenCV知识,所以只截取了视频的一部分

目录

一、所用到的OpenCv知识:

二、项目实现流程

1 将车流量视频加载出来

2 通过形态学识别车辆

2.1 前景/背景分割算法

2.2 去噪、腐蚀、膨胀以及闭运算操作

2.3 识别车辆

3 对车辆进行统计

3.1 实现思路

3.2 设定统计区域

3.3 对车辆进行计数

3.4 显示统计信息

4 整体运行代码


一、所用到的OpenCv知识:

1.窗口展示

2.图像/视频的加载

3.基本图像&文本绘制;

车辆识别:

4.基本图像运算与处理

5.形态学

6.轮廓查找

二、项目实现流程

1 将车流量视频加载出来

import cv2 
import numpy as np

# 打开摄像头
cap = cv2.VideoCapture('./video.mp4')

# 循环读取视频
while True:
    ret, frame = cap.read()
    # 读取视频的每一帧,返回“标记”ret和这一帧的数据frame,读到数据ret为TRUE,没读到为Fales
    if ret == True:
        cv2.imshow('video', frame)        
    # 用户按ESC退出
    key = cv2.waitKey(1)
    if key == 27:
        break
        
# 别忘了释放资源
cap.release()
cv2.destroyAllWindows()

代码中video为车辆视频素材

2 通过形态学识别车辆

2.1 前景/背景分割算法

cv2.createBackgroundSubtractorMOG2()    # 是 OpenCV 库中用于背景减除的函数

  • 背景减除是一种计算机视觉技术,用于从视频序列中分离出前景物体和背景。其基本思想是通过对视频序列中的像素进行分析,建立背景模型,然后将当前帧与背景模型进行比较,将与背景模型差异较大的像素判定为前景像素,从而提取出前景物体。这种技术在视频监控、目标跟踪等诸多领域有广泛的应用。

 实例代码

import cv2 
import numpy as np
# 加载车辆视频
cap = cv2.VideoCapture('./video.mp4')
# 创建MOG对象
mog = cv2.createBackgroundSubtractorMOG2()
# 循环读取视频
while True:
    ret, frame = cap.read()
    # 读取视频的每一帧,返回“标记”ret和这一帧的数据frame,读到数据ret为TRUE,没读到为Fales
    if ret == True:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        bgmask = mog.apply(frame)
        cv2.imshow('bgmask', bgmask)
    # 用户按ESC退出
    key = cv2.waitKey(1000//120)  # 1000//60 可以调帧数
    if key & 0xFF  == 27:
        break
    
# 最后别忘了释放资源
cap.release()
cv2.destroyAllWindows()

逐帧读取视频,使用 mog.apply(frame)方法将背景减除应用到每一帧上,得到前景掩码fgmask,并显示这个掩码

 这样我们就能通过这个算法在视频中找出正在行驶的车辆

2.2 去噪、腐蚀、膨胀以及闭运算操作

首先将上一小节前景分割后的车辆视频进行去噪、腐蚀、膨胀等操作

# 去噪
blur = cv2.GaussianBlur(gray, (13, 13), 15)
bgmask = mog.apply(blur)
# 腐蚀
erode = cv2.erode(bgmask, kernel)
# 膨胀
dialte = cv2.dilate(erode, kernel, iterations=4)
# 消除内部的小方块:闭运算
close = cv2.morphologyEx(dialte, cv2.MORPH_CLOSE, kernel, iterations=1)

测式代码如下 

import cv2 
import numpy as np

# 加载视频
cap = cv2.VideoCapture('./video.mp4')
# 创建MOG对象
mog = cv2.createBackgroundSubtractorMOG2()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

# 循环读取视频
while True:
    ret, frame = cap.read()
    # 读取视频的每一帧,返回“标记”ret和这一帧的数据frame,读到数据ret为TRUE,没读到为Fales
    if ret == True:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 去噪
        blur = cv2.GaussianBlur(gray, (13, 13), 15)
        bgmask = mog.apply(blur)
        # 腐蚀
        erode = cv2.erode(bgmask, kernel)
        # 膨胀
        dialte = cv2.dilate(erode, kernel, iterations=4)
        # 消除内部的小方块:闭运算
        close = cv2.morphologyEx(dialte, cv2.MORPH_CLOSE, kernel, iterations=1)
        cv2.imshow('video', close)
    # 用户按ESC退出
    key = cv2.waitKey(1000//60) 
    if key & 0xFF  == 27:
        break
    
# 释放资源
cap.release()
cv2.destroyAllWindows()

效果如图所示,我们只需要当车辆靠近时检测车辆,所以靠近时呈现出较为饱满的轮廓即可

2.3 识别车辆

获取汽车轮廓

 # findContours(image, mode, method[, contours[, hierarchy[, offset]]])

 新版本OpenCv返回两个结果,轮廓和层级,老版本返回三个参数,图像,轮廓,和层级

contours, hierarchy = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

设置检测阈值

min_w = 150
min_h = 150
max_w = 385
max_h = 368

 画出所有检测出的轮廓

for contour in contours:
    # 最大外接矩形
    x, y, w, h = cv2.boundingRect(contour)
    is_valid = (min_w < w < max_w) and (min_h < h < max_h )
    if not is_valid:
        continue
    # 绘制矩形,要求坐标点都是整数
    cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

代码解析:首先对视频每一帧视频的白色区域查找最大外接矩形,然后根据车辆在合理位置的大小给定一个阈值变量 is_valid 得到满足画框的最大和最小边界值,效果如图所示:

3 对车辆进行统计

3.1 实现思路

在离我们摄像头(视频)较近位置放置一条实线,假想当车辆过线时,则对车辆计数。

计数思路:在检测到车辆(矩形框)设置一个中心点,当中心点的高超过我们设定实线的高时,则判定为有车辆经过,车辆计数+1。

3.2 设定统计区域

下面为代码实操

# 定义全局变量
line_high = 535
offset = 3
cars = []
carno= 0

cv2.line(frame, (50, line_high), (1250, line_high), (255, 255, 0), 3)

line_high= 535 为线的高度;

offset = 3是为计数区域设定的阈值,以防多数或少数

cars = [ ]把经过的每辆车的坐标存储到列表里

carno = 0 为车辆计数

生成外接矩形的中心点:

def center(x, y, w, h):
    cx = int(x + w/2)
    cy = int(y + h/2)
    return cx, cy

  将检测到车辆的中心坐标存储到cars列表

cpoint = center(x, y, w, h)
cars.append(cpoint)

3.3 对车辆进行计数

 遍历列表cars中的中心点坐标,并判断是否在计数区域内,若在区域内则carno+1

# 判断汽车是否过线
    for (x, y) in cars:
        if y > (line_high - 1) and y < (line_high + offset):
            # 落入有效区间
            carno +=1
            # print(carno)
        cars.remove((x, y))

3.4 显示统计信息

cv2.putText(frame, 'Vehicle Count:' + str(carno), (750, 100), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5)

效果如图所示

4 整体运行代码

附上整体运行代码,仅供参考 

import cv2 
import numpy as np

# 打开摄像头
cap = cv2.VideoCapture('./video.mp4')
# 创建MOG对象
mog = cv2.createBackgroundSubtractorMOG2()
# 获取形态学卷积
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

min_w = 150
min_h = 150
max_w = 385
max_h = 368
line_high = 535
offset = 3
cars = []
carno= 0
# 生成外接矩形的中心点
def center(x, y, w, h):
    cx = int(x + w/2)
    cy = int(y + h/2)
    return cx, cy

# 循环读取视频
while True:
    ret, frame = cap.read()
    # 读取视频的每一帧,返回“标记”ret和这一帧的数据frame,读到数据ret为TRUE,没读到为Fales
    if ret == True:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 去噪
        blur = cv2.GaussianBlur(gray, (13, 13), 15)
        bgmask = mog.apply(blur)
        # 腐蚀
        erode = cv2.erode(bgmask, kernel)
        # 膨胀
        dialte = cv2.dilate(erode, kernel, iterations=4)
        # 消除内部的小方块:闭运算
        close = cv2.morphologyEx(dialte, cv2.MORPH_CLOSE, kernel, iterations=1)
        # 获取车辆轮廓
        contours, hierarchy = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        
        cv2.line(frame, (50, line_high), (1250, line_high), (255, 255, 0), 3)
        
        # 画出所有检测出来的轮廓
        for contour in contours:
            # 最大外接矩形
            x, y, w, h = cv2.boundingRect(contour)
            is_valid = (min_w < w < max_w) and (min_h < h < max_h )
            if not is_valid:
                continue
            # 绘制矩形,要求坐标点都是整数
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
            cpoint = center(x, y, w, h)
            cars.append(cpoint)
            # 判断汽车是否过线
            for (x, y) in cars:
                if y > (line_high - 1) and y < (line_high + offset):
                    # 落入有效区间
                    carno +=1
                    # print(carno)
                cars.remove((x, y))
        cv2.putText(frame, 'Vehicle Count:' + str(carno), (750, 100), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5)
        cv2.imshow('frame', frame)
    
    # 用户按ESC退出
    key = cv2.waitKey(1000//120)  # 1000//60 可以调帧数
    if key & 0xFF  == 27:
        break
print('车辆计数:', carno)    
# 最后别忘了释放资源
cap.release()
cv2.destroyAllWindows()

标签:视频,计数,检测,frame,cv2,ret,OpenCv,车辆,line
From: https://blog.csdn.net/agentssl/article/details/144201495

相关文章

  • cpp opencv static library
    OpenCV5+VisualStudio2022win64staticlibraryHowtouseOpencvasstaticlibrary(withoutDLL)inVC++projectsdownloaddownloadOpencV5fromhttps://github.com/opencv/opencv/tree/5.xbuildextractthefilesuseCmakeBUILDSHAREDLIBSOFFBUILDO......
  • 《机器学习》——利用OpenCV库中的KNN算法进行图像识别
    文章目录KNN算法介绍下载OpenCV库实验内容实验结果完整代码手写数字传入模型训练KNN算法介绍一、KNN算法的基本要素K值的选择:K值代表选择与新测试样本距离最近的前K个训练样本数,通常K是不大于20的整数。K值的选择对算法结果有重要影响,需要通过交叉验证等方法来确......
  • 面向自动驾驶的实时交通场景深度图像分割与障碍物检测系统的设计与实现
    面向自动驾驶的实时交通场景深度图像分割与障碍物检测系统的设计与实现摘要随着自动驾驶技术的快速发展,视觉感知技术成为其中的核心环节之一。本研究设计并实现了基于YOLOv8的实时交通场景障碍物检测与语义分割系统。通过深度学习技术优化模型性能,系统实现了在复杂交通环......
  • C#调用C++代码,以OpenCV为例
    前言使用C#调用C++代码是一个很常见的需求,因此本文以知名的C++机器视觉库OpenCV为例,说明在C#中如何通过使用P/Invoke(平台调用)来调用C++代码。只是以OpenCV为例,实际上在C#中使用OpenCV可以使用OpenCVSharp这个项目,这是一个很优秀的项目,GitHub地址:https://github.com/shimat/opencv......
  • OpenCV 入门
    OpenCV_Python入门创建/显示窗口方法说明参数返回namedWindow创建一个窗口窗口名称,WINDOW_NORMAL(窗口属性)resizeWindow设置窗口大小窗口名称,宽,高imshow显示窗口窗口名称,要显示的图像destroyAllWindows关闭所有窗口waitKey延时监听键盘按下0无限/单位毫秒键盘按下......
  • OpenCV-Python实战(7)——阈值处理
    一、cv2.threshold()res,dst=cv2.threshold(src=*,thresh=*,maxval=*,type=*) res:函数返回的阈值。dst:阈值处理后的函数。src:要处理的图像。thresh:阈值。maxval:设定像素最大值。type:阈值函数处理方法,常见方法如下表所示:方法值解释THRESH_BINARY0大于阈值取最大值,......
  • 日志文件爆满_开发脚本每小时自动检测日志大小_定期清理日志_生产环境redis宕机_无法
     今天日志数据占用磁盘爆满,正常运行的系统发生,redis无法写入的报错,导致共用的redis服务器,瘫痪了,很多系统都进不去了. 最后查了一下才知道,是因为磁盘上一个日志文件170多GB了,都是日志.看看怎么处理:首先编写一个脚本,用来循环检测,每一个小时检测文件大小,如果超过......
  • 高精度3D扫描仪用于航空叶片三维尺寸检测及余量分析
    叶片是航空发动机的核心部件,它负责将高温高压的气流转化为发动机推进力。航空发动机高压涡轮单个叶片所产生的动力是一辆小型家用汽车发动机的十倍以上。这些叶片必须在极端恶劣的高温环境下维持正常运转。因此,涡轮叶片设计和检测标准严苛,以保证性能和效率最大化,从而给飞行安全......
  • Linux磁盘阈值及内存阈值检测脚本
    #!/bin/bash#设置阈值,例如磁盘使用率超过80%,内存使用率超过90%DISK_THRESHOLD=90MEMORY_THRESHOLD=99#获取磁盘使用百分比(这里以根目录为例)DISK_USAGE=$(df/--output=pcent|grep-o'[0-9]\+')#获取内存使用百分比MEMORY_USAGE=$(free|grepMem|awk'{print......
  • python+panddleocr+文本检测自定义数据集训练及测试
    python+panddleocr+文本检测自定义数据集训练及测试引言1相关链接2预训练模型及配置文件3文本检测的数据集格式文本检测训练测试1,标签转换(1)标签转换脚本(2)转换后的数据集结果2,训练(1)训练脚本(2)训练结果3,导出(1)导出脚本(2)导出结果4,测试......