相信很多人在学习opencv都会需要一个巩固练手的项目,而今天分享的车辆计数就是一个不错的选择。
效果如图所示:
代码如下:
代码运行时,按s键可保存当前帧率图像,按Esc键可退出程序。
python前置环境条件如下:
pip install numpy matplotlib opencv_python
import cv2
path='./car.mp4'
min_w,min_h=90,90
# 检测线高度
line_height=500
#线偏移量
offset=6
#car数量
carno=0
cars = []
#获取视频
cap=cv2.VideoCapture(path)
# cv2.resizeWindow('video', 900, 600)#重新设置窗口为指定大小
bgsubmog=cv2.bgsegm.createBackgroundSubtractorMOG()
def get_center(x,y,w,h):
return x+0.5*w,y+0.5*h
while True:
#形态学kernel
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
ret, frame = cap.read()
if ret==True:
#gray
cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
# print(frame.shape)#(1080, 1920, 3)
#高斯 去噪
blur=cv2.GaussianBlur(frame,(3,3),5)
blur=cv2.GaussianBlur(blur,(3,3),5)
#去背影
mask=bgsubmog.apply(blur)
#腐蚀
erode=cv2.erode(mask,kernel)
#膨胀
dilate=cv2.dilate(erode,kernel,iterations=2)
#闭操作,去掉物体内部小块
close=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
close=cv2.morphologyEx(close,cv2.MORPH_CLOSE,kernel)
close=cv2.morphologyEx(close,cv2.MORPH_CLOSE,kernel)
#查找轮廓
cnts,h=cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#检测线
cv2.line(frame,(10,line_height),(1800,line_height),(0,255,0),2)
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
#有效车辆
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 5, 255), 2)
cpoint=get_center(x,y,w,h)
cars.append(cpoint)
for (x,y) in cars:
if(y>line_height-offset) and (y<line_height+offset):
carno+=1
cars.remove((x,y))
print('-------当前car统计数量--------',carno)
cv2.putText(frame,f'car count : {carno}',(60,300),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,255))
cv2.imshow('erode video',frame)
key=cv2.waitKey(1) #1ms取一帧
if(key&0xFF==27 or key&0xFF==ord('q')):
break
elif (key & 0xFF == ord('s')):
cv2.imwrite("./car.png", frame) # 保存图片
#释放VideoCapture
cap.release()
cv2.destroyAllWindows() #销毁窗口
虽然基于opencv的车辆计数能够在一定程度上取得不错的表现,但是仍然有许多不足之处。这就要考虑通过深度学习来实现车辆的检测,下一篇blog为大家分享基于yolo系列的目标检测。