Python-OpenCV中的VideoCapture类的官方文档:
https://docs.opencv.org/4.0.0/d8/dfe/classcv_1_1VideoCapture.html
VideoCapture()是用于从视频文件、图片序列、摄像头捕获视频的类;
#!/usr/bin/env python
'''
VideoCapture()的使用
'''
import cv2
import argparse
import os
import pdb
# 构造参数解析并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-v", “–videoPath”, default="./video_1.mp4", help=“path to input video”)
ap.add_argument("-o", “–outputPath”, default=“grabImages”, help=“path to output frames”)
args = vars(ap.parse_args())
# 初始化,并读取第一帧
# rval表示是否成功获取帧
# frame是捕获到的图像
vc = cv2.VideoCapture(args[“videoPath”])
rval, frame = vc.read()
# 获取视频fps
fps = vc.get(cv2.CAP_PROP_FPS)
# 获取视频总帧数
frame_all = vc.get(cv2.CAP_PROP_FRAME_COUNT)
print("[INFO] 视频FPS: {}".format(fps))
print("[INFO] 视频总帧数: {}".format(frame_all))
print("[INFO] 视频时长: {}s".format(frame_all/fps))
outputPath = os.path.sep.join([args[“outputPath”]])
if os.path.exists(outputPath) is False:
print("[INFO] 创建文件夹,用于保存提取的帧")
os.mkdir(outputPath)
# 每隔100帧保存一张图片
frame_interval = 100
# 统计当前帧
frame_count = 1
# 保存图片个数
count = 0
while rval:
rval, frame = vc.read()
if frame_count % frame_interval == 0:
filename = os.path.sep.join([outputPath, “test_{}.jpg”.format(count)])
cv2.imwrite(filename, frame)
count += 1
print(“保存图片:{}”.format(filename))
frame_count += 1
c = cv2.waitKey(1)
if c == 27:
break
# 关闭视频文件
vc.release()
print("[INFO] 总共保存:{}张图片".format(count))
cv2.destroyAllWindows()
cap= cv2.VideoCapture(args[“videoPath”])
cap = cv2.VideoCapture(0)
VideoCapture()中参数是0,表示打开笔记本的内置摄像头。
cap = cv2.VideoCapture("…/test.avi")
VideoCapture("…/test.avi"),表示参数是视频文件路径则打开视频。
ret,frame = cap.read()
cap.read()按帧读取视频,ret,frame是cap.read()方法的两个返回值。
ret是布尔值,如果读取帧正确,则返回True,如果文件读取到结尾,则返回False。frame就是每一帧的图像,是个三维矩阵。
c=cv2.waitKey(1)
c得到的是键盘输入的ASCII码,esc键对应的ASCII码是27,即按esc键时if条件句成立
waitKey()方法本身表示等待键盘输入,
参数是1,表示延时1ms切换到下一帧图像,对于视频而言;
参数为0,如cv2.waitKey(0)只显示当前帧图像,相当于视频暂停,;
参数过大如cv2.waitKey(1000),会因为延时过久而感觉到卡顿。
调用release()释放摄像头
调用destroyAllWindows()关闭所有图像窗口
OpenCV 底层是用 FFMEPG 进行多媒体开发的,所以 OpenCV 它的长项不在于此,它只是提供了这种能力而已,如果要针对多媒体文件做复杂的处理,推荐的还是 FFMEPG 专业库。
OpenCV 用来创建视频文件的类是 VideoWriter。
文件后缀名
我们一般都知道视频文件是 .mp4、.3gp、.rmvb 等等格式的,后缀名是为了告诉用户或者操作系统,它的内容是什么格式的,方便用专业的工具或者软件操作它们。
文件格式
我们可以将一个视频文件看做一个容器,这个容器里面有视频画面数据、音频数据、字幕数据等等。
不同的文件格式如 mp4、avi、mkv 等等,它们存放打包数据的方式不一样,文件内部文件编码方式也可能不一样。
编码格式
视频容器中,一般有视频和音频数据,它们采取的编码方式不一样。
视频常见的编码方式通常有: x264、h264、mpeg-4
音频常见的编码方式通常有: mp3、AAC、flac
编码的目的主要是为了高效存储和传输,如果你不采用编码压缩的话,那么视频可以看做是一系列的图片序列,体积会非常大。
编码器和解码器
把视频或者音频按照编码格式,编码成特定文件格式需要编码器的参与,不然每次开发重新写代码代价很高。
把特定文件格式解码成特定的编码格式数据,这个过程称为解码,需要解码器的存在。
解码器和编码器都有开源的或者收费的工具库,极大方便了开发者。
FPS 帧率
frame per second,每秒钟有多少帧图像。
fps 越高,细节越好,体验也越好,但是文件容量也越高。
VideoWriter(filename, fourcc, fps, frameSize[, isColor])
filename:要保存的文件的路径
fourcc:指定编码器
fps:要保存的视频的帧率
frameSize:要保存的文件的画面尺寸
isColor:指示是黑白画面还是彩色的画面
fourcc 本身是一个 32 位的无符号数值,用 4 个字母表示采用的编码器。 常用的有 “DIVX"、”MJPG"、“XVID”、“X264"。fourcc可用的列表。
代码示例
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
# write the flipped frame
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
这段代码的目的就是获取摄像头的视频流,然后保存到本地,帧率是 20fps,尺寸是640*480.
如果需要读取视频文件,那么就将 VideoCapture 指定文件路径。
如果将图片序列合成为视频文件,原理也一样,一张一张读取,然后写到 VideoWriter 当中去。