最近因为经常对视频进行操作,所以记录下Python用opencv来读写视频的方法。

一、opencv读视频

python调用opencv来读视频比较简单,可以直接调用cv2.VideoCapture来读取视频和摄像头,基本上,常见的avi和mp4都能够正常读取。cv2.VideoCapture是通过传入数字来读取对应的摄像头,或者通过传入一个路径字符串来读取对应的视频文件。

最简单直接的读取视频的例子如下:

import cv2

cap = cv2.VideoCapture(0)  #读取摄像头
#cap = cv2.VideoCapture("video.mp4")  #读取视频文件

while(True):
    ret, frame = cap.read()
    if ret:
        cv2.imshow("frame", frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
cap.release()

读取视频后,OpenCV提供了很多的视频相关的属性,我觉得常见且比较有用的几个属性见如下表格(完整表格见官网文档):

C/C++: CAP_PROP_POS_MSEC 

Python: cv.CAP_PROP_POS_MSEC

Current position of the video file in milliseconds.当前视频帧在第几毫秒

C/C++: CAP_PROP_POS_FRAMES 

Python: cv.CAP_PROP_POS_FRAMES

0-based index of the frame to be decoded/captured next.当前帧在视频中第几帧,从0开始

C/C++: CAP_PROP_POS_AVI_RATIO 

Python: cv.CAP_PROP_POS_AVI_RATIO

Relative position of the video file: 0=start of the film, 1=end of the film.视频帧在视频中的相对位置

C/C++: CAP_PROP_FRAME_WIDTH 

Python: cv.CAP_PROP_FRAME_WIDTH

Width of the frames in the video stream.视频帧宽度

C/C++: CAP_PROP_FRAME_HEIGHT 

Python: cv.CAP_PROP_FRAME_HEIGHT

Height of the frames in the video stream.视频帧高度

C/C++: CAP_PROP_FPS 

Python: cv.CAP_PROP_FPS

Frame rate.帧率

C/C++: CAP_PROP_FOURCC 

Python: cv.CAP_PROP_FOURCC

4-character code of codec. see VideoWriter::fourcc .视频编码格式

C/C++: CAP_PROP_FRAME_COUNT 

Python: cv.CAP_PROP_FRAME_COUNT

Number of frames in the video file.视频总帧数

 有了上面的属性后,要获取对应的属性值,可以通过cv2.VideoCapture的get方法来获取,同样,可以通过set方法来写属性:

size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fps = cap.get(cv2.CAP_PROP_FPS)

二、 opencv写视频

opencv写视频调用的是cv2.VideoWriter,cv2.VideoWriter需要传入的四个主要的参数:保存的视频路径、编码格式、帧率、视频帧尺寸。

简单的写视频的例子在上面读视频的例子基础上,稍微添加一点代码,例子如下:

import cv2

cap = cv2.VideoCapture(0)  #读取摄像头
#cap = cv2.VideoCapture("video.mp4")  #读取视频文件
fps = 15
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
videoWriter = cv2.VideoWriter('video.mp4', cv2.VideoWriter_fourcc('M','P','E','G'), fps, size)

while(True):
    ret, frame = cap.read()
    if ret:
        videoWriter.write(frame)
        cv2.imshow("frame", frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
cap.release()
videoWriter.release()

这里主要说下编码格式,常见的视频编码格式可以在找fourcc.org上面查找。

opencv中比较常见的编码格式有"DIVX"、”MJPG"、"XVID"、"MPEG"等,这几个基本上opencv都是自带的可以直接读写的,保存的文件格式可以是.mp4也可以是.avi,但是OpenCV并不是自带的支持所有格式的,有时候在工程中可能会遇到需要其它编码格式,例如在web中要显示的话,常见的还是h264这种支持流的格式,而这一种opencv是不自带的,所以需要通过其它途径来实现。

要想使用OpenCV来保存h264视频的话,需要使用额外的库,在windows上是比较简单的,直接下载openh264库来使用即可,使用方法也比较简单,到openh264的github上下载相关的文件,比如我用的opencv-python为3.4.3.18,它使用的openh264版本是1.7,所以就可以下载http://ciscobinary.openh264.org/openh264-1.7.0-win64.dll.bz2的版本,如下:

下载之后直接解压,放到脚本所在的路径下,然后修改上面写视频的编码格式,格式可以是'h','2','6','4'或者'x','2','6','4',如下:

videoWriter = cv2.VideoWriter('video.mp4', cv2.VideoWriter_fourcc('h','2','6','4'), fps, size)

Linux稍微麻烦一点,本来以为可以参照Windows这种做法从上面的路径下载库文件来使用,但实际上运行的时候并没有用,会有问题,所以没解决,后面在github上找到其他的方法,稍微麻烦一点点,这里还没整理好,就先不加了。

 

东风夜放花千树。更吹落、星如雨。

宝马雕车香满路。

凤箫声动,玉壶光转,一夜鱼龙舞。

蛾儿雪柳黄金缕。笑语盈盈暗香去。

众里寻他千百度。

蓦然回首,那人却在,灯火阑珊处。

  --辛弃疾 《青玉案·元夕》