视频摘要简介
通过运动目标分析,提取运动目标,然后对各个目标的运动轨迹进行分析,将不同的目标拼接到一个共同的背景场景中,即同时展现在不同时间出现的多个对象。
视频摘要主要运用在对长时间的监控视频的压缩上,节省视频占用的空间,同时可以保留视频中的目标和活动。
一般的视频摘要的步骤可以总结为:
视频读取→背景建模 → 前景提取→ 目标轨迹跟踪→ 目标的时序与空间规划 → 生成浓缩视频
本文主要通过一个简单的去除视频里非运动帧来实现一个简单的视频压缩的功能。
帧间差分法
简单的视频压缩就是想把完全静止不动的视频帧从原视频里删除,我们的兴趣目标一般是在移动的视频里。所以我们可以用帧差法来检测移动物体,它的原理是利用视频中物体的移动将引起相邻视频帧内容的不同,从而显示出移动的前景。
两帧之间的帧差图像可以这样定义:
其中imgCur代表当前帧的图像,imgPre代表前一帧图像。
在得到帧差图像后,我们并不能得到很明显的判断条件,所以我们需要对帧差图像进行二值化,我们设置一个阈值T
然后我们只需遍历图像求出图像中所有白点的个数,即是运动前景的面积,计算一下面积比例即可以确定当前帧是否有物体移动。
# coding=utf-8
# 导入必要的软件包
import cv2
# 视频文件输入初始化
filename = r"C:\Users\Desktop\bgs\video\test1.mp4"
capture = cv2.VideoCapture(filename)
# 视频文件输出参数设置
fps = capture.get(cv2.CAP_PROP_FPS) # fps of video
size = (int(capture.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', '2')
out1 = cv2.VideoWriter('video_diff_v2/test1_v2.avi', fourcc, fps, size)
out2 = cv2.VideoWriter('video_diff/test1_op.avi', fourcc, fps, size)
# 初始化当前帧的前帧
lastFrame = None
# 遍历视频的每一帧
while capture.isOpened():
# 读取下一帧
(ret, frame) = capture.read()
# 如果不能抓取到一帧,说明我们到了视频的结尾
if not ret:
break
# 如果第一帧是None,对其进行初始化
if lastFrame is None:
lastFrame = frame
continue
# 计算当前帧和前帧的不同
frameDelta = cv2.absdiff(lastFrame, frame)
# 当前帧设置为下一帧的前帧
lastFrame = frame.copy()
# 结果转为灰度图
thresh = cv2.cvtColor(frameDelta, cv2.COLOR_BGR2GRAY)
# 图像二值化
_, thresh = cv2.threshold(thresh, 30, 255, cv2.THRESH_BINARY)
area = cv2.sumElems(thresh)[0] / 255
# 设置阈值来过滤非运动帧
if(area > thresh.shape[0] * thresh.shape[1] * 0.1):
# 显示当前帧
# cv2.imshow("frame", frame)
# cv2.imshow("frameDelta", frameDelta)
# thresh = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)
# cv2.imshow("thresh", thresh)
# 保存视频
out1.write(frame)
# out2.write(thresh)
# 如果q键被按下,跳出循环
# if cv2.waitKey(200) & 0xFF == ord('q'):
# break
# 清理资源并关闭打开的窗口
out1.release()
out2.release()
capture.release()
cv2.destroyAllWindows()