我正在尝试使用阈值标准从OpenCV写出视频帧来指定要写出的帧。
我通过比较帧间像素强度来生成运动索引,并且旨在自动移动运动索引小于定义阈值的视频片段(当视频中的人不移动时)。
不幸的是,当我绘制动作索引时,我看到以下内容: (图1:根据帧编号绘制运动索引轨迹,用户定义的段覆盖(橙色),后续阈值绘制为水平线 - 阈值定义为用户定义区域的平均值加上标准偏差的3倍。)
正如我的情节所证明的那样,高速运动指数值的周期经常会低于我的阈值,然后再次快速上升。我的代码目前就是这样,当我希望它们被包含时,它不会将这些子阈值帧写入文件。我想要做的是定义图形的区域,其中运动指数持续高于或低于阈值,连续任意数量的帧 - 即我只想写出视频运动发生在阈值以上持续一段时间的帧,而不写入运动指标轨迹低于阈值的区域。
目前,我的代码仅在循环中将一个帧与下一个帧进行比较以生成运动索引值列表,因此将多个帧进行比较以查看是否存在一组持续的高于阈值的值是不可能的。有没有人知道如何解决这个问题?
我很欣赏这可能有点令人困惑 - 如果需要澄清,请告诉我。
提前致谢!
import cv2
import tkinter as tk
from tkinter.filedialog import askopenfilename
import numpy as np
import os
import matplotlib.pyplot as plt
MIList =[]
root = tk.Tk()
root.withdraw()
selectedvideo = askopenfilename()
cap = cv2.VideoCapture(selectedvideo)
length = cap.get(cv2.CAP_PROP_FRAME_COUNT)
intlength = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
currentframenumber = cap.get(cv2.CAP_PROP_POS_FRAMES)
intcurrentframenumber = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
scaling_factor = 1
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter((selectedvideo + 'motionindexed.avi'),fourcc, 60.0, (640,478), isColor=False)
with open((selectedvideo + 'threshold' + '.txt'), 'r') as readthreshold:
threshold = float(readthreshold.readline())
def frame_diff(prev_frame, cur_frame, next_frame):
diff_frames1 = cv2.absdiff(next_frame, cur_frame)
diff_frames2 = cv2.absdiff(cur_frame, prev_frame)
return cv2.bitwise_and(diff_frames1, diff_frames2)
def get_frame(cap):
ret, frame = cap.read()
if ret == True:
scaling_factor = 1
frame = cv2.resize(frame, None, fx = scaling_factor, fy = scaling_factor, interpolation = cv2.INTER_AREA)
return cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
if __name__ == '__main__':
prev_frame = get_frame(cap)
cur_frame = get_frame(cap)
next_frame = get_frame(cap)
while (cap.isOpened()):
try:
cv2.imshow("Object Movement", frame_diff(prev_frame, cur_frame, next_frame))
prev_frame = cur_frame
cur_frame = next_frame
next_frame = get_frame(cap)
differencesquared = (next_frame-cur_frame)**2
interframedifference = np.sum(differencesquared)
MIList.append(interframedifference)
print(interframedifference)
if interframedifference > threshold:
out.write(cur_frame)
key = cv2.waitKey(1)
if key == ord('q'):
break
except:
break
cap.release()
cv2.destroyAllWindows()