提取帧图片,并根据当前时间命名,效果如下:
import cv2
import os
from datetime import datetime, timedelta
root_path = 'D:/2root_data/video/'
files = os.listdir(root_path)
for file in files:
if file.endswith('.mp4'):
video_path = root_path + file
cap = cv2.VideoCapture(video_path)
now = datetime.now()
fps = int(cap.get(cv2.CAP_PROP_FPS))
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
frame_all = cap.get(cv2.CAP_PROP_FRAME_COUNT)
print(f'视频时长:{frame_all/fps/60:.1f} 分钟')
print(f'视频尺寸:{size}')
success, frame = cap.read()
# 视频的当前帧
i = 0
# 帧率
timeF = 60
while success:
if i % timeF == 0:
dt = str(now+timedelta(seconds=i//timeF)).replace(' ', '_').replace('-', '_').replace(':', '_').replace('.', '_')[:-3]
floder = root_path + 'image'
if not os.path.exists(floder):
os.makedirs(floder)
newname = floder + '/' + dt + '.jpg'
cv2.imwrite(newname, frame)
print(f'保存图片:{newname}')
i += 1
# 获取下一帧
success, frame = cap.read()
cap.release()
- 下一步改进:根据某几个时间段抽取图片,截取荣耀时刻
注意:如果要抽取的图片数量非常多,print 往往增加很多倍的耗时,严重影响效率
由于我 抽取的图片数量不多 且 电脑配置不高 ,加上print 防止CPU一直占满,以缓解电脑卡死状况
import cv2
import os
import pandas as pd
from datetime import datetime,timedelta
def save2frames(video, start_end_time_list):
video_path = root_path + video
cap = cv2.VideoCapture(video_path)
now = datetime.now()
FPS = int(cap.get(cv2.CAP_PROP_FPS))
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
frame_all = cap.get(cv2.CAP_PROP_FRAME_COUNT)
print(f'视频时长:{frame_all/FPS/60:.1f} 分钟')
print(f'视频尺寸:{size}')
success, frame = cap.read()
i = 0 #一个视频里的第几帧
index = 0 #第几组起始时间
timeF = 60 # 帧率
ID, start_time, end_time = start_end_time_list[index]
while success:
if i >= start_time * FPS:
if i % timeF == 0:
dt = str(now+timedelta(seconds=i//timeF)).replace(' ', '_').replace('-', '_').replace(':', '_').replace('.', '_')[:-3]
floder = root_path + 'image'
if not os.path.exists(floder):
os.makedirs(floder)
newname = floder + '/' + dt + '_' + str(index) +'.jpg'
cv2.imwrite(newname, frame)
success, frame = cap.read() #获取下一帧
i +=1
# 加上print() 输出图片会变慢,但是CPU占用没有那么高
print(start_time * FPS, (end_time + 1) * FPS, i)
if i == (end_time + 1) * FPS:
index += 1
if index == len(start_end_time_list):
break
ID, start_time, end_time = start_end_time_list[index]
cap.release()
def get_seconds(time):
h, m, s = [int(t) for t in time.split(':')]
return h*60*60 + m*60 + s
if __name__ == "__main__":
# 如果读取csv,格式都为字符串 则不用astype进行转换
# df = pd.read_csv('C:/Users/Desktop/test.csv', encoding='gb18030')
df = pd.ExcelFile('C:/Users/Desktop/test.xlsx').parse()
root_path = 'D:/2root_data/video/'
files = os.listdir(root_path)
for video, group in df.groupby('视频名称'):
start_end_time_list = sorted(list(zip(list(group['ID']),
[get_seconds(i)for i in list(group['开始时间'].astype('str'))],
[get_seconds(i)for i in list(group['结束时间'].astype('str'))])), key=lambda y: y)
print(start_end_time_list)
save2frames(video, start_end_time_list)