处理视频,最常用的开源工具箱非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
安装依赖包:
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博客