欢迎光临
我们一直在努力

【OpenCV】(十)车辆统计项目

系列内容:OpenCV概述与环境配置,OpenCV基础知识和绘制图形,图像的算数与位运算,图像视频的加载和显示,图像基本变换,滤波器,形态学,图像轮廓,图像直方图,车辆统计项目,特征检测和匹配,图像查找和拼接,虚拟计算器项目,信用卡识别项目,图像的分割与修复,人脸检测与车牌识别,目标追踪,答题卡识别判卷与文档ocr扫描识别,光流估计

 1.效果图

如图10.1所示:


1-车辆统计项目效果图

2.涉及的内容:

窗口的展示

图像/视频的加载

基本图像的绘制

车辆识别

基本图像运算与处理

形态学

轮廓查找

3.涉及的流程

加载视频

通过形态学识别车辆

对车辆进行统计

显示车辆统计信息

4.知识补充

背景剪除

背景减除(Background Subtraction)是许多基于计算机视觉的任务中的主要预处理步骤。如果我们有完整的背景帧,那么我们可以通过帧差法来计算像素差从而获取到前景对象。但是在大多数情况下,我们可能没有这样的图像,所以我们需要从我们拥有的任何图像中提取背景。当运动物体有阴影时,由于阴影也在移动,情况会变的更加复杂。为此引入了背景减除算法,通过这一方法我们能够从视频中分离出运动的物体前景,从而达到目标检测的目的。

BackgroundSubtractorMOG

这是一个以混合高斯模型为基础的前景/背景分割算法。它是 P.KadewTraKuPong 和 R.Bowden 在 2001 年提出的。

它使用 K(K=3 或 5)个高斯分布混合对背景像素进行建模。使用这些颜色(在整个视频中)存在时间的长短作为混合的权重。背景的颜色一般持续的时间最长,而且更加静止。

在编写代码时,我们需要函数:cv2.createBackgroundSubtractorMOG() 创建一个背景对象。这个函数有些可选参数,比如要进行建模场景的时间长度,高斯混合成分的数量,阈值等。将他们全部设置为默认值。然后在整个视频中我们是需要使用

backgroundsubtractor.apply() 就可以得到前景的掩模了.

移动的物体会被标记为白色,背景会被标记为黑色的

5.导入视频

import cv2
import numpy as np

# 加载视频
cap = cv2.VideoCapture('video01.mp4')

# 循环读取视频
while True:
ret, frame = cap.read()
if ret==True:
cv2.imshow('video',frame)

# 用户按ESC退出
key = cv2.waitKey(1) & 0xFF
if key == 27:
break

# 释放视频资源

6.去除背景

import cv2
import numpy as np

# 加载视频
cap = cv2.VideoCapture(0)
#创建msg对象
mog=cv2.bgsegm.createBackgroundSubtractorMOG()

while True:
ret,frame=cap.read()
if ret==True:
fgmask=mog.apply(frame)
cv2.imshow('video',fgmask)

# 用户按ESC退出
key = cv2.waitKey(30)
if key == 27:
break

# 释放视频资源
cap.release()
cv2.destroyAllWindows()

7.形态学识别车辆

import cv2
import numpy as np

# 加载视频
cap = cv2.VideoCapture('video01.mp4')

#创建msg对象
mog=cv2.bgsegm.createBackgroundSubtractorMOG()
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

min_w=110
min_h=100

line_high=550

#偏移量
offset=3

cars=[]

carno=0

#计算外接矩形的中心点
def center(x,y,w,h):
x1=int(w/2)
y1=int(h/2)
cx=int(x)+x1
cy=int(y)+y1
return cx,cy

# 循环读取视频
while True:
ret, frame = cap.read()
if ret==True:
#把原始帧进行灰度化,然后去噪
gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#去噪
blur=cv2.GaussianBlur(gray,(1,1),5)
mask=mog.apply(blur)

#腐蚀
erode=cv2.erode(mask,kernel)
#膨胀,把图像还原回来
dilate=cv2.dilate(erode,kernel,iterations=2)

#消除内部的小块
#闭运算
close=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)

#查找轮廓
result,contours,h=cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# result,contours,h=cv2.findContours(erode,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

#画出检测线
cv2.line(frame,(10,line_high),(1200,line_high),(255,255,0),3)

#画出所有检测出来的轮廓
for contour in contours:
#最大外接矩形
(x,y,w,h)=cv2.boundingRect(contour)
#通过外接矩形的大小来过滤小框
is_valid=(w>=min_w)&(h>=min_h)
if not is_valid:
continue
#获取符合要求的矩形,正常的车
#要求坐标点都是整数
cv2.rectangle(frame,(int(x),int(y)),(int(x+w),int(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)&y<(line_high+offset):
#落入有效区间,计数+!
carno+=1
cars.remove((x,y))
print(carno)

#如何划线,画在哪儿
#如何计数

# cv2.imshow('video',erode)
# cv2.imshow('dialte',dilate)
# cv2.imshow('close',close)
cv2.putText(frame,'Vehicle Count:'+str(carno),(100,60),cv2.FONT_HERSHEY_SIMPLEX,2,(0,0,255),5)
cv2.imshow('frame',frame)

# 用户按ESC退出
key = cv2.waitKey(1)
if key == 27:
break

# 释放视频资源
cap.release()
cv2.destroyAllWindows()

结果如图2所示:


10.2-形态学识别车辆

PS:由于截取的车流视频可能是手动拍摄,有抖动,造成单台车重复计数,若选择固定摄像头的视频源,效果更好。

赞(0)
未经允许不得转载:171主机测评 » 【OpenCV】(十)车辆统计项目
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址