使用pyscenedetect进行视频场景切割

1. 简介

在视频剪辑有转场一词:一个视频场景转换到另一个视频场景,场景与场景之间的过渡或转换,就叫做转场。
本篇介绍一个强大的开源工具PySceneDetect,它是一款基于opencv的视频场景切换检测和分析工具,项目地址: https://github.com/Breakthrough/PySceneDetect

2. 创建使用环境

conda create -n pyscenedetect python=3.7
conda activate pyscenedetect
conda install ffmpeg -y
pip install scenedetect opencv-python

3. 命令行测试

pyscenedetect提供了一个命令行工具,可以通过-h参数来查看它的帮助信息

Usage: scenedetect [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
 
  For example:
 
  scenedetect -i video.mp4 -s video.stats.csv detect-content list-scenes
 
  Note that the following options represent [OPTIONS] above. To list the
  optional [ARGS] for a particular COMMAND, type `scenedetect help COMMAND`.
  You can also combine commands (e.g. scenedetect [...] detect-content save-
  images --png split-video).
 
Options:
  -i, --input VIDEO             [Required] Input video file. May be specified
                                multiple times to concatenate several videos
                                together. Also supports image sequences and
                                URLs.
  -o, --output DIR              Output directory for all files (stats file,
                                output videos, images, log files, etc...).
  -f, --framerate FPS           Force framerate, in frames/sec (e.g. -f
                                29.97). Disables check to ensure that all
                                input videos have the same framerates.
  -d, --downscale N             Integer factor to downscale frames by (e.g. 2,
                                3, 4...), where the frame is scaled to width/N
                                x height/N (thus -d 1 implies no downscaling).
                                Each increment speeds up processing by a
                                factor of 4 (e.g. -d 2 is 4 times quicker than
                                -d 1). Higher values can be used for high
                                definition content with minimal effect on
                                accuracy. [default: 2 for SD, 4 for 720p, 6
                                for 1080p, 12 for 4k]
  -fs, --frame-skip N           Skips N frames during processing (-fs 1 skips
                                every other frame, processing 50% of the
                                video, -fs 2 processes 33% of the frames, -fs
                                3 processes 25%, etc...). Reduces processing
                                speed at expense of accuracy.  [default: 0]
  -m, --min-scene-len TIMECODE  Minimum size/length of any scene. TIMECODE can
                                be specified as exact number of frames, a time
                                in seconds followed by s, or a timecode in the
                                format HH:MM:SS or HH:MM:SS.nnn  [default:
                                0.6s]
  --drop-short-scenes           Drop scenes shorter than `--min-scene-len`
                                instead of combining them with neighbors
  -s, --stats CSV               Path to stats file (.csv) for writing frame
                                metrics to. If the file exists, any metrics
                                will be processed, otherwise a new file will
                                be created. Can be used to determine optimal
                                values for various scene detector options, and
                                to cache frame calculations in order to speed
                                up multiple detection runs.
  -v, --verbosity LEVEL         Level of debug/info/error information to show.
                                Setting to none will suppress all output
                                except that generated by actions (e.g.
                                timecode list output). Can be overriden by
                                `-q`/`--quiet`.
  -l, --logfile LOG             Path to log file for writing application
                                logging information, mainly for debugging.
                                Make sure to set `-v debug` as well if you are
                                submitting a bug report.
  -q, --quiet                   Suppresses all output of PySceneDetect except
                                for those from the specified commands.
                                Equivalent to setting `--verbosity none`.
                                Overrides the current verbosity level, even if
                                `-v`/`--verbosity` is set.
  -h, --help                    Show this message and exit.
 
Commands:
  about             Print license/copyright info.
  detect-content    Perform content detection algorithm on input video(s).
  detect-threshold  Perform threshold detection algorithm on input video(s).
  export-html       Exports scene list to a HTML file.
  help              Print help for command (help [command]).
  list-scenes       Prints scene list and outputs to a CSV file.
  save-images       Create images for each detected scene.
  split-video       Split input video(s) using ffmpeg or mkvmerge.
  time              Set start/end/duration of input video(s).
  version           Print version of PySceneDetect.

找个包含多场景切换的视频测试一下,执行命令

scenedetect -i lldq.mp4 detect-content split-video

脚本运行结束后,会在当前目录生成每个镜头的视频片段,每个视频片段只包含一个场景:
在这里插入图片描述

如果想从视频的某个时间点开始,可以使用参数time:

scenedetect -i lldq.mp4 time -s 5s detect-content split-video

还可以将检测后的场景图片保存下来,同时生成统计文件csv:

scenedetect.exe -i lldq.mp4 -o video_scenes detect-content save-images

4. 场景切割算法

pyscenedetect使用了2种场景切割的方法,它们是detect-content和detect-threshold,除此之外,它还支持自定义检测算法。

  • detect-content
    顾名思义,这种方法就是根据前后图像的内容来进行判断,与我们常识中所说的视频转场是一样的。算法会根据前后2帧的视频数据,计算出它们不同的区域大小,如果这个区域大于某个预先设定的值(默认是30,可以通过–threshold参数来指定),那么就认为场景已经切换了
  • detect-threshold
    这是比较传统的检测方法,有点像ffmpeg中的blackframe滤镜。它会用特定的值去跟数据帧的亮度比较进行,如果大于某个预先设定的值,就认为场景已经切换了。在pyscenedetect中,这个值是由视频帧的每个像素的RGB的平均值计算而来
  • 自定义检测算法
    所有的检测算法必须继承自SceneDetector这个类
from scenedetect.scene_detector import SceneDetector
 
class CustomDetector(SceneDetector):
    """CustomDetector class to implement a scene detection algorithm."""
    def __init__(self):
        pass
 
    def process_frame(self, frame_num, frame_img, frame_metrics, scene_list):
        """Computes/stores metrics and detects any scene changes.
        Prototype method, no actual detection.
        """
        return
 
    def post_process(self, scene_list):
        pass
		

类中主要有2个方法,process_frame负责处理所有的视频帧;post_process是可选的,它在process_frame结束后执行,主要用来做一些后期处理,比如场景切换数据的文件保存。

下面主要来看看process_frame方法,它有如下几个重要参数

更加实现细节方面,可以参考源码目录下的scenedetect/detectors/content_detector.py或scenedetect/detectors/threshold_detector.py

  • frame_num: 当前处理到的帧数
  • frame_img: 返回的帧数据,格式是numpy数组
  • frame_metrics: 保存检测算法计算结果的字典
  • scene_list: 视频中所有场景切换包含的帧数列表

5. Python API的使用

如果需要在自己的代码中去使用pyscenedetect,除了使用命令行调用的方式外,pyscenedetect还提供了基于python的API。

下面是一个简单的demo,程序读取视频文件,使用content-detector算法进行检测,最后将所有场景的开始时间、结束时间和总的帧数分别打印输出。

from scenedetect.video_manager import VideoManager
from scenedetect.scene_manager import SceneManager
from scenedetect.stats_manager import StatsManager
from scenedetect.detectors.content_detector import ContentDetector
 
 
def find_scenes(video_path):
    video_manager = VideoManager([video_path])
    stats_manager = StatsManager()
    scene_manager = SceneManager(stats_manager)
 
    # 使用contect-detector
    scene_manager.add_detector(ContentDetector())
 
    try:
        video_manager.set_downscale_factor()
 
        video_manager.start()
 
        scene_manager.detect_scenes(frame_source=video_manager)
 
        scene_list = scene_manager.get_scene_list()
 
        print('List of scenes obtained:')
        for i, scene in enumerate(scene_list):
            print(
                'Scene %2d: Start %s / Frame %d, End %s / Frame %d' % (
                    i + 1,
                    scene[0].get_timecode(), scene[0].get_frames(),
                    scene[1].get_timecode(), scene[1].get_frames(),))
 
    finally:
        video_manager.release()
 
 
if __name__ == '__main__':
    find_scenes('lldq.mp4')

运行输出如下:
在这里插入图片描述

6. 参考

https://github.com/Breakthrough/PySceneDetect
https://pyscenedetect.readthedocs.io/projects/Manual/en/latest/
https://blog.gdeltproject.org/using-ffmpegs-blackdetect-filter-to-identify-commercial-blocks/
https://blog.csdn.net/djstavaV/article/details/118215641
https://blog.csdn.net/daydayup858/article/details/128256460
http://scenedetect.com/projects/Manual/en/latest/

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PySceneDetect视频大小没有限制,可以处理不同大小的视频文件。不过,处理大型视频文件时,可能需要更长的处理时间和更大的内存空间,因此建议在处理大型视频文件时,使用更高配置的计算机或者分段处理视频文件。 另外,如果视频文件过大,也可以使用 PySceneDetect 中的 `VideoSplitter` 类将大型视频文件分割成多个较小的视频文件,从而方便处理和分析。具体来说,可以按照以下步骤进行操作: 1. 安装 PySceneDetect:可以使用 pip 命令在终端中安装,命令为:`pip install scenedetect` 2. 导入 PySceneDetect 库:在 Python 编辑器中导入 PySceneDetect 库,命令为:`import scenedetect` 3. 创建 PySceneDetect 处理器:使用 PySceneDetect 中的 `VideoSplitter` 类来创建处理器,命令为: ``` from scenedetect.video_splitter import split_video_ffmpeg video_path = "VIDEO_FILE_PATH" split_length = 300 # 分割长度,单位为秒 output_directory = "OUTPUT_DIRECTORY" split_video_ffmpeg([video_path], split_length, output_directory) ``` 其中,`video_path` 是要分割的视频文件路径,`split_length` 是分割长度,`output_directory` 是输出文件夹。 4. 处理分割后的视频文件:使用 PySceneDetect 对分割后的视频文件进行处理和分析,具体步骤同上。处理完毕后,可以将分割后的视频文件合并成一个视频文件,命令为: ``` from scenedetect.video_splitter import list_all_videos from scenedetect.video_splitter import concatenate_videos_ffmpeg video_paths = list_all_videos(output_directory) concatenate_videos_ffmpeg(video_paths, "CONCATENATED_VIDEO_FILE") ``` 其中,`output_directory` 是分割后的视频文件夹,`CONCATENATED_VIDEO_FILE` 是合并后的视频文件名。 使用 PySceneDetect 对大型视频文件进行分割和处理,可以提高处理效率和减少内存占用,从而更加高效地分析和处理视频内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值