Python中调用OpenCV接口中的高斯混合模型,实现对运动目标的检测,并保存录制视频
Python中调用OpenCV接口中的高斯混合模型(GMM),实现对运动目标的检测
import numpy as np
import cv2
# TODO: 本代码使用OpenCV接口中的高斯混合模型,实现对运动目标的检测
cap = cv2.VideoCapture(0) # 打开摄像头
# cap = cv2.VideoCapture("demo.avi")
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
# cap = cv2.VideoCapture("surveillance_demo\\demo.mp4")
mog = cv2.createBackgroundSubtractorMOG2() # 定义高斯混合模型对象 mog
fourcc1 = cv2.VideoWriter_fourcc(*'XVID')
fourcc2 = cv2.VideoWriter_fourcc(*'XVID')
out_detect = cv2.VideoWriter('output_detect.avi', fourcc1, 20.0, size)
out_bg = cv2.VideoWriter('output_bg.avi', fourcc1, 20.0, size)
i = 0
while(1): # 摄像头正常,进入循环体,读取摄像头每一帧图像
ret, frame = cap.read() # 读取摄像头每一帧图像,frame是这一帧的图像
print(frame.shape)
fgmask = mog.apply(frame) # 使用前面定义的高斯混合模型对象 mog 当前帧的运动目标检测,返回二值图像
gray_frame = fgmask.copy()
# 使用 findContours 检测图像轮廓框,具体原理有论文,但不建议阅读。会使用即可。
# 返回值:image,轮廓图像,不常用。 cnts,轮廓的坐标。 hierarchy,各个框之间父子关系,不常用。
image, cnts, hierarchy = cv2.findContours(gray_frame, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 绘制每一个 cnts 框到原始图像 frame 中
for c in cnts:
if cv2.contourArea(c) < 900: # 计算候选框的面积,如果小于1500,跳过当前候选框
continue
(x, y, w, h) = cv2.boundingRect(c) # 根据轮廓c,得到当前最佳矩形框
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2) # 将该矩形框画在当前帧 frame 上
cv2.rectangle(image, (x, y), (x + w, y + h), (255, 255, 255), 2) # 将该矩形框画在当前帧 frame 上
cv2.imshow("contours", frame) # 显示当前帧
cv2.imshow("fgmask", image) # 显示运动前景图像
image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
print(image.shape)
print(frame.shape)
out_detect.write(frame)
out_bg.write(image)
cv2.waitKey(20)
i = i+1
# if cv2.waitKey(int(1000 / 12)) & 0xff == ord("q"): # 可以不用看,这是cv提供的中断机制
# break
cap.release() # 释放候选框
out_detect.release()
out_bg.release()
cv2.destroyAllWindows()
效果图: