【OpenCV实战】 视频车辆统计
项目总体分为四大步:
- 加载视频
- 车辆识别
- 车辆统计
- 信息显示
1. 加载视频
import cv2
import numpy as np
# 读取视频
cap = cv2.VideoCapture('video/cars.mp4')
while True:
# 读取帧
ret, frame = cap.read()
if (ret == True):
cv2.imshow('video', frame)
else:
break
key = cv2.waitKey(1)
if (key == 27):
break
cap.release()
cv2.destroyAllWindows()
2. 车辆识别
形态学处理
import cv2
import numpy as np
# 读取视频
cap = cv2.VideoCapture('video/cars.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)
# 去噪
blur = cv2.GaussianBlur(frame, (3, 3), 5)
# 去背影
mask = bgsubmog.apply(blur)
# 腐蚀 去掉小方块
erode = cv2.erode(mask, kernel)
# 膨胀 还原放大
dilate = cv2.dilate(erode, kernel, iterations=3)
# 闭操作 去掉物体内部方块
close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
#
cnts, h = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for (i, c) in enumerate(cnts):
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
cv2.imshow('video', mask)
cv2.imshow('erode', close)
else:
print("Error")
break
key = cv2.waitKey(1)
if (key == 27):
break
cap.release()
cv2.destroyAllWindows()
3. 车辆统计
最小合法车宽高和检测线高度根据实际情况需要调整。
import cv2
import numpy as np
# 最小合法车宽高
min_w = 50
min_h = 60
# 检测线高度
line_high = 600
# 存放有效车辆数组
cars = []
# 线的偏移量
offset = 6
# 统计车的数量
carno = 0
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('video/cars.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)
# 去噪
blur = cv2.GaussianBlur(frame, (3, 3), 5)
# 去背影
mask = bgsubmog.apply(blur)
# 腐蚀 去掉小方块
erode = cv2.erode(mask, kernel)
# 膨胀 还原放大
dilate = cv2.dilate(erode, kernel, iterations=3)
# 闭操作 去掉物体内部方块
close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
#
cnts, h = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制检测线
cv2.line(frame, (10, line_high), (1200, line_high), (255, 255, 0), 3)
for (i, c) in enumerate(cnts):
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
# 对车辆的宽高进行判断
# 以验证是否是有效车辆
isValid = (w >= min_w) and (h >= min_h)
if (not isValid):
continue
# 到这里都是有效车
cpoint = center(x, y, w, h)
cars.append(cpoint)
for (x, y) in cars:
if ((y > line_high - offset) and (y < line_high + offset)):
carno += 1
cars.remove((x, y))
print(carno)
cv2.imshow('video', frame)
else:
print("Error")
break
key = cv2.waitKey(1)
if (key == 27):
break
cap.release()
cv2.destroyAllWindows()
4. 显示信息(完整代码)
这部分我根据视频的实际情况,对形态学操作做了一些调整。
但识别效果仍然不是太好,还需要进一步调整。

import cv2
import numpy as np
# 最小合法车宽高
min_w = 50
min_h = 60
# 检测线高度
line_high = 600
# 存放有效车辆数组
cars = []
# 线的偏移量
offset = 6
# 统计车的数量
carno = 0
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('video/cars.mp4')
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()
#
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
while True:
# 读取帧
ret, frame = cap.read()
if (ret == True):
# 灰度
cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 去噪
blur = cv2.GaussianBlur(frame, (5, 5), 5)
# 去背影
mask = bgsubmog.apply(blur)
# 膨胀 还原放大
dilate = cv2.dilate(mask , kernel, iterations=5)
# 腐蚀 去掉小方块
erode = cv2.erode(dilate, kernel, iterations=3)
# 闭操作 去掉物体内部方块
close = cv2.morphologyEx(erode, cv2.MORPH_CLOSE, kernel, iterations=6)
#
cnts, h = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制检测线
cv2.line(frame, (10, line_high), (1200, line_high), (255, 255, 0), 3)
for (i, c) in enumerate(cnts):
(x, y, w, h) = cv2.boundingRect(c)
# 对车辆的宽高进行判断
# 以验证是否是有效车辆
isValid = (w >= min_w) and (h >= min_h)
if (not isValid):
continue
# 到这里都是有效车
cpoint = center(x, y, w, h)
cars.append(cpoint)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
for (x, y) in cars:
if ((y > line_high - offset) and (y < line_high + offset)):
carno += 1
cars.remove((x, y))
print(carno)
cv2.putText(frame, "Cars Count:" + str(carno), (500, 60), cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, 2, (255, 0, 0), 5)
cv2.imshow('video', frame)
cv2.imshow('1', close)
else:
print("Error")
break
key = cv2.waitKey(1)
if (key == 27):
break
cap.release()
cv2.destroyAllWindows()
浙公网安备 33010602011771号