前言
相信大家在使用cv2读取视频流的过程中一定遇到过读取缓慢的问题(或者在处理高帧视频时变的缓慢),为了研究如何解决这一问题研究了下opencv文档,今天为大家带来一个小notes,能优化 卡顿和花屏&灰屏。
分析原因
由于opencv是默认为自带的ffmpeg进行解码播放视频,在使用单独的使用ffmpeg进行播放视频时发现与opencv的差异:
- opencv进行连接后播放的视频画面是从cv2读取视频流时进行播放的
- ffmpeg在碰到视频流连接不顺畅会跳到实时状态的画面,不会进行读取缓冲区的画面
查阅opencv文档中发现ret, frame = cap.read()中的read函数是包含了两大步骤:从缓冲区拿出数据 + 对数据进行解码
当我们无法解决视频流自身的问题的时候,可以从读取视频流这里做文章。细分从缓冲区拿数据和解码这两个过程,显而易见的是解码的过程较为耗费时间。 针对这一问题我们可以在保证不影响性能的前提下牺牲部分帧加速视频处理过程,采用cap.grab() 和 cap.retrieve() 分别进行跳帧和解码替代cap.read()
解决
例如视频的帧率是30,在不影响对下游任务的影响的前提下,我们可以进行跳帧处理。每处理一帧后跳过下一帧,对下下帧进行读取解码工作
import cv2 cap = cv2.VideoCapture(0) idx = 0 freq = 2 while True: idx += 1 ret = cap.grab() if not ret: break if idx % freq == 1: ret, frame = cap.retrieve() if frame is None: break cv2.imshow("video", frame) c = cv2.waitKey(1) & 0xff if c == 27: cap.release() break cap.release()