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,提问作者陳昱廷
相关产品推荐
相关产品推荐

