1.项目总览
2. 视频加载
import cv2
import numpy as np
cap=cv2.VideoCapture('video.mp4')
while True:
ret,fram=cap.read()
cv2.imshow('video',fram)
key=cv2.waitKey(100)
if(key==27):
break
cap.release()
cv2.destroyAllWindows()
3. 去背景
opencv–背景减除–BackgroundSubtractorMOG2
createBackgroundSubtractorMOG();
该函数可以使用默认参数,修改最多的是history,值越大计算越准,越耗时;
.apply()
就可以得到前景的掩模了
移动的物体会被标记为白色,背景会被标记为黑色的
前景的掩模就是白色的了
import cv2
import numpy as np
cap=cv2.VideoCapture('video.mp4')
#获取背景,此功能需要安装opencv扩展库
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()
while True:
ret,fram=cap.read()
if(ret==True):
#灰度
cv2.cvtColor(fram,cv2.COLOR_BGRA2GRAY)
#去噪(高斯)
blur=cv2.GaussianBlur(fram,(3,3),5)
#去背景,.apply() 得到前景的掩模了,移动的物体会被标记为白色,背景会被标记为黑色的
mask=bgsubmog.apply(blur)
cv2.imshow('mask',mask)
key=cv2.waitKey(100)
if(key==27):
break
cap.release()
cv2.destroyAllWindows()
高斯滤波去噪
4.形态学处理,轮廓统计
- 腐蚀, 去掉图中小斑块
- 膨胀, 还原放大
- 闭操作, 去掉物体内部小块
import cv2
from cv2 import COLOR_BGRA2GRAY
from cv2 import erode
from cv2 import dilate
from cv2 import CHAIN_APPROX_SIMPLE
import numpy as np
cap=cv2.VideoCapture('video.mp4')
#获取背景,此功能需要安装opencv扩展库
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()
#形态学kernel
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
while True:
ret,fram=cap.read()
if(ret==True):
#灰度
cv2.cvtColor(fram,cv2.COLOR_BGRA2GRAY)
#去噪(高斯)
blur=cv2.GaussianBlur(fram,(3,3),5)
#去背景,.apply() 得到前景的掩模了,移动的物体会被标记为白色,背景会被标记为黑色的
mask=bgsubmog.apply(blur)
#腐蚀,去掉图中小斑块
erode=cv2.erode(mask,kernel)
#膨胀,还原放大
dilate=cv2.dilate(erode,kernel,iterations=3)
#闭操作,去掉物体内部小块
close=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
close=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
cv2.imshow('mask',mask)
cv2.imshow('erode',erode)
cv2.imshow('dilate',dilate)
cv2.imshow('close',close)
key=cv2.waitKey(100)
if(key==27):
break
cap.release()
cv2.destroyAllWindows()
#轮廓查找
contours,hierarchy=cv2.findContours(close,cv2.RETR_TREE,CHAIN_APPROX_SIMPLE)
for (i,c) in enumerate(contours):
(x,y,w,h)=cv2.boundingRect(c)
print(x,x,w,h)
cv2.rectangle(fram,(x,y),(x+w,y+h),(0,0,255),2)
5.逻辑处理
import cv2
import numpy as np
#车辆的最小宽高
min_w=90
min_h=90
#定义线高
line_high=550
#线的偏移量
offset=7
#存放车辆数组
cars=[]
#统计车的数量
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.mp4')
#获取背景,此功能需要安装opencv扩展库
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()
#形态学kernel
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
while True:
ret,fram=cap.read()
if(ret==True):
#灰度
cv2.cvtColor(fram,cv2.COLOR_BGRA2GRAY)
#去噪(高斯)
blur=cv2.GaussianBlur(fram,(3,3),5)
#去背景,.apply() 得到前景的掩模了,移动的物体会被标记为白色,背景会被标记为黑色的
mask=bgsubmog.apply(blur)
#腐蚀,去掉图中小斑块
erode=cv2.erode(mask,kernel)
#膨胀,还原放大
dilate=cv2.dilate(erode,kernel,iterations=3)
#闭操作,去掉物体内部小块
close=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
close=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
#轮廓查找
cnts,h=cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#划一条检测线
cv2.line(fram,(10,line_high),(1200,line_high),(255,225,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
#到这里的是有效的车
cv2.rectangle(fram,(x,y),(x+w,y+h),(0,0,255),2)
#计数方式,计算汽车轮廓中心点,当这个中心点经过指定的那条界限,数量加一
cpoint =center(x,y,w,h)
#print(cpoint)
cars.append(cpoint)
#要有一条线
#偏移范围6,点在线的附近+-6处经过都有效
#从数组中减去
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',fram)
key=cv2.waitKey(1)
if(key==27):
break
cap.release()
cv2.destroyAllWindows()
6 实时显示统计信息
putText函数直接写在内循环,屏幕上打印的text会一闪而过
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(fram,"Cars Contur:"+str(carno),(500,60),fontFace=FONT_HERSHEY_COMPLEX_SMALL,fontScale=2,color=(0,255,0),thickness=5)
6.2 SyntaxError: positional argument follows keyword argument
SyntaxError: positional argument follows keyword argument
出现这个bug的原因在于参数位置不正确,关键字参数必须跟随在位置参数后面! 因为python函数在解析参数时, 是按照顺序来的, 位置参数是必须先满足, 才能考虑其他可变参数.
解决方法1: 出错的位置起,每个变量前面都加上形参的名字
cv2.putText(fram,"Cars Contur:"+str(carno),(500,60),fontFace=FONT_HERSHEY_COMPLEX_SMALL,fontScale=2,color=(0,255,0),thickness=5)
解决方法2: 删掉所有形参的名字
cv2.putText(fram,"Cars Contur:"+str(carno),(500,60),FONT_HERSHEY_COMPLEX_SMALL,2,(0,255,0),5)
7 完整代码
import cv2
from cv2 import FONT_HERSHEY_COMPLEX_SMALL
import numpy as np
#车辆的最小宽高
min_w=100
min_h=90
#定义线高
line_high=550
#线的偏移量
offset=7
#存放车辆数组
cars=[]
#统计车的数量
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.mp4')
#获取背景,此功能需要安装opencv扩展库
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()
#形态学kernel
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
while True:
ret,fram=cap.read()
if(ret==True):
#灰度
cv2.cvtColor(fram,cv2.COLOR_BGRA2GRAY)
#去噪(高斯)
blur=cv2.GaussianBlur(fram,(3,3),5)
#去背景,.apply() 得到前景的掩模了,移动的物体会被标记为白色,背景会被标记为黑色的
mask=bgsubmog.apply(blur)
#腐蚀,去掉图中小斑块
erode=cv2.erode(mask,kernel)
#膨胀,还原放大
dilate=cv2.dilate(erode,kernel,iterations=3)
#闭操作,去掉物体内部小块
close=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
close=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
#轮廓查找
cnts,h=cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#划一条检测线
cv2.line(fram,(10,line_high),(1200,line_high),(255,225,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
#到这里的是有效的车
cv2.rectangle(fram,(x,y),(x+w,y+h),(0,0,255),2)
#计数方式,计算汽车轮廓中心点,当这个中心点经过指定的那条界限,数量加一
cpoint =center(x,y,w,h)
cv2.circle(fram,cpoint,5,(0,0,255),-1)
#print(cpoint)
cars.append(cpoint)
#要有一条线
#偏移范围6,点在线的附近+-6处经过都有效
#从数组中减去
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(fram,"Cars Contur:"+str(carno),(500,60),fontFace=FONT_HERSHEY_COMPLEX_SMALL,fontScale=2,color=(0,255,0),thickness=5)
cv2.putText(fram,"Cars Contur: "+str(carno),(500,60),FONT_HERSHEY_COMPLEX_SMALL,2,(255,0,0),3)
cv2.imshow('video',fram)
key=cv2.waitKey(50)
if(key==27):
break
cap.release()
cv2.destroyAllWindows()
8 传统方法 存在的缺陷
但是仍然存在一下问题,
1.检测线的高低;
2.检测物体的长宽设置;
3.检测线偏移量;
4.以检测框的中心经过检测线作为检测表标准,容易漏记多计;
以上提到的几个事项的参数,都是人为设定的,不够灵活。这是传统算法的缺点,深度学习可以跟踪,从车辆进入视线和离开视线跟踪为一辆车,不会重复,漏计等