基于opencv,使用python提取视频帧以及提取TVL1光流

发布时间:2024-11-12 09:17

     处理视频,最常用的开源工具箱非opencv莫属了,python可以很好的支持它。

一 从视频读取帧、得到相关属性、并设置保存哪些帧

     首先;我们得新建一个videocapture对象;

cap=cv2.VideoCapture(videopath)

通过上面建立的对象,可以获取视频的相关属性,一般使用中用到的属性主要有如下:

     cv2.CAP_PROP_FRAME_WIDTH 视频的宽度。

    cv2.CAP_PROP_FRAME_HEIGHT 视频的高度。

    cv2.CAP_PROP_FPS 视频的帧率
通过函数:
 

cap.get(pID) # cap.get(cv2.CAP_PROP_FPS)

当从视频中读取帧的时候,我们可以设置时间或者帧序数读取指定的帧,通过set函数可以实现:

set(cv2.CAP_PROP_POS_MSEC,time) #time为设置的时间,以毫秒计(1s = 1000ms)

set(cv2.CAP_PROP_POS_FRAMES,frame) #frame为帧序数

下面一个实例来展现完整的用法:

cap = cv2.VideoCapture('test.avi') #创建一个视频获取对象

flag = 0 #用于指定帧的序号

fr=1

time=0 #用于指定帧的时长

while (cap.isOpened()):

cap.set(cv2.CAP_PROP_POS_MSEC,time)

#cap.set(cv2.CAP_PROP_POS_FRAMES,flag) #设置帧数标记

ret,im = cap.read()#获取图像

if not ret: #如果获取失败,则结束

print("exit")

break

#cv2.waitKey(2000)#延时

#cv2.imshow('a',im)#显示图像,用在循环中可以播放视频

cv2.imwrite('output/{0:05d}.jpg'.format(fr),im)#保存图片

time+=50 #设置每隔50ms读取帧

#flag+=10 #每隔10帧读取一帧

fr+=1

二 、通过连续的帧提取TVL1光流

安装依赖包:

pip3 install opencv-python==4.1.2.30

pip3 install opencv-contrib-python==4.1.2.30

def cal_for_frames(video_path):

frames = glob(os.path.join(video_path, '*.jpg'))

frames.sort()

flow = []

prev = cv2.imread(frames[0])

prev = cv2.cvtColor(prev, cv2.COLOR_BGR2GRAY)

for i, frame_curr in enumerate(frames[1:]):

curr = cv2.imread(frame_curr)

curr = cv2.cvtColor(curr, cv2.COLOR_BGR2GRAY)

tmp_flow = compute_TVL1(prev, curr)

flow.append(tmp_flow)

prev = curr

return flow

def compute_TVL1(prev, curr, bound=15):

"""Compute the TV-L1 optical flow."""

TVL1=cv2.optflow.DualTVL1OpticalFlow_create()

# TVL1 = cv2.DualTVL1OpticalFlow_create()

# TVL1=cv2.createOptFlow_DualTVL1()

flow = TVL1.calc(prev, curr, None)

assert flow.dtype == np.float32

flow = (flow + bound) * (255.0 / (2 * bound))

flow = np.round(flow).astype(int)

flow[flow >= 255] = 255

flow[flow <= 0] = 0

return flow

def save_flow(video_flows, flow_path):

if not os.path.exists(os.path.join(flow_path, 'u')):

os.mkdir(os.path.join(flow_path, 'u'))

if not os.path.exists(os.path.join(flow_path, 'v')):

os.mkdir(os.path.join(flow_path, 'v'))

for i, flow in enumerate(video_flows):

cv2.imwrite(os.path.join(flow_path,'u', "{:06d}.jpg".format(i)),

flow[:, :, 0])

cv2.imwrite(os.path.join(flow_path,'v', "{:06d}.jpg".format(i)),

flow[:, :, 1])

def extract_flow(video_path, flow_path):

flow = cal_for_frames(video_path)

save_flow(flow, flow_path)

print('complete:' + flow_path)

return

if __name__ == '__main__':

video_path=path_to_video #预先提取好的视频帧

save_path=path_to_save #保存光流的路径

extract_flow(video_path,save_path)

---------------------------------------------------------------------------------------------------------------

import cv2 cap = cv2.VideoCapture(file_path.encode('utf-8')) # file_path是文件的绝对路径,防止路径中含有中文时报错,需要解码

if cap.isOpened(): # 当成功打开视频时

cap.isOpened()返回True,否则返回False # get方法参数按顺序对应下表(从0开始编号)

rate = cap.get(5) # 帧速率

FrameNumber = cap.get(7) # 视频文件的帧数

duration = FrameNumber/rate/60 # 帧速率/视频总帧数 是时间,除以60之后单位是分钟

另外,cv2.VideoCapture(0)是打开本地摄像头

以下是opencv-python可以获取视频的相关信息,可以通过从0开始的序号获取

