opencv视频文件的读写与摄像头操作
1.实验目的
熟悉opencv读入视频和另存
2.实验设备
安装了python和pychrm的电脑一台
3.实验内容
读入一段视频和写入一段视频
4.实验原理
OpenCV提供了VideoCapture类和VideoWriter类来支持各种格式的视频文件。支持
的格式类型会因系统的不同而变化,但应该都支持AVI格式。在到达视频文件末尾之前,
VideoCapture类可通过read()函数来获取新的帧,每帧是一幅基于BGR格式的图像。
其实视频的读写和图片的读写是一样的,视频读写只是多了一个循环步骤,不断循环读或写视频的每一帧,这样就能显示和保存我们的视频。
opencv通过VideoCapture类对视频进行读取操作及调用摄像头。cv2.VideoCapture函数创建一个 VideoCapture 类的实例,如果传入对应的参数,可以直接打开视频文件或者要调用的摄像头。传入视频文件路径是打开视频文件操作,传入参数id为打开视频捕获设备及摄像头,如果只有一个摄像头可以填0 ,表示打开默认的摄像头。
函数原型:
vc = cv2.VideoCapture("视频地址路径")
rval, frame = vc.read()
rval表示是否成功获取帧(布尔值false或true) ,frame是捕获到的帧(也称图像)。
read()函数按帧读取视频的每一帧,该函数结合 VideoCapture::grab()和VideoCapture ()其中之一被调用,用于捕获、解码和返回下一个视频帧。这是一个最方便的函数,对于读取视频文件或者捕获从解码和返回刚刚捕获的帧,假如没有视频帧被捕获(相机没有连接或者视频文件中没有更多的帧)将返回 false。imshow()函数不断播放每一帧,就能够播放视频,最后我们有一个退出的判断if cv2.waitKey(50) & 0xff==ord('q'):break,当按下‘q’的时候跳出循环。
我们打开了视频还需要一个关闭操作,release()函数可以达到关闭视频文件或者摄像头的作用。我们用imshow()创建一个窗口时也需要destroyAllWindows()函数来关闭窗口。
保存视频文件:
函数原型:
fps=vc.get(cv2.CAP_PROP_FPS)
返回值是该视频一秒的图像数(也称帧率)
VideoWriter函数构建一个存储帧的容器,通过循环,把每一帧写入容器中,write函数为写入,这跟摄像头录一段视频是一样的都是不断写入每一帧图像到容器中。
get(CV_CAP_PROP_FRAME_WIDTH) :该方法可以获取到帧的高度
get(CV_CAP_PROP_FRAME_WIDTH) : 该方法可以获取到帧的宽度
get(CV_CAP_PROP_FRAME_HEIGHT) :该方法可以获取到帧的高度
get(CV_CAP_PROP_FPS): 该方法可以获取到帧率
get(CV_CAP_PROP_FRAME_COUNT) :该方法可以获取到帧的总帧数
Opencv的VideoCapture类可以获得摄像头的帧,但对摄像头而言,通常不是用视频的文件名来构造VideoCapure类,而是需要传递摄像头的设备索引,VideoCaptrue类对视频进行读取操作以及调用摄像头,也就是设备索引ID。接下来我们会捕获摄像头10秒的视频信息,并将其写入到一个AVI文件中。
当我们需要同步一组摄像头或一个多个摄像头时,read()方法就不再适合了,可用grad()和retritve()方法代替它。
首先我们用cv2. VideoCapture()函数打开摄像头,参数0等可以打开默认摄像头,如果默认笔记本/台式机只有一个USB摄像头,Index=0; 一般Index为0和1,根据具体情况区分,摄像头接入和断开会改变Index值。然后获取尺寸大小,因为我们够造用于存储视频的方法中需要用到。
cv2.VideoWriter函数够造存储信息的容器,这里必须指定视频编码器。编码器的可用性根据系统的不同而不同,下面是一些常用选项。
cv2.VideoWriter_fourcc ('P','I','M','1') 该选项是MPEG-1编码类型,文件拓展名为.avi
cv2.VideoWriter_fourcc ('I', '4', '2', '0') 该选项是一个未压缩的YUV颜色编码,是4:2:0色度子采样,这种编码有很好的兼容性,但会产生较大的文件,文件拓展名为.avi
cv2.VideoWriter_fourcc ('X', 'V', 'I', 'D') 该选项是 MPEG-4.4编码类型,如果希望得到的视频大小为平均值,推荐使用此选项,文件拓展名为.avi codec
cv2.VideoWriter_fourcc ('T', 'H', 'I', 'O') 该选项是一个Flash视频,文件拓展名为.flv
read()函数读取摄像头的下一帧。通过不断循环,就可以形成一段视频影像。write函数将每一帧写入容器中。
waitKey()的参数为等待键盘触发的时间,单位为毫秒,返回值是-1(表示没有键被按下)或者ASCII码,python提供了一个标准的ord(),该函数可以将字符串转换为ASCII码。opencv的窗口函数和waitKey()函数互相依赖,opencv的窗口只有在调用waitKey()函数时才会更新,waitKey()函数只有在opencv窗口成为活动窗口时,才能捕获输入信息。
5.实验步骤
打开pycharm。
我们右击相应的文件目录,选择new--->点击Python File,然后输入新建的文件名,点击确定,相应的.py文件就建好了,可以进行编写代码了。
1.播放一个视频
通过VideoCapture()函数可以打开摄像头和打开一个视频文件
import cv2
videoCapture=cv2.VideoCapture("images\768x576.avi")
接下来因为视频是由一帧一帧的图像构成的,我们要播放这个视频就要从初始帧开始播放到最后一帧,所以我们要用循环来播放每一帧。我们用read()函数来获取帧(即一张图像),它有两个返回值,第一个是一个布尔值,返回是否成功标识ret(True代表成功,False代表失败),frane为读取的视频帧。然后用imshow()函数显示图像,通过不到循环播放每一帧就形成了视频。waitKey()函数我们延迟100ms再播放下一帧或者按‘q’退出,最后我们还需要调用release函数释放视频流和调用destroyAllWindows函数关闭所有窗口。
while True:
ret,frmae=videoCapture.read()
cv2.imshow('move',frmae)
if cv2.waitKey(100) & 0xff==ord('q'):
break
cap.release()
cv2.destroyAllWindows()
运行我们代码。
运行结果
2.保存一个视频
OpenCV写视频,需要指定视频的格式,可以从原视频中获取; 使用VideoWriter类和write()函数。
VideoWriter类写入视频时,需要提供视频名,格式,码率(fps),帧的尺寸等参数。
基本流程:将一幅图像传递给VideoWriter类的writer()函数,该函数会将这幅图像加到VideoWriter类所指向的文件中,下面给出了一个示例,该示例读取AVI文件的帧,并采用YUV颜色编码将其写入到另一个帧中。
新建一个py文件。先读取视频文件。
import cv2
vc=cv2.VideoCapture("images\768x576.avi")
获取该视频的帧率,该视频应该是10帧的(1秒10张图像)
fps=videoCapture.get(cv2.CAP_PROP_FPS)
get获取视频流中帧的高度和宽度,该size参数会在VideoWriter类写入视频时用到
size=(int(vc.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(vc.get(cv2.CAP_PROP_FRAME_HEIGHT)))
构造VideoWriter类,指定写视频的格式,参数:写入的文件地址,VideoWriter_fourcc为视频编解码器(视频格式),帧率及尺寸。
cv2.VideoWriter_fourcc('I', '4', '2', '0'),该参数是YUV编码类型,文件名后缀为.avi
cv2.VideoWriter_fourcc('P', 'I', 'M', 'I'),该参数是MPEG-1编码类型,文件名后缀为.avi
cv2.VideoWriter_fourcc('X', 'V', 'I', 'D'),该参数是MPEG-4编码类型,文件名后缀为.avi
cv2.VideoWriter_fourcc('T', 'H', 'E', 'O'),该参数是Ogg Vorbis,文件名后缀为.ogv
cv2.VideoWriter_fourcc('F', 'L', 'V', '1'),该参数是Flash视频,文件名后缀为.flv
参数:保存的地址及文件名,格式,帧率及尺寸。
videoWriter=cv2.VideoWriter('images\768x576_move.avi',
cv2.VideoWriter_fourcc('I','4','2','0'),
fps,size)
读原视频的每一帧,success是布尔值(false或true)
success, frame = vc.read()
将一帧写入到videoWriter中,然后获取下一帧,不断循环写入就形成了视频文件
while success: videoWriter.write(frame) success,frame=videoCapture.read() ##获取下一帧
这样就把视频保存了,当然你也可以编码成其他的格式
运行结果
3.捕获摄像头的帧
VideoCapture类可以获得摄像头的帧,但对摄像头而言,通常不是用视频的文件名来构造VideoCapure类,而是需要传递摄像头的设备索引,VideoCaptrue类对视频进行读取操作以及调用摄像头。接下来我们会捕获摄像头10秒的视频信息,并将其写入到一个AVI文件中。
当我们需要同步一组摄像头或一个多头摄像头时,read()方法就不再适合了,可用grad()和retritve()方法代替它。
创建一个.py文件,VideoCapture函数打开摄像头。
import cv2
cameraCapture=cv2.VideoCapture(0)
get获取摄像头中帧的高度和宽度,该size参数会在VideoWriter类写入视频时用到。
fps=30
size=(int(cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
构造VideoWriter保存我们的摄像头信息,参数有:保存的路径和文件名,格式,帧率,尺寸,到时候会形成一个1秒30帧的视频。
videoWriter=cv2.VideoWriter('images\mi.avi', cv2.VideoWriter_fourcc('I','4','2','0'), fps,
size)
初始化用于循环 10秒钟*30 可以说就是300张图像组成的视频。
numFramesRemaining=10*fps-1
读取摄像头的每一帧,success是布尔值。
success,frame=cameraCapture.read()
判断success 的值是否为ture和numFramesRemaining是否为0。
while success and numFramesRemaining > 0:
将摄像头信息的每一帧写入到videoWriter中。将一帧写入videoWriter中,再获取下一帧,循环写入videoWriter,知道把300帧的图像写入
videoWriter.write(frame)
success,frame=cameraCapture.read() ##获取下一帧
numFramesRemaining -=1
调用release函数释放视频流
cameraCapture.release()
注:摄像头代号,0为默认摄像头,笔记本内建摄像头一般为 0,或者填写视频名称直接加载本地视频文件。