通过前景的提取进行车辆的框选并且通过框选的中心位置对车辆进行判断
能够实现该视频中的车辆,进行运动检测
基于opencv下的python
import cv2
import numpy as np
"""
可以进行优化的参数:
kernal=进行二值化的腐蚀的内核大小和形状
kernal2=进行开闭操作的内核大小和形状
"""
bs = cv2.createBackgroundSubtractorKNN(detectShadows=True)#KNN算法背景提取,打开阴影检测
#发现并未能较好去除阴影,可以优化,上升到论文层次
camera = cv2.VideoCapture("源视频0.avi") #读取视频
# camera = cv2.VideoCapture("2.wmv")
kernal=cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))#制作执行算子核,椭圆形,3x3大小
kernal2=cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
# def get_s_pic(image): #没用的函数
# hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# h, s, v = cv2.split(hsv)
# return s
def mark_road(image): #通过填充遮挡非路面部分
points2 = np.array([[180, 0], [320, 0], [320, 120]], np.int32)
points1= np.array([[0, 0], [0, 130], [130, 0]], np.int32)
cv2.polylines(image, [points1], True, (255, 0, 0), 1, 8)
cv2.polylines(image, [points2], True, (255, 0, 0), 1, 8)
cv2.fillPoly(image,[points1],(0, 0, 0),1)
cv2.fillPoly(image,[points2],(0, 0, 0),1)
def mark_line(image):#标记双黄线部分
points=np.array([[154,20],[150,240],[180,240],[160,20]],np.int32)
cv2.polylines(image,[points],True,(255,0,0),1,8)
def del_shadow(image):#用于防止车辆阴影遮挡双黄线
points = np.array([[154, 20], [150, 240], [180, 240], [160, 20]], np.int32)
cv2.fillPoly(image, [points], (0, 0, 0), 1)
while True:#循环处理每一帧画面
ret, init_pic = camera.read()#获取一帧画面
# s_pic=get_s_pic(init_pic)
frame = cv2.GaussianBlur(init_pic, (5, 5), 0)#画面模糊
fgmask = bs.apply(init_pic)#进行KNN学习的差分背景提取
mark_road(fgmask)#遮挡非路面部分
# del_shadow(fgmask)
ret, th = cv2.threshold(fgmask, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) #图像二值化,转换成黑白图
# ret,th = cv2.threshold(fgmask,250, 255, cv2.THRESH_BINARY)
th = cv2.erode(th, kernel=kernal, iterations=1) #图像腐蚀,去除小块的白色噪声
dilated = cv2.dilate(th, kernel=kernal2, iterations=2) #图像膨胀,填充边缘的部分,操作两次
openaction=cv2.morphologyEx(dilated,cv2.MORPH_OPEN,kernal2,iterations=1) #开操作,去除图像轮廓外的噪声
closeaction=cv2.morphologyEx(openaction,cv2.MORPH_CLOSE,kernal2,iterations=2) #闭操作,填补轮廓内的小黑洞,操作两次
contours, hier = cv2.findContours(closeaction, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)#对矩形把轮廓框柱住
for c in contours:#对每一个矩形进行判断
if (cv2.contourArea(c) > 200)&(cv2.contourArea(c)<5000): #计算矩形的面积,在200到5000之内
(x, y, w, h) = cv2.boundingRect(c)#获取方框的信息,方框画的起点,以及长宽
# w-=int(h*0.7) #通过阴影的长度进行简单粗暴的转换
cv2.rectangle(init_pic, (x, y), (x + w, y + h), (255, 255, 0), 1)#画青色方框
if ((x+w/2)>150)&((x+w/2)<160):#判断方框中心位置是否在双黄线范围内
cv2.rectangle(init_pic, (x, y), (x + w, y + h), (0, 0, 255), 2)#画红色方框
mark_line(init_pic)#标记双黄线范围
cv2.imshow("mog", fgmask)
cv2.imshow("thresh", closeaction)
# cv2.imshow("diff", frame & cv2.cvtColor(fgmask, cv2.COLOR_GRAY2BGR))
cv2.imshow("detection", init_pic)
k = cv2.waitKey(50) & 0xff#等等按键操作
if k == 27:#判断esc是否按下
break
camera.release()#停止播放
cv2.destroyAllWindows()#关闭所有窗口