开发者

使用Python + OpenCV提取和保存视频帧

目录
  • 引言
  • 环境准备
  • 代码实现
  • 运行 命令行工具
    • 1 处理单个视频文件
    • 2 批量处理目录中的所有视频
    • 完整帮助信息
  • 结语

    引言

    php

    在计算机视觉、机器学习和图像处理应用php中,从视频中处理图像帧是一个常见的任务。python提供了一些强大的库和工tUHwUsI具,使我们能够轻松地从视频中提取帧并对其进行处理。

    百度百科: OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在linux、Windows、android和MAC OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

    环境准备

    使用 OpenCV 库从视频中提取特定帧并保存为图像文件,首先需要确保安装了必要的库。

    注意:OpenCV库为 opencv-python ,导入OpenCV语法为 import cv2

    pip install opencv-python numpy matplotlib
    

    代码实现

    注意:运行代码需通过命令行的方式

    import cv2
    import os
    import argparse
    from datetime import timedelta
    from pathlib import Path
    
    def extract_frames(video_path, output_dir, frame_interval=None, time_interval=None, prefix="frame"):
        """
        从视频中提取帧并保存到指定目录
    
        参数:
            video_path: 视频文件路径
            output_dir: 输出目录
            frame_interval: 帧间隔(每多少帧提取一帧)
            time_interval: 时间间隔(秒)
            prefix: 输出文件名前缀
        """
    
        # 检查视频文件
        if not os.path.isfile(video_path):
            print(f"错误: 视频文件 '{video_path}' 不存在")
            return
    
        # 创建输出目录 确保输出目录存在
        os.makedirs(output_dir, exist_ok=True)
    
        # 打开视频文件
        cap = cv2.VideoCapture(video_path)
        if not cap.isOpened():
            print(f"错误: 无法打开视频文件 {video_path}")
            return
    
        # 获取视频文件名(不含扩展名)作为默认前缀
        if prefix is None:
            video_name = Path(video_path).stem  # 例如: "input" from "input.mp4"
            prefix = video_name
    
        # 获取视频属性
        fps = cap.get(cv2.CAP_PROP_FPS)
        frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
        duration = frame_count / fps
    
        print(f"视频信息:")
        print(f"  视频路径: {video_path}")
        print(f"  帧率: {fps:.2f} fps")
        print(f"  总帧数: {frame_count}")
        print(f"  分辨率: {width}x{height}")
        print(f"  时长: {timedelta(seconds=duration)}")
    
        # 确定提取间隔
        if frame_interval is not None:
            interval = frame_interval
            use_frame_interval = True
            print(f"将每 {interval} 帧提取一帧")
        elif time_interval is not None:
            interval = max(1, int(time_interval * fps))  # 确保至少1帧
            use_frame_interval = True
            print(f"将每 {time_interval} 秒({interval}帧)提取一帧")
        else:
            interval = 1
            use_frame_interval = True
            print("将提取所有帧")
    
        # 开始提取帧
        frame_number = 0
        saved_count = 0
    
        print("\n开始提取帧...")
    
        while True:
            ret, frame = cap.read()
            jsif not ret:
                break
    
            # 检查是否应该保存当前帧
            if use_frame_interval and frame_number % interval == 0:
                save_path = os.path.join(output_dir, f"{prefix}_{frame_number:06d}.jpg")
                cv2.imwrite(save_path, frame)
                saved_count += 1
    
            frame_number += 1
    
        cap.release()
        print(f"完成提取: 共处理 {frame_number} 帧,保存 {saved_count} 张到 {output_dir}")
    
    
    def main():
        parser = argparse.ArgumentParser(description='从视频中提取帧并保存')
        parser.add_argument('--video_dir', help='视频所在目录(处理目录下所有视频)')
        parser.add_argument('--video_path', help='单个视频文件路径(与video_dir互斥)')
        parser.add_argument('--output_dir', help='输出目录')
        group = parser.add_mutually_exclusive_group()
        group.add_argument('--frame_interval', type=int, help='帧间隔(每多少帧提取一帧)')
        group.add_argument('--time_interval', type=float, help='时间间隔(秒)')
        parser.add_argument('--prefix', help='输出文件名前缀(默认为视频文件名)')
        parser.add_argument('--extensions', default='mp4,mkv,avi,mov', help='允许的视频扩展名,逗号分隔')
    
        args = parser.parse_args()
    
        # 验证输入参数
        if not args.video_dir and not args.video_path:
            parser.error("请指tUHwUsI定 --video_dir 或 --video_path")
    
        # 获取视频文件列表
        video_files = []
        if args.video_dir:
            if not os.path.exists(args.video_dir):
                print(f"错误: 视频目录 {args.video_dir} 不存在")
                return
    
            allowed_extensions = set(args.extensions.lower().split(','))
            for entry in os.scandir(args.video_dir):
                if entry.is_file() and entry.name.lower().split('.')[-1] in allowed_extensions:
                    video_files.append(entry.path)
    
            if not video_files:
                print(f"错误: 在目录 {args.video_dir} 中未找到支持的视频文件")
                return
        else:
            if not os.path.exists(args.video_path):
                print(f"错误: 视频文件 {args.video_path} 不存在")
                return
            video_files = [args.video_path]
    
        print(f"找到 {len(video_files)} 个视频文件需要处理")
    
        # 处理每个视频
        for video_path in video_files:
            video_name = Path(video_path).stem
    
            # 使用视频名作为默认前缀(除非用户指定了全局前缀)
            prefix = args.prefix if args.prefix else video_name
    
            extract_frames(
                video_path,
                args.output_dir,  # 直接使用用户指定的输出目录,不再创建子目录
                args.frame_interval,
                args.time_interval,
                prefix
            )
    
    if __name__ == "__main__":
        main()
    
    
    

    运行 命令行工具

    你可以通过以下命令行方式运行这个视频帧提取程序。

    程序支持两种模式:①单视频处理②批量处理目录中的所有视频

    1 处理单个视频文件

    bash 命令

    python [代码名] --video_path 视频路径 --output_dir 输出目录 [其他参数]
    

    示例:

    提取 input.mp4 的帧,每秒提取一帧,保存到 frames/ 目录:

    python frame.py --video_path input.mp4 --output_dir frames/ --time_interval 1.0
    

    2 批量处理目录中的所有视频

    bash 命令

    python frame.py --video_dir 视频目录 --output_dir 输出目录 [其他参数]
    

    示例:

    处理 videos/ 目录下的所有视频(默认支持 mp4、mkv、avi、mov 格式),每 30 帧提取一帧,保存到 frames/ 目录:

    python frame.py --video_dir videos/ --output_dir frames/ --frame_interval 30
    

    完整帮助信息

    查看所有可用参数:

    python frame.py --help
    

    结语

    使用Python和OpenCV提取视频帧是一项强大而灵活的技术,适用于各种计算机视觉和多媒体处理任务。本文介绍的方法从基础到高级,覆盖了大多数实际应用场景。通过调整参数和结合其他Python库,您可以构建更复杂的视频处理流程。

    到此这篇关于使用Python + OpenCV提取和保存视频帧的文章就介绍到这了,更多相关OpenCV提取和保存视频帧内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