python视频转图片

使用opencv,遍历用户输入文件夹及其子文件夹的所有指定类型视频文件,读取每一帧并保存到另外的指定文件夹中。
转换过程中对文件后缀名进行了简单检查。
先看效果。
在这里插入图片描述

#!/usr/bin/env python
# -*- coding:utf-8 -*-
###
# File: /Users/simonliu/Documents/python/video2jpg/video_to_jpg.py
# Project: /Users/simonliu/Documents/python
# Created Date: 2022-05-07 18:23:39
# Author: Simon Liu
# -----
# Last Modified: 2022-06-10 15:53:08
# Modified By: Simon Liu
# -----
# Copyright (c) 2022 SimonLiu Inc.
# 
# May the force be with you.
# -----
# HISTORY:
# Date      	By	Comments
# ----------	---	----------------------------------------------------------
###
import cv2
from cv2 import VideoWriter, VideoWriter_fourcc, imread, resize
from pathlib import Path
import os,sys

# src_dir = 'Movies/cat_video'
# src_path = Path.home()/Path(src_dir)
# Option to decide whether to save frame to independent folders ,每个视频帧是否保存在独立文件夹,默认为False
independent_folder = False
# Skip {frame_to_skip} frames before saving another frame ,保存图片的间隔帧数
frame_to_skip = 15
total_saved = 0
total_file_count = 0
current_file = 0
file_types = ['MOV','MP4','AVI','FLV']

def get_total_file_count(src_path):
    global total_file_count,file_types
    # Get total file count
    for f in src_path.glob('**/*'):
        if(f.is_file() and (f.suffix.upper()[1:] in file_types)):
            total_file_count += 1
        else:
            pass

def browse_video_files(src_path,dst_path):
    global file_types,total_saved,total_file_count,current_file
    if src_path.exists():
        print('找到源视频文件夹:%s, \n符合条件的视频文件总数:%d'%(str(src_path),total_file_count))
        for f in src_path.glob('**/*'):
            current_file += 1
            if(f.is_file() and (f.suffix.upper()[1:] in file_types)):
                print(f'正在转换文件({current_file}/{total_file_count})------->>>',f.name)
                video2pic(f,dst_path)
            else:
                pass
    else:
        print('文件夹不存在:',str(dir))
    

def video2pic(f,dst_path):
    global total_saved
    filename = f.stem #获取文件名,不含后缀
    cap = cv2.VideoCapture(str(f))
    fps = int(cap.get(cv2.CAP_PROP_FPS))  # 获取帧率
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 获取宽度
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 获取高度
    fcount = cap.get(cv2.CAP_PROP_FRAME_COUNT)      # 获取视频总帧数
    
    while True:
        userinput = input(f"请输入选取帧间隔(0-{fps},直接回车默认是5):")
        if userinput == '':
            frame_to_skip = 5
            break
        elif userinput.isdigit():
            frame_to_skip = int(frame_to_skip)
            if frame_to_skip >= 0 and frame_to_skip < fps:
                break
            else:
                print("输入非法,请重新输入提示范围内的数字")
        else:
            print("输入非法,请重新输入提示范围内的数字")
    
    frame_to_save =  int(fcount/frame_to_skip)
    print(f'视频文件帧率:{fps}, 分辨率:{width}x{height},视频总帧数:{fcount},保存间隔帧数:{frame_to_skip},预计保存帧数:{frame_to_save}')

    suc = cap.isOpened()  # 是否成功打开
    frame_count = 0
    frame_saved = 0
    # dst_dir = f'{src_path}_frames/{filename}_frames'
    if independent_folder:
        dst_path = dst_path/f'{filename}_frames'
    print(f'目标文件夹:',dst_path)
    if dst_path.exists():
        # print(f'目标文件夹 {dst_path} 已经存在...')
        pass
    else:
        print(f'创建目标文件夹: {dst_path} ')
        dst_path.mkdir(exist_ok=True, parents=True)
    suc, frame = cap.read()
    while suc:
        frame_count +=  1
        if frame_count%frame_to_skip == 0:
            frame_saved += 1
            total_saved += 1
            print(f'正在写入 {dst_path}/{filename}_{frame_saved:05d}.jpg\r',end='')
            cv2.imwrite(f'{dst_path}/{filename}_{frame_saved:05d}.jpg', frame)
        suc, frame = cap.read()
        cv2.waitKey(1)
    cap.release()
    print(f'\n视频转图片结束!从视频 {f.name} 中保存了 {frame_saved} 帧画面。')

def input_video_path():
    while True:
        video_path = input('请输入图片文件夹位置(输入Q或q退出):')
        if video_path == "Q" or video_path == 'q':
            sys.exit()
        # video_path = "~/Movies/cat_video_frames_picked_224x224"
        video_path = os.path.expanduser(video_path)
        src_path = Path(video_path)
        if src_path.exists():
            break
        else:
            print(f"文件夹{src_path}不存在,请检查输入的文件夹名称是否正确。")
    basename = str(src_path.stem)
    dst_path = src_path.parent/f'{basename}_frames'
    return src_path,dst_path

def main():
    global total_file_count,total_saved
    src_path,dst_path = input_video_path()
    get_total_file_count(src_path)
    browse_video_files(src_path,dst_path)
    print(f'总共转换了{total_file_count}个文件, 保存了{total_saved}帧图片。')

if __name__ == '__main__':
    main()

仓库地址:
simonliu009/video2jpg: A python script that converts video to jpg files

参考资料:
使用Python实现MP4格式视频与图片相互转换
python文件和路径操作神器:pathlib

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值