涉及到的内容
- 窗口的展示
- 图像/视频的加载
- 基本图像的绘制
- 车辆识别
- 基本图像运算与处理
- 形态学
- 轮廓查找
整体流程
- 加载视频
- 通过形态学识别车辆
- 对车辆进行统计
- 显示车辆统计信息
#加载视频
import cv2
import numpy as np
cap = cv2.VideoCapture('./20220628.mp4')
#循环读取视频
while True:
ret,frame = cap.read()
if ret == True:
cv2.imshow('video',frame)
key = cv2.waitKey(30)
#按esc退出
if key == 27:
break
#释放资源
cap.release()
cv2.destroyAllWindows()
视频效果图:
# BackgroundSubtractorMOG
# 这是一个以混合高斯模型为基础的前景/背景分割算法
# cv2.bgsegm.createBcakgroundSubtractorMOG()
#去除背景示例
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
#创建mog对象
mog = cv2.bgsegm.createBackgroundSubtractorMOG()
#循环读取视频
while True:
ret,frame = cap.read()
if ret == True:
fgmask = mog.apply(frame)
cv2.imshow('video',fgmask)
key = cv2.waitKey(30)
#按esc退出
if key == 27:
break
#释放资源
cap.release()
cv2.destroyAllWindows()
完整代码:
import cv2
import numpy as np
cap = cv2.VideoCapture('./20220628.mp4')
#创建mog对象
mog = cv2.bgsegm.createBackgroundSubtractorMOG()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
#阈值
min_w = 20
min_h = 8
#划线
line_length=700
#计数的范围
offest = 9
cars = []
c_num=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,(3,3),5)
mask = mog.apply(blur)
# #腐蚀
# erode = cv2.erode(mask,kernel)
# #膨胀
# dilate = cv2.dilate(erode,kernel,iterations=2)
# #消除方块-闭运算
# dst = cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel,iterations=1)
# cv2.imshow('video',dilate)
#膨胀
dilate = cv2.dilate(mask,kernel,iterations=2)
#腐蚀
erode = cv2.erode(dilate,kernel,iterations=2)
#消除方块-闭运算
dst = cv2.morphologyEx(erode,cv2.MORPH_CLOSE,kernel,iterations=2)
#查找轮廓
contours,hierarchy = cv2.findContours(dst,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#画出检测线
cv2.line(frame,(line_length,0),(line_length,740),(255,255,0),2)
#画出所有检测出来的轮廓
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,(x,y),(x + w,y + h),(0,0,255),2)#图片,起始点,结束点,颜色,线宽
#把车抽象为点,用点与线的距离来计算数量
point = center(x,y,w,h)
#保存车辆信息
cars.append(point)
cv2.circle(frame,(point),3,(0,255,0),-1)
#判断车辆是否过线
for (x,y) in cars:
if x > (line_length-offest) and x < (line_length+offest):
#进入有效范围
#数量+1
c_num+=1
#去除识别过的车辆
cars.remove((x,y))
print(c_num)
cv2.putText(frame,'Vehicle Count:'+str(c_num),(10,30),cv2.FONT_HERSHEY_COMPLEX,1,(250,20,240),1)
cv2.imshow('video',frame)
key = cv2.waitKey(50)
#按esc退出
if key == 27:
break
#释放资源
cap.release()
cv2.destroyAllWindows()
效果: