超详细的视频抽帧——利用opencv-python
直接上代码
import os
import cv2
def extract_frames(video_path, dst_folder, png_name, index, frame_num):
video = cv2.VideoCapture()
if not video.open(video_path):
print("can not open the video")
exit(1)
count = 0
frames_num = video.get(7)
# step = int(frames_num/frame_num)
step = 4
while True:
_, frame = video.read()
if frame is None:
break
if count % step == 0:
save_path = os.path.join(str(dst_folder), str(png_name)+'-'+'{:0>4d}.png'.format(index))
cv2.imwrite(save_path, frame)
index += 1
count += 1
# if (index==frame_num):
if (index==frames_num):
break
video.release()
def main(VIDEO_PATH, EXTRACT_FLODER, PNG_NAME, FRAME_NUM):
extract_frames(VIDEO_PATH, EXTRACT_FLODER, PNG_NAME, 0, FRAME_NUM)
if __name__ == '__main__':
txt = open('./Index.txt', 'r').readlines()
for class_info in txt:
png_name = class_info.split('.')[0]
sub_id = class_info.split('-', 3)[0]
sts, seq_num = class_info.split('-', 3)[1:3]
sts_seq_num = str(sts) + '-' + str(seq_num)
view_angel = class_info.split('-', 3)[3].split('.')[0]
class_path = './video_frame/' + sub_id +'/' + sts_seq_num + '/' + view_angel +'/'
if not os.path.exists(class_path):
os.makedirs(class_path)
else:
pass
video_path = os.path.join('./video', class_info).strip()
print(video_path)
main(video_path, class_path, png_name, 16)
此代码功能:
对于输入的每一个视频,我们既可以抽取指定数目的帧数(如对输入的每个视频抽取16帧,即代码中main()函数中的参数16),也可以每隔几帧抽取一帧(如代码中extract_frames()函数中的step=4,表示每隔4帧抽出一帧并保存)
各函数详解:
- 首先看看需要导入的包,os是python自带的,而cv2需要大家自行安装(即pip install opencv-python)。
- extract_frames()函数就是抽帧的核心代码,video = cv2.VideoCapture(),video.open(video_path),_, frame = video.read() 表示读取路径为video_path下的视频,并抽帧。step表示每隔step步抽取一帧。save_path表示将抽取的frame保存的路径,cv2.imwrite(save_path, frame)表示将抽取的frame写到该路径下。
- main()函数表示调用前面的extract_frames()函数。
- if name == ‘main’:函数部分表示对于每个视频都调用main()函数。
希望对大家有帮助!