基于 OpenCV 的车辆检测系统

项目介绍

通过此车辆检测系统,我们可以实时判断某时刻内通过摄像头某一区域内的车辆数,如下图所示:
在这里插入图片描述

实现流程

  • 1、提取出一段视频中的每一帧图像;
  • 2、使用帧差分技术检测车辆目标;
  • 3、图像预处理:
    • 3.1 对图像应用阈值处理;
    • 3.2 图像膨胀;
  • 4、选择车辆检测区域(ROI);
  • 5、在 ROI 中寻找车辆轮廓;
  • 6、将轮廓绘制到原始帧上得到含有轮廓的每一帧;
  • 7、将得到的所有帧合成视频。

代码

import os
import re
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 得到 frames 文件夹中所有图像的文件名
col_frames = os.listdir('frames/')

# 根据文件名给所有图像排序
col_frames.sort(key=lambda f: int(re.sub('\D', '', f)))

# 空列表 col_images 用于存放加载进来的图像
col_images=[]

for i in col_frames:
    # 加载图像
    img = cv2.imread('frames/'+i)
    # 将图像加载到 col_images 中
    col_images.append(img)

# 视频路径
pathOut = 'vehicle_detection_v3.mp4'

# 帧率(每秒多少帧)
fps = 14.0

# 每帧的图像尺寸
size = (col_images[0].shape[1], col_images[0].shape[0])

# 写入视频
out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'DIVX'), fps, size)

# 用于图像膨胀的核
kernel = np.ones((4,4),np.uint8)

# 字体类型
font = cv2.FONT_HERSHEY_SIMPLEX

for i in range(len(col_images)-1):

    # 帧差分技术检测车辆目标
    grayA = cv2.cvtColor(col_images[i], cv2.COLOR_BGR2GRAY)  # 上一帧图像
    grayB = cv2.cvtColor(col_images[i+1], cv2.COLOR_BGR2GRAY)  # 下一帧图像
    diff_image = cv2.absdiff(grayB, grayA)  # 两帧图像之差

    # 图像阈值化
    ret, thresh = cv2.threshold(diff_image, 30, 255, cv2.THRESH_BINARY)

    # 图像膨胀
    dilated = cv2.dilate(thresh,kernel,iterations = 1)

    # 寻找轮廓
    contours, hierarchy = cv2.findContours(dilated.copy(), cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

    # 统计选择的检测区域中的轮廓(有效轮廓)
    valid_cntrs = []  # 空列表 valid_cntrs 用于存放有效轮廓
    for cntr in contours:  # 遍历找到的所有轮廓
        x,y,w,h = cv2.boundingRect(cntr)  # 轮廓的坐标
        # 选择的检测区域为 [:200, 80:]
        # 有效轮廓的面积大于等于 25
        if (x <= 200) & (y >= 80) & (cv2.contourArea(cntr) >= 25):
            valid_cntrs.append(cntr)  # 将有效轮廓添加进 valid_cntrs

    # 把每一帧中找到的有效轮廓添加到原始帧上
    dmy = col_images[i].copy()
    cv2.drawContours(dmy, valid_cntrs, -1, (127,200,0), 2)

    cv2.putText(dmy, "vehicles detected: " + str(len(valid_cntrs)), (55, 15), font, 0.6, (0, 180, 0), 2)
    cv2.line(dmy, (0, 80),(256,80),(100, 255, 255))
    out.write(dmy)
    
out.release()

猜你喜欢

转载自blog.csdn.net/qq_36758914/article/details/106843567