使用已有的混合高斯前景检测库函数,实现一段视频中的运动目标检测
根据OpenCV官方提供的样例代码所写
createBackgroundSubtractorMOG2()有3个参数,分别是历史像素对背景像素计算值的影响时间,判断是否为前景点的分割阈值,以及是否检测倒影 仔细阅读类内函数的话发现还能设置混合高斯的元数,像素更新率等其余参数
1.读取文件,设置输出视频格式
import cv2 as cv
import numpy as np
cap = cv.VideoCapture('F:\大学\大三下\数字图像处理\第3章作业 高斯建模与运动目标检测\第3章作业 高斯建模与运动目标检测\pets2006_0.avi')
fourcc = cv.VideoWriter_fourcc(*'MJPG')
fps = cap.get(cv.CAP_PROP_FPS)
print('该视频的帧速率为:',fps)
size =(int(cap.get(cv.CAP_PROP_FRAME_WIDTH)),
int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)))
print('该视频每一帧的大小为:',size)
out1 = cv.VideoWriter('5_Gaussian_mask_normal.avi', fourcc, fps, size,0)
out2 = cv.VideoWriter('5_Gaussian_final_normal.avi', fourcc, fps, size)
#该视频的帧速率为: 30.0
#该视频每一帧的大小为: (320, 240)
调用背景检测函数,并设置参数
检测出前景区域的二值图像之后,使用findContours()寻找边缘 画矩形可以选择画最小外接矩形,还是画能覆盖区域的最小的水平放置的矩形
#背景检测框架
backSub = cv.createBackgroundSubtractorMOG2()
#设置混合高斯模型数
backSub.setNMixtures(5)
backSub.setShadowValue(0)
while cap.isOpened():
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame any more. Exiting ...")
break
#每一帧背景检测都会作为背景检测的输入
fgMask = backSub.apply(frame)
background = backSub.getBackgroundImage()
out1.write(fgMask)
#寻找检测区域
#高斯平滑
blur = cv.GaussianBlur(fgMask,(5,5),0)
contours, hierarchy = cv.findContours(image = blur,mode = cv.RETR_CCOMP,method = cv.CHAIN_APPROX_SIMPLE)
image = frame;
# image = cv.drawContours(image,contours,-1,(255,0,0))
for i in range(0,len(contours)):
# #以下画的是最小外接矩形,可以不是标准的水平放置的矩形框
# rect = cv.minAreaRect(contours[i])
# box = np.int0(cv.boxPoints(rect))
# s = np.square(box[1][0]-box[0][0])+np.square(box[1][1]-box[0][1])\
# +np.square(box[2][0]-box[1][0])+np.square(box[2][1]-box[1][1])
# if s > 500:
# cv.line(image,tuple(box[0]),tuple(box[1]),(255,0,0))
# cv.line(image,tuple(box[1]),tuple(box[2]),(255,0,0))
# cv.line(image,tuple(box[2]),tuple(box[3]),(255,0,0))
# cv.line(image,tuple(box[3]),tuple(box[0]),(255,0,0))
#以下画的是标准水平放置的矩形框
x, y, w, h = cv.boundingRect(contours[i])
s = w*h
if s > 500:
cv.rectangle(image, (x,y), (x+w,y+h), (255,0,0))
out2.write(image)
if cv.waitKey(1) == ord('q'):
break
#Can't receive frame any more. Exiting ...
输出背景图像,并释放资源
cv.imwrite('BackGround.png',background)
cap.release()
out1.release()
out2.release()
cv.destroyAllWindows()
背景检测结果如下
运动目标检测结果截图