CAP_PROP_POS_MSEC 视频文件的当前位置(以毫秒为单位)或视频捕获时间戳。
CAP_PROP_POS_FRAMES 接下来要解码/捕获的帧的基于0的索引。
CAP_PROP_POS_AVI_RATIO 视频文件的相对位置:0 - 电影的开始,1 - 电影的结尾。
CAP_PROP_FRAME_WIDTH 视频流中帧的宽度。
CAP_PROP_FRAME_HEIGHT 视频流中帧的高度。
CAP_PROP_FPS 帧速率。
CAP_PROP_FOURCC 编解码器的4字符代码。

CAP_PROP_FRAME_COUNT 视频文件中的帧数。
CAP_PROP_FORMAT 返回的Mat对象的格式 retrieve() 。

CAP_PROP_MODE 指示当前捕获模式的特定于后端的值。
CAP_PROP_BRIGHTNESS 图像的亮度(仅适用于相机)。
CAP_PROP_CONTRAST 图像对比度(仅适用于相机)。
CAP_PROP_SATURATION 图像的饱和度(仅适用于相机)。
CAP_PROP_HUE 图像的色调(仅适用于相机)。
CAP_PROP_GAIN 图像的增益(仅适用于相机)。
CAP_PROP_EXPOSURE 曝光(仅适用于相机)。
CAP_PROP_CONVERT_RGB 布尔标志,指示是否应将图像转换为RGB。
CAP_PROP_WHITE_BALANCE_U 白平衡设置的U值(注意:目前仅支持DC1394 v 2.x后端)
CAP_PROP_WHITE_BALANCE_V 白平衡设置的V值(注意:目前仅支持DC1394 v 2.x后端)
CAP_PROP_RECTIFICATION 立体摄像机的整流标志(注意:目前仅支持DC1394 v 2.x后端)
CAP_PROP_ISO_SPEED摄像机 的ISO速度(注意:目前仅支持DC1394 v 2.x后端)
CAP_PROP_BUFFERSIZE 存储在内部缓冲存储器中的帧数(注意:目前仅支持DC1394 v 2.x后端)

注意:以上属性在获取时,通过对应的编号进行,上面所列出的属性,从0开始编号;

如: cap=cv2.VideoCapture(video_path)

      number_of_frame=cap.get(7)  //获取视频的帧数

来源 opencv-python获取视频时长_weixin_43249191的博客-CSDN博客_opencv获取视频时长
--------------------------------------------------------------------------------------------------------------------------------------------------------------

三、可视化光流

import cv2 as cv

import numpy as np

import os

path = 'path_to_videos'

videos = os.listdir(path)

TVL1 = cv.optflow.DualTVL1OpticalFlow_create()

for video in videos:

video_path = path + '/' + video

cap = cv.VideoCapture(video_path)

ret, frame1 = cap.read()

prvs = cv.cvtColor(frame1,cv.COLOR_BGR2GRAY)

hsv = np.zeros_like(frame1)

hsv[...,1] = 255

count = 0

while(True):

ret, frame2 = cap.read()

if not ret:

break

next = cv.cvtColor(frame2,cv.COLOR_BGR2GRAY)

# 返回一个两通道的光流向量,实际上是每个点的像素位移值

flow = TVL1.calc(prvs,next, None)

# 笛卡尔坐标转换为极坐标,获得极轴和极角

mag, ang = cv.cartToPolar(flow[...,0], flow[...,1])

hsv[...,0] = ang*180/np.pi/2 #角度

hsv[...,2] = cv.normalize(mag,None,0,255,cv.NORM_MINMAX)

bgr = cv.cvtColor(hsv,cv.COLOR_HSV2BGR)

path_ = path + '/' + os.path.basename(video).split('.')[0]

if not os.path.exists(path_):

os.makedirs(path_)

cv.imwrite(path_ + "/frame{0:06d}.jpg".format(count), bgr)

count += 1

prvs = next

cap.release()

cv.destroyAllWindows()

参考资料:win10+python3+opencv3 读取视频中的指定帧并存为图片_li_huifei的博客-CSDN博客

网址:基于opencv,使用python提取视频帧以及提取TVL1光流 https://www.yuejiaxmz.com/news/view/49703

相关内容

Python的生活小技巧
PyCharm+Python3.8+OpenCV4.1集成环境安装配置
小米视频免费短剧内测招募来了:2000部短剧免费看
基于python的膳食健康推荐系统
创意生活 +关注 已有 28 人关注 发表新帖
Python实现简便算法提升拼音输入法准确率与效率
2024江苏绿色节能家电以旧换新补贴领取及使用流程(图解)
2024长沙节能家电以旧换新补贴活动攻略(时间+使用+领取流程)
朋友圈「话题标签」= 全民推广视频号?
Python爬虫山东济南景点数据可视化和景点推荐系统 开题报告

随便看看