python批量提取视频帧
python批量提取视频帧,两种提取方式:
- 按帧数提取,每个视频提取固定帧数,若所取帧数超过视频总帧数,则截取视频所有帧
- 按时间间隔提取,每个time提取一帧
1. 使用示例:
python video_set.py -f=frames
python video_set.py -f=20
python video_set.py -t=times
python video_set.py -t=2.5
2. 注意事项
(1)frames是每个视频所截取的帧数,支持整数类型,若所取帧数超过视频总帧数,则截取视频所有帧;times是取帧间隔时间,支持浮点型,可根据需要自行调整,两者同时使用则帧数优先,此脚本采取固定步长进行取帧
(2)在此脚本同级目录,创建两个目录,一个是video目录,用来存放原视频,另一个是img目录,用来存放截取后的视频帧,截取的视频帧存放在img目录下与视频名同名的目录下,图片名为帧数
3. 代码
#!/usr/bin/env python
# coding=utf-8
import os
import cv2
import argparse
import shutil
import math
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--frames', help="set frames", type=int)
parser.add_argument('-t', '--times', help="set times", type=float)
#parser.add_argument('-p', '--path', help="video path", type=str)
args = parser.parse_args()
videos_src_path = r'./video/'
#videos_src_path = args.path
print('now processing videos from {}'.format(videos_src_path))
videos_save_path = r'./img/'
if not os.path.exists(videos_save_path):
os.makedirs(videos_save_path)
file_count = 0
videos = os.listdir(videos_src_path)
for each_video in videos:
file_count += 1
each_video_name = each_video.split('.')[0]
each_video_full_path = os.path.join(videos_src_path, each_video)
img_path = os.path.join(videos_save_path, each_video_name)
if os.path.exists(img_path):
shutil.rmtree(img_path)
os.mkdir(img_path)
cap = cv2.VideoCapture(each_video_full_path)
frames_num = cap.get(7)
rate = cap.get(5)
duration = round(frames_num / rate)
print("video {} is setting\ntime length:{}s".format(each_video_name, duration))
c = 0
j = 0
ret = True
if args.frames:
if frames_num >= args.frames:
numbers = math.floor(frames_num / args.frames)
else:
numbers = 1
print("video {} frames is out of range\nall frames:{}".format(each_video_name, int(frames_num)))
while ret:
ret, frame = cap.read()
if frame is None:
continue
c += 1
if c % numbers == 0:
j += 1
if j <= args.frames:
cv2.imencode('.jpg', frame)[1].tofile(img_path + '/' + '{}.jpg'.format(c))
else:
numbers = int(frames_num/duration*args.times)
while ret:
ret, frame = cap.read()
if frame is None:
continue
c += 1
if c % numbers == 0:
cv2.imencode('.jpg', frame)[1].tofile(img_path + '/' + '{}.jpg'.format(c))
print('\nvideo numbers:', str(file_count), '\nAll is done ,thanks')