我的 python 代码没有将视频帧保存为图像
My python code doesn't save video frames as images
我正在尝试抓取视频中的特定帧(例如第 0、10、20 帧...)并使用 Python 和 CV2 将它们保存为图像。由于某些原因,我的代码只保存了第一帧。创建所有其他帧,但大小为 0(它们已损坏)。
我该如何解决这个问题?
import cv2
from numpy import integer
number = 10;
filename = "18s.mp4";
def uniform():
cap = cv2.VideoCapture(filename);
frame_count= int(cap.get(cv2.CAP_PROP_FRAME_COUNT));
print(frame_count)
for x in range(0, number):
frame_no = 1*(x/number)
frame_no_int=int(frame_no*frame_count)
cap.set(2,frame_no);
ret, frame = cap.read()
cv2.imwrite(filename+'_frame_'+str(frame_no_int)+'.jpg', frame);
# When everything done, release the capture
cap.release()
if __name__ == '__main__':
uniform()
显然,CAP_PROP_POS_AVI_RATIO
(您在 cap.set()
中使用的常量 2)效果不佳。查看修改后的脚本的输出:
import cv2
from numpy import integer
number = 10
filename = 'chaplin.mp4'
def uniform():
cap = cv2.VideoCapture(filename)
frame_count= int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print(frame_count)
for x in range(0, number):
frame_pos_ratio = 1.0*x/number
frame_no_int=int(frame_pos_ratio*frame_count)
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_no_int)
print (frame_no_int, cap.get(cv2.CAP_PROP_POS_AVI_RATIO))
ret, frame = cap.read()
cv2.imwrite('_frame_'+str(frame_no_int)+'.jpg', frame)
# Attempt to go the end of film
cap.set(cv2.CAP_PROP_POS_AVI_RATIO, 1)
print (cap.get(cv2.CAP_PROP_POS_FRAMES))
# When everything done, release the capture
cap.release()
if __name__ == '__main__':
uniform()
输出:
172
(0, 6.510416666666667e-05)
(17, 6.510416666666667e-05)
(34, 6.510416666666667e-05)
(51, 6.510416666666667e-05)
(68, 6.510416666666667e-05)
(86, 6.510416666666667e-05)
(103, 6.510416666666667e-05)
(120, 6.510416666666667e-05)
(137, 6.510416666666667e-05)
(154, 6.510416666666667e-05)
150.0
如您所见,cap.get(cv2.CAP_PROP_POS_AVI_RATIO)
在循环中只是 returns 一个常量 6.51e-05
。
尽管有 174 帧,cap.set(cv2.CAP_PROP_POS_AVI_RATIO, 1)
只带你到第 150 帧,这绝对是一个错误。
此行为符合 this question。
P.S。有趣的是,甚至 cv2.CAP_PROP_FRAME_COUNT
也不能正常工作。显然,我的视频文件只包含 150 帧,但它们的编号是从 22 到 171,ffprobe -show_frames chaplin.mp4 | grep coded_picture_number
证明了这一点。所以 CAP_PROP_FRAME_COUNT 的输出就是 max(frame_no)+1.
我正在尝试抓取视频中的特定帧(例如第 0、10、20 帧...)并使用 Python 和 CV2 将它们保存为图像。由于某些原因,我的代码只保存了第一帧。创建所有其他帧,但大小为 0(它们已损坏)。
我该如何解决这个问题?
import cv2
from numpy import integer
number = 10;
filename = "18s.mp4";
def uniform():
cap = cv2.VideoCapture(filename);
frame_count= int(cap.get(cv2.CAP_PROP_FRAME_COUNT));
print(frame_count)
for x in range(0, number):
frame_no = 1*(x/number)
frame_no_int=int(frame_no*frame_count)
cap.set(2,frame_no);
ret, frame = cap.read()
cv2.imwrite(filename+'_frame_'+str(frame_no_int)+'.jpg', frame);
# When everything done, release the capture
cap.release()
if __name__ == '__main__':
uniform()
显然,CAP_PROP_POS_AVI_RATIO
(您在 cap.set()
中使用的常量 2)效果不佳。查看修改后的脚本的输出:
import cv2
from numpy import integer
number = 10
filename = 'chaplin.mp4'
def uniform():
cap = cv2.VideoCapture(filename)
frame_count= int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print(frame_count)
for x in range(0, number):
frame_pos_ratio = 1.0*x/number
frame_no_int=int(frame_pos_ratio*frame_count)
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_no_int)
print (frame_no_int, cap.get(cv2.CAP_PROP_POS_AVI_RATIO))
ret, frame = cap.read()
cv2.imwrite('_frame_'+str(frame_no_int)+'.jpg', frame)
# Attempt to go the end of film
cap.set(cv2.CAP_PROP_POS_AVI_RATIO, 1)
print (cap.get(cv2.CAP_PROP_POS_FRAMES))
# When everything done, release the capture
cap.release()
if __name__ == '__main__':
uniform()
输出:
172
(0, 6.510416666666667e-05)
(17, 6.510416666666667e-05)
(34, 6.510416666666667e-05)
(51, 6.510416666666667e-05)
(68, 6.510416666666667e-05)
(86, 6.510416666666667e-05)
(103, 6.510416666666667e-05)
(120, 6.510416666666667e-05)
(137, 6.510416666666667e-05)
(154, 6.510416666666667e-05)
150.0
如您所见,cap.get(cv2.CAP_PROP_POS_AVI_RATIO)
在循环中只是 returns 一个常量 6.51e-05
。
尽管有 174 帧,cap.set(cv2.CAP_PROP_POS_AVI_RATIO, 1)
只带你到第 150 帧,这绝对是一个错误。
此行为符合 this question。
P.S。有趣的是,甚至 cv2.CAP_PROP_FRAME_COUNT
也不能正常工作。显然,我的视频文件只包含 150 帧,但它们的编号是从 22 到 171,ffprobe -show_frames chaplin.mp4 | grep coded_picture_number
证明了这一点。所以 CAP_PROP_FRAME_COUNT 的输出就是 max(frame_no)+1.