基于 cv2 视觉库 多样化截取视频帧并保存

其实现在很多视觉任务都涉及到视频的读取以及分析,类似于各种制造厂、道路监控等等等,所有有必要学习并记录下视频帧的读取方式,方便回忆。

其实总的来说,读取一个视频截取其中的帧分为两步:(1)根据video路径,创建抓取视频帧的句柄(我习惯这么叫)(2)使用句柄以及视频帧下标(第几帧)获取。当前我这么说也很抽象,下面我们一步步来:

1. 根据video路径,创建抓取视频帧的句柄

import cv2

# 全局变量 video路径
video_path = '/xx/xx/xx/test.avi'

# (1) 获取抓取视频帧句柄
video_cap = cv2.VideoCapture(video_path)

# (2)该对象提供了默认函数isOpened()用来判断句柄是否获取成功
#    如果vedio路径不对,VideoCapture()返回None??返回啥存疑,具体代码没看到

if not self.video_cap.isOpened():
    self.video_cap = None
else:
    print('success')

2. 截取视频帧并保存

# 在我们截取视频帧之前,我们需要知道当前视频有多少帧
# cv2提供了默认的关键字 CAP_PROP_FRAME_COUNT 可以获得视频总的帧数

frame_len = int(video_cap.get(cv2.CAP_PROP_FRAME_COUNT))

# 获取视频帧速率 FPS
frame_fps = int(video_cap.get(cv2.CV_CAP_PROP_FPS))

# 获取视频帧宽度和高度
frame_width = int(video_cap.get(cv2.CV_CAP_PROP_FRAME_WIDTH))
frame_height = int(video_cap.get(cv2.CV_CAP_PROP_FRAME_HEIGHT))


# 有了这些信息,正式开始截取视频帧
# (3) 没有任何需求的情况下,循环获取每一帧。
while True:
    # 句柄内置函数read(),返回两个参数,ret:是否截取成功 True or False,frame:截取的帧
    ret, frame = video_cap.read()
    if frame is None:
        break
    # 写入
    cv2.imwrite(save_path, frame)

# 最后释放句柄 
video.release()

3. 特殊需求

如果需要截取特定的帧?或者截取一系列特征的帧(帧下标用list存储),我们需要怎么办?其实也很简单。

# (4) 截取特定的帧 截取第idx个帧
# 句柄内置函数set() , 设置要获取的帧的索引号
# 注:CV_CAP_PROP_POS_FRAMES:下一个要解码/截取的帧的基于0的索引号
# set() 函数还是挺有说法的,如果你们有时间可以去看看,set有两个参数,有不同的组合方式。

video_cap.set(cv2.CAP_PROP_POS_FRAMES, idx) 
 
# 句柄内置函数read()返回一个布尔值:是否截取成功;需要截取的视频帧。
bool, frame = video_cap.read() 

# (5) 根据间隔interval,对整个视频截取frames
# 根据interval和视频总帧数,我们可以得到需要获得每一帧索引号的list

frames_list = [x0, x1, x2,..., xn]

# 重点来了,在这里你可以循环遍历 也可以 使用迭代器访问
# 这就要用到 def __next__(self)

class GetFrame:
def __init__(self): 
    self.idx = 1
def __next__(self):
    if self.idx合法:
        video_cap.set(cv2.CAP_PROP_POS_FRAMES, frames_list[idx]) 
        bool, frame = video_cap.read()
        self.idx += 1
        return frame

gf = GetFrame()
for frame in gf:
    print(frame)

# !发现了把,重写__next__()后,辅助for循环迭代遍历。

剩下的就没有什么了,这里面主要的几个函数,如果各位有兴趣可以去看看。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值