如何用OpenCV 2.4.13(Python2.7)移除视频中的无运动帧?
实现方案:OpenCV 2.4.13 + Python 2.7 视频帧去重
嘿,针对你的需求,我整理了一套适配指定版本的实现方案,核心就是逐帧对比相邻帧,过滤掉完全重复的帧,只把有变化的帧保存到输出视频里。
实现思路
- 先打开输入视频,获取它的基础参数(宽、高、帧率、编码格式),这些参数必须和输出视频保持一致,不然会出现播放异常
- 初始化视频写入器,用来存储去重后的帧序列
- 读取第一帧作为初始基准帧,直接写入输出(毕竟没有前一帧可以对比,肯定要保留)
- 循环读取后续每帧,和当前基准帧做差异对比:
- 如果两帧像素完全一致,就跳过这帧
- 如果有差异,就写入输出视频,同时把当前帧更新为新的基准帧
- 最后记得释放视频捕获和写入的资源,避免内存泄漏
完整代码示例
import cv2 import numpy as np def remove_duplicate_frames(input_video_path, output_video_path): # 打开输入视频文件 cap = cv2.VideoCapture(input_video_path) if not cap.isOpened(): print "无法打开输入视频文件,请检查路径是否正确" return # 获取视频基础参数(适配OpenCV 2.4版本API) fps = cap.get(cv2.cv.CV_CAP_PROP_FPS) width = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)) # 设置编码格式,这里用MJPG,你也可以根据需求替换成XVID等 fourcc = cv2.cv.CV_FOURCC(*'MJPG') # 初始化视频写入器 out = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height)) if not out.isOpened(): print "无法初始化视频写入器,请检查编码格式是否支持" cap.release() return # 读取第一帧作为基准帧 ret, prev_frame = cap.read() if not ret: print "输入视频为空或无法读取帧" cap.release() out.release() return out.write(prev_frame) # 直接写入第一帧 # 逐帧处理后续内容 while True: ret, curr_frame = cap.read() if not ret: break # 视频读取完毕,退出循环 # 对比当前帧与基准帧是否完全相同 diff = cv2.absdiff(prev_frame, curr_frame) if np.sum(diff) == 0: # 像素差异总和为0,说明帧完全重复,跳过 continue else: # 帧有变化,写入输出并更新基准帧 out.write(curr_frame) prev_frame = curr_frame.copy() # 必须拷贝,避免内存引用导致的异常 # 释放所有资源 cap.release() out.release() print "帧去重完成!输出视频已保存至:", output_video_path # 调用示例,替换成你的实际路径 if __name__ == "__main__": input_video = "your_input_video.avi" output_video = "your_output_video.avi" remove_duplicate_frames(input_video, output_video)
关键细节说明
- OpenCV 2.4专属API注意:在2.4版本中,获取视频属性、设置编码格式都需要用
cv2.cv下的常量,比如cv2.cv.CV_CAP_PROP_FPS、cv2.cv.CV_FOURCC,这和3.x及之后版本的API不一样,别搞混了 - 帧对比逻辑:用
cv2.absdiff计算两帧像素差异后求和,总和为0就代表完全重复。你也可以用np.array_equal(prev_frame, curr_frame),但absdiff能兼容一些细微的像素类型/通道差异,更稳妥 - 基准帧更新:一定要用
curr_frame.copy()来更新基准帧,不然prev_frame会直接引用curr_frame的内存,后续循环里基准帧会跟着当前帧变化,导致对比失效 - 编码格式选择:示例用的MJPG编码兼容性较强,如果需要其他格式,可以替换
CV_FOURCC的参数,比如*'XVID'对应XVID编码,前提是你的OpenCV支持该编码
内容的提问来源于stack exchange,提问作者Nithin
相关产品推荐
相关产品推荐

