You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenCV从会议视频提取幻灯片并去除冗余帧

解决会议视频幻灯片提取的冗余帧问题

你的问题根源是逐帧保存所有画面,但会议视频中绝大多数时间幻灯片内容没有变化,只有切换时刻才产生有效新画面。要避免冗余,核心逻辑是只保存与上一帧存在显著差异的帧——也就是幻灯片切换的关键帧。

下面是具体改进方案和代码实现:

核心思路

  • 对比当前帧与上一帧的内容差异,设置合理的差异阈值
  • 仅当差异超过阈值时,才将当前帧判定为新幻灯片并保存
  • 对帧做预处理(转灰度、模糊),过滤演讲者手势、光线抖动等微小干扰

改进后的代码

这里使用**结构相似性指数(SSIM)**衡量帧差异,它比简单像素差更能精准反映画面内容的实质性变化:

import cv2
import os
from skimage.metrics import structural_similarity as ssim

def calculate_frame_diff(frame1, frame2):
    # 转灰度图,降低计算复杂度
    gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
    # 高斯模糊,过滤噪声干扰
    gray1 = cv2.GaussianBlur(gray1, (5, 5), 0)
    gray2 = cv2.GaussianBlur(gray2, (5, 5), 0)
    # 计算SSIM,返回值越接近1表示两帧越相似
    similarity_score, _ = ssim(gray1, gray2, full=True)
    return 1 - similarity_score  # 转换为差异值,值越大差异越明显

# 初始化视频捕获
cam = cv2.VideoCapture("C:\\Users\\zoomrx\\Desktop\\Video\\1.mp4")
output_dir = 'data_clean'

# 创建输出目录
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

current_frame_idx = 0
previous_frame = None
# 差异阈值,可根据视频实际情况调整(推荐范围0.1-0.3)
diff_threshold = 0.2

while True:
    ret, frame = cam.read()
    if not ret:
        break
    
    roi = frame[166:959, 24:1433]  # 保留你原有的ROI区域
    
    if previous_frame is None:
        # 第一帧直接保存
        save_path = f'./{output_dir}/slide_{current_frame_idx}.jpg'
        print(f'保存新幻灯片: {save_path}')
        cv2.imwrite(save_path, roi)
        previous_frame = roi.copy()
        current_frame_idx += 1
    else:
        # 计算当前帧与上一帧的差异
        diff_value = calculate_frame_diff(roi, previous_frame)
        if diff_value > diff_threshold:
            # 差异超过阈值,判定为新幻灯片并保存
            save_path = f'./{output_dir}/slide_{current_frame_idx}.jpg'
            print(f'保存新幻灯片: {save_path}')
            cv2.imwrite(save_path, roi)
            previous_frame = roi.copy()
            current_frame_idx += 1
    
    if cv2.waitKey(1) & 0xFF == 27:
        break

cam.release()
cv2.destroyAllWindows()

关键说明

  1. SSIM差异计算:从亮度、对比度、结构三个维度评估图像相似性,能有效过滤演讲者手势、屏幕反光等非幻灯片内容的微小变化。
  2. 预处理步骤:转灰度和高斯模糊既减少了计算量,又避免了噪声导致的误判。
  3. 阈值调整:如果幻灯片切换时画面差异大,可适当提高diff_threshold;如果视频存在较多抖动,可降低阈值。

备选方案(无需额外依赖)

若不想安装scikit-image库,可使用简单的像素差均值判断:

def calculate_frame_diff(frame1, frame2):
    gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
    # 计算像素差的绝对值均值
    diff_map = cv2.absdiff(gray1, gray2)
    return diff_map.mean()

此时阈值建议设为10-30之间,根据视频实际情况微调。

内容的提问来源于stack exchange,提问作者Shishir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:35:19