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

Python+OpenCV视频帧去重:仅保留重复帧首张并添加时间轴方案求助

实现思路
  • 帧去重逻辑:对裁剪后的画面做全像素一致性对比,当前帧和上一张已保留的裁剪帧完全相同时直接丢弃,仅保留首次出现的帧
  • 时间轴信息获取:调用OpenCV的CAP_PROP_POS_MSEC属性读取当前帧对应的视频毫秒级时间戳,保存文件时直接把时间戳写入文件名或单独生成对应关系表
  • 计数逻辑:单独统计保留的有效帧序号,避免丢弃重复帧后文件名序号断层
修改后完整代码
import numpy as np
import cv2

def get_frames_and_timestamps(video_name, time_F):
    frame_list = []
    vc = cv2.VideoCapture(video_name)
    frame_counter = 1
    rval = vc.isOpened()
    
    while rval:  
        rval, video_frame = vc.read()
        if not rval:
            break
        # 每隔time_F帧采样,同时获取当前帧时间戳(毫秒)
        if frame_counter % time_F == 0: 
            timestamp = vc.get(cv2.CAP_PROP_POS_MSEC)
            frame_list.append((video_frame, timestamp))     
        frame_counter += 1
    vc.release()
    return frame_list 

# 配置参数
time_F = 24
video_name = 'writingvideo2/11_0330吳恒基.mp4' 
x, y, w, h = 50, 150, 1800, 650
save_path_prefix = 'output2/image/11/'

# 读取采样帧与对应时间戳
sampled_frames = get_frames_and_timestamps(video_name, time_F) 

last_keep_frame = None
keep_count = 0

for frame, timestamp in sampled_frames:
    # 裁剪画面
    current_crop = frame[y:y+h, x:x+w]
    # 去重判断
    if last_keep_frame is not None and np.array_equal(current_crop, last_keep_frame):
        continue
    # 保留当前帧
    last_keep_frame = current_crop.copy()
    # 文件名带保留序号与时间戳,方便对应时间轴
    filename = f'{save_path_prefix}{keep_count}_{int(timestamp)}ms.png'
    cv2.imwrite(filename, current_crop, [cv2.IMWRITE_PNG_COMPRESSION, 3])
    # 显示画面
    cv2.imshow("cropped", current_crop)
    keep_count += 1
    cv2.waitKey(100)

cv2.destroyAllWindows()
关键改动说明
  • 原采样函数修改为同时返回帧和对应时间戳,时间轴精度到毫秒
  • 新增last_keep_frame变量存储上一张保留的裁剪帧,用np.array_equal做全像素对比,完全一致则跳过保存
  • 文件名同时包含有效帧序号和时间戳,直接对应视频时间轴位置
  • 修复了原代码末尾cv2.destroyAllWindows漏加括号的问题,替换了PNG存储时无效的JPEG质量参数

内容的提问来源于stack exchange,提问作者陳昱廷

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 10:48:03