长生栈 长生栈
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Living Team

编程技术分享
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据集制作-从视频提取关键帧(原理)

    • 一、主流关键帧提取方法
      • 1. 基于场景变化检测(Scene Change Detection)
      • 2. 基于运动分析(Motion Analysis)
      • 3. 基于内容显著性(Saliency Detection)
      • 4. 基于深度学习(Deep Learning)
    • 二、高级提取技术
      • 1. 压缩域提取(Compressed Domain Extraction)
      • 2. 时间采样法(Temporal Sampling)
      • 3. 混合方法(Hybrid Approaches)
    • 三、方法选择指南
    DC Wang
    2025-06-07
    随笔
    目录

    数据集制作-从视频提取关键帧(原理)

    # 数据集制作-从视频提取关键帧

    # 一、主流关键帧提取方法

    # 1. 基于场景变化检测(Scene Change Detection)

    import cv2
    
    def detect_scene_changes(video_path, threshold=0.3):
        """检测场景变化并提取关键帧"""
        cap = cv2.VideoCapture(video_path)
        ret, prev_frame = cap.read()
        frames = []
        
        while True:
            ret, curr_frame = cap.read()
            if not ret: break
                
            # 计算直方图差异
            hist_diff = cv2.compareHist(
                cv2.calcHist([prev_frame], [0], None, [256], [0,256]),
                cv2.calcHist([curr_frame], [0], None, [256], [0,256]),
                cv2.HISTCMP_BHATTACHARYYA
            )
            
            # 检测场景变化
            if hist_diff > threshold:
                frames.append(curr_frame)
                
            prev_frame = curr_frame
        
        cap.release()
        return frames
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    原理: 通过比较连续帧之间的颜色直方图差异,当差异超过阈值时提取为关键帧 ​​优点:​​ 对亮度变化鲁棒,计算速度快 ​​适用:​​ 新闻剪辑、电视节目等有明显场景切换的视频

    # 2. 基于运动分析(Motion Analysis)

    import cv2
    
    def detect_motion_based_frames(video_path, motion_threshold=50):
        """基于运动分析提取关键帧"""
        cap = cv2.VideoCapture(video_path)
        ret, prev_frame = cap.read()
        prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
        frames = []
        
        while True:
            ret, curr_frame = cap.read()
            if not ret: break
            
            curr_gray = cv2.cvtColor(curr_frame, cv2.COLOR_BGR2GRAY)
            
            # 计算光流
            flow = cv2.calcOpticalFlowFarneback(
                prev_gray, curr_gray, None, 0.5, 3, 15, 3, 5, 1.2, 0
            )
            
            # 计算平均运动量
            magnitude = np.sqrt(flow[...,0]**2 + flow[...,1]**2)
            avg_motion = np.mean(magnitude)
            
            # 检测显著运动
            if avg_motion > motion_threshold:
                frames.append(curr_frame)
            
            prev_gray = curr_gray
        
        cap.release()
        return frames
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32

    原理: 使用光流算法分析像素点运动量,检测显著运动区域 ​​优点:​​ 能有效识别物体移动和相机运动 ​​适用:​​ 体育比赛、监控视频等运动量大的场景

    # 3. 基于内容显著性(Saliency Detection)

    import cv2
    import numpy as np
    
    def extract_salient_frames(video_path, saliency_threshold=0.5):
        """基于内容显著性提取关键帧"""
        cap = cv2.VideoCapture(video_path)
        frames = []
        
        # 创建显著性检测器
        saliency = cv2.saliency.StaticSaliencyFineGrained_create()
        
        while True:
            ret, frame = cap.read()
            if not ret: break
            
            # 计算显著性图
            success, saliency_map = saliency.computeSaliency(frame)
            
            if success:
                # 计算平均显著性
                mean_saliency = np.mean(saliency_map)
                
                # 检测显著内容
                if mean_saliency > saliency_threshold:
                    frames.append(frame)
        
        cap.release()
        return frames
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

    原理: 识别图像中最吸引人的区域 ​​优点:​​ 符合人类视觉注意机制 ​​适用:​​ 广告视频、产品展示等需要突出主体的内容

    # 4. 基于深度学习(Deep Learning)

    import tensorflow as tf
    from tensorflow.keras.applications import MobileNetV2
    from tensorflow.keras.models import Model
    import cv2
    
    def extract_deep_features(video_path, threshold=0.75):
        """基于深度学习特征提取关键帧"""
        # 加载预训练模型
        base_model = MobileNetV2(weights='imagenet', include_top=False, pooling='avg')
        model = Model(inputs=base_model.input, outputs=base_model.output)
        
        cap = cv2.VideoCapture(video_path)
        ret, prev_frame = cap.read()
        frames = []
        
        # 提取第一帧特征
        prev_img = cv2.resize(prev_frame, (224, 224))
        prev_features = model.predict(np.expand_dims(prev_img, axis=0))
        
        while True:
            ret, curr_frame = cap.read()
            if not ret: break
            
            curr_img = cv2.resize(curr_frame, (224, 224))
            curr_features = model.predict(np.expand_dims(curr_img, axis=0))
            
            # 计算余弦相似度
            sim = np.dot(prev_features, curr_features.T)[0][0]
            
            # 检测内容显著变化
            if sim < threshold:
                frames.append(curr_frame)
                prev_features = curr_features
        
        cap.release()
        return frames
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    原理: 使用CNN提取高级语义特征进行帧间比较 ​​优点:​​ 识别内容而非像素变化,准确率高 ​​适用:​​ 复杂场景下需要理解语义内容的情况

    # 二、高级提取技术

    # 1. 压缩域提取(Compressed Domain Extraction)

    原理: 直接从视频压缩数据中提取关键帧(I帧) ​​优势:​​ 无需完整解码视频,速度极快 ​​实现:​​

    # 使用FFmpeg提取I帧
    ffmpeg -skip_frame nokey -i input.mp4 -vsync 0 frame_%03d.jpg
    
    1
    2

    # 2. 时间采样法(Temporal Sampling)

    def temporal_sampling(video_path, interval=100):
        """按固定间隔提取帧"""
        cap = cv2.VideoCapture(video_path)
        frames = []
        
        for frame_idx in range(0, int(cap.get(cv2.CAP_PROP_FRAME_COUNT)), interval):
            cap.set(cv2.CAP_PROP_POS_FRAMES, frame_idx)
            ret, frame = cap.read()
            if ret:
                frames.append(frame)
        
        cap.release()
        return frames
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    原理: 按固定时间间隔采样 ​​优点:​​ 简单高效,分布均匀 ​​缺点:​​ 可能错过重要时刻 ​​适用:​​ 监控视频、时间序列分析

    # 3. 混合方法(Hybrid Approaches)

    def hybrid_extraction(video_path):
        """混合方法提取关键帧"""
        # 第一阶段:快速提取候选帧
        candidates = temporal_sampling(video_path, interval=300)
        
        # 第二阶段:内容分析筛选
        saliency = cv2.saliency.StaticSaliencyFineGrained_create()
        key_frames = []
        
        for frame in candidates:
            success, saliency_map = saliency.computeSaliency(frame)
            if success and np.mean(saliency_map) > 0.4:
                key_frames.append(frame)
        
        return key_frames
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    原理: 结合多种方法的优势 ​​典型流程:​​

    1. 时间采样获取候选帧
    2. 使用场景检测过滤无效帧
    3. 基于显著性评分排序
    4. 聚类算法去除相似帧

    # 三、方法选择指南

    方法类型 准确度 计算复杂度 适用场景 推荐实施
    场景变化 ★★☆ ★☆☆ 新闻/影视剧 直方图差异法
    运动分析 ★★☆ ★★☆ 体育/监控 光流法
    内容显著性 ★★★ ★★☆ 广告/产品展示 OpenCV saliency API
    深度学习 ★★★ ★★★ 复杂语义内容 MobileNet特征提取
    压缩域提取 ★☆☆ ★☆☆ 高速批处理 FFmpeg工具
    混合方法 ★★★ ★★☆ 通用高要求场景 时间采样+内容筛选
    编辑 (opens new window)
    上次更新: 2025/06/07, 21:53:36
    最近更新
    01
    ESP32-网络摄像头方案
    06-14
    02
    ESP32-PWM驱动SG90舵机
    06-14
    03
    ESP32-实时操作系统freertos
    06-14
    更多文章>
    Theme by Vdoing | Copyright © 2019-2025 DC Wang All right reserved | 辽公网安备 21021102001125号 | 吉ICP备20001966号-2
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式