我目前正在尝试读取正在写入的视频的帧。
首先,这有可能吗? 我尝试了如下所示的代码。显示了两个输出示例,一个示例是我尝试实时阅读的内容,另一个示例是我随后阅读的内容。帧计数器比第一种情况要低得多,因此可以肯定的是,它现在不起作用,但是我对其他方法没有想法。
如果任何人都可以通过确认是否可行或者有关于如何实现这一目标的想法来提供帮助,那将很棒。
import cv2
import time
videoPath = r'C:\Users\Me\Desktop\Video.ts'
cap = cv2.VideoCapture(videoPath)
totalCount = 0
frameCount = 0
idleTimer = 0
while(cap.isOpened()):
ret, frame = cap.read()
# if ret is False this is the current end of the video
if (ret is False):
idleTimer += 10
# Show how many frames were read since last idle time, and total frames read
totalCount += frameCount
print ('Read ' + str(frameCount) + ' frames. Total frames: ' + str(totalCount))
# Reset current frame count
frameCount = 0
# Wait 10 seconds (for the video file to grow)
time.sleep(10)
else:
idleTimer = 0
frameCount += 1
# If idle 3x in a row, assume video is no longer being written to
if (idleTimer >= 30):
cap.release()
在录制过程中在视频上运行此代码可获得:
Read 169 frames. Total frames: 169
Read 257 frames. Total frames: 426
Read 0 frames. Total frames: 426
Read 251 frames. Total frames: 677
Read 29 frames. Total frames: 706
Read 2 frames. Total frames: 708
Read 73 frames. Total frames: 781
Read 1 frames. Total frames: 782
Read 57 frames. Total frames: 839
Read 1 frames. Total frames: 840
Read 55 frames. Total frames: 895
Read 1 frames. Total frames: 896
Read 38 frames. Total frames: 934
Read 0 frames. Total frames: 934
Read 251 frames. Total frames: 1185
Read 8 frames. Total frames: 1193
Read 152 frames. Total frames: 1345
Read 0 frames. Total frames: 1345
Read 0 frames. Total frames: 1345
但是在录制完成后运行:
Read 4354 frames. Total frames: 4354
Read 0 frames. Total frames: 4354
Read 0 frames. Total frames: 4354
非常感谢。
编辑:我对此做了一些额外的测试-我的代码现在将处理后的帧记录到一个新的视频中,因此我可以比较处理过的帧和未处理的帧。
if (cap.isOpened()):
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
fps = int(cap.get(cv2.CAP_PROP_FPS))
out = cv2.VideoWriter(r"C:\Users\Me\Desktop\Video_copy.avi", cv2.VideoWriter_fourcc('M','J','P','G'), fps, (width, height))
while(cap.isOpened()):
ret, frame = cap.read()
# if ret is False this is the current end of the video
if (ret is False):
idleTimer += 10
# Show how many frames were read since last idle time, and total frames read
totalCount += frameCount
print ('Read ' + str(frameCount) + ' frames. Total frames: ' + str(totalCount) + '. CAP_PROP_FRAME_COUNT: ' + str(cap.get(cv2.CAP_PROP_FRAME_COUNT)))
print ('Idling...')
# Reset current frame count
frameCount = 0
time.sleep(10)
else:
#Write this frame to new video
out.write(frame)
idleTimer = 0
frameCount += 1
# If idle 3x in a row, assume video is no longer being written to
if (idleTimer >= 30):
cap.release()
out.release()
print ('Video has been released.')
如果我在刚刚录制的视频上运行它,输出将如下所示:
Read 1197 frames. Total frames: 1197. CAP_PROP_FRAME_COUNT: 911.0
Read 115 frames. Total frames: 1312. CAP_PROP_FRAME_COUNT: 911.0
Read 169 frames. Total frames: 1481. CAP_PROP_FRAME_COUNT: 911.0
Read 291 frames. Total frames: 1772. CAP_PROP_FRAME_COUNT: 911.0
Read 138 frames. Total frames: 1910. CAP_PROP_FRAME_COUNT: 911.0
Read 142 frames. Total frames: 2052. CAP_PROP_FRAME_COUNT: 911.0
Read 152 frames. Total frames: 2204. CAP_PROP_FRAME_COUNT: 911.0
Read 186 frames. Total frames: 2390. CAP_PROP_FRAME_COUNT: 911.0
Read 358 frames. Total frames: 2748. CAP_PROP_FRAME_COUNT: 911.0
Read 124 frames. Total frames: 2872. CAP_PROP_FRAME_COUNT: 911.0
Read 329 frames. Total frames: 3201. CAP_PROP_FRAME_COUNT: 911.0
Read 0 frames. Total frames: 3201. CAP_PROP_FRAME_COUNT: 911.0
Read 0 frames. Total frames: 3201. CAP_PROP_FRAME_COUNT: 911.0
Video has been released.
这里有一个有趣的行为:cap.get(cv2.CAP_PROP_FRAME_COUNT)
不会在整个执行过程中改变其值,即使视频的大小明显增加了。另外,从第一次迭代开始,它返回的值要小于已处理的帧数。
在录制完成后运行相同的代码,现在所有数字都匹配。
Read 4349 frames. Total frames: 4349. CAP_PROP_FRAME_COUNT: 4349.0
Read 0 frames. Total frames: 4349. CAP_PROP_FRAME_COUNT: 4349.0
Read 0 frames. Total frames: 4349. CAP_PROP_FRAME_COUNT: 4349.0
Video has been released.
另外,播放我正在录制的Video_copy
时,我可以确认每等待10秒就会得到新帧,但是里面有空洞(如预期的那样,因为我的实时执行处理了3201和后期执行处理了4349帧)。
答案 0 :(得分:0)
我找到了解决我特定问题的方法,如下所示。
关键是重新加载VideoCapture
对象。我正在处理长达3分钟的视频(目前),连续cv2.VideoCapture()
的调用似乎并不需要花费更多的时间-我认为它只是创建了对视频的引用,因此相当轻巧。
if (cap.isOpened()):
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
fps = int(cap.get(cv2.CAP_PROP_FPS))
out = cv2.VideoWriter(r"C:\Users\Me\Desktop\Video_copy.avi", cv2.VideoWriter_fourcc('M','J','P','G'), fps, (width, height))
while(cap.isOpened()):
ret, frame = cap.read()
# If ret is False this is the current end of the video
if (ret is False):
cap.release()
out.release()
print ('Video has been released.')
# If not, let's record this new frame
else:
#Write this frame to new video
out.write(frame)
frameCount += 1
# If I'm 3 frames away from the end, try to reload the video
# 3 is an arbitrary number (I want it to try to get more frames at least 3 times
# before deciding that the video is indeed over and releasing
# If the video grew in size in the last 10 seconds, this will get the new frames
# For some reason this wouldn't work if I let it go all the way to the end
if (frameCount > (cap.get(cv2.CAP_PROP_FRAME_COUNT) - 3)):
time.sleep(10)
cap = cv2.VideoCapture(path)
# Jump to the frame I just processed, to avoid re-reading the whole video
cap.set(cv2.CAP_PROP_POS_FRAMES, frameCount - 1)
希望这可能对某人有所帮助。