penCV基础操作-视频
1.获取视频和播放视频
还是先上代码,再去解释代码,这样便于学习。
import numpy as np import cv2 #读取摄像头,若想读取视频,参数0换成视频的路径+文件名 cap = cv2.VideoCapture(0) while(True): ret, frame = cap.read() cv2.imshow('frame',frame) if cv2.waitKey(1)== ord('q'): break cap.release() cv2.destroyAllWindows()
对照前面操作图像的代码,是不是发现很像。
cv2.VideoCapture()
创建了一个VideoCapture
对象,用来捕获视频。它的参数可以是设备的索引号,或是一个视频文件。设备的索引号是指定要用的摄像头,一般内置的摄像头的索引号为0,可以换成1或其他的数字调用其他的摄像头。
因为视频是一帧一帧获取的,所以接下来是个一个while True
循环,循环读取每一帧。
ret, frame = cap.read()
读取每一帧,其中ret
表示一个True/False
的布尔值,用来表示是否读取成功。frame
表示读取到的np.array
类型的每一帧,就是图片。
cv2.imshow('frame',frame)
将每一帧显示在一个叫frame的窗口上。这里解释一下,为什么这样显示在窗口上会产生视频的效果。前面操作图片的时候,我们提到过,显示多幅图像的时候,若cv2.imshow()
指定相同的窗口名,这样后面显示的图片会覆盖前面的图片,而产生一个窗口。这里视频显示也是同样的道理,每次while
循环,窗口'frame'
的名字不变,这样每一帧会覆盖上一帧,就产生了视频的效果。
if cv2.waitKey(1)== ord('q'):break
这里程序会等一毫秒,只要用户没有按下'q'
键,程序就会执行下一个循环,若按下了'q'
键,则程序会break
跳出while
循环。这里可以通过改变cv2.waitKey()
里面的时间参数,来改变视频的播放速度。
cap.release()
和cv2.destroyAllWindows()
是用来停止捕获视频和关闭相应的显示窗口的。
补充:
有时cv2.VideoCapture()
可能不能成功的初始化摄像头设备。这种情况下代码会报
错。你可以使用 cap.isOpened()
,来检查是否成功初始化了。如果返回值是 True
,那就没有问题。否则就要使用函数 cap.open()
。这是while True
可以改为 while cap.isOpened()
。
函数 cap.get(propId)
可以用来获得视频的一些参数信息。这里
propId 可以是 0 到 18 之间的任何整数。每一个数代表视频的一个属性:
• CV_CAP_PROP_POS_MSEC Current position of the video file in milliseconds.
(0-视频文件的当前位置(毫秒))
• CV_CAP_PROP_POS_FRAMES 0-based index of the frame to be decoded/captured next.
(1-下一步要解码/捕获的帧的基于0的索引)
• CV_CAP_PROP_POS_AVI_RATIO Relative position of the video file: 0 - start of the film, 1 - end of the film.
(2-视频文件的相对位置:0-胶片开始,1-胶片结束)
• CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream.
(3-视频流中帧的宽度)
• CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video stream.
(4-视频流中帧的高度)
• CV_CAP_PROP_FPS Frame rate.
(5-帧率)
• CV_CAP_PROP_FOURCC 4-character code of codec.
(6-编解码器的4字符代码)
• CV_CAP_PROP_FRAME_COUNT Number of frames in the video file.
(7-视频文件中的帧数。)
• CV_CAP_PROP_FORMAT Format of the Mat objects returned by retrieve() .
(8-返回mat对象的格式)
• CV_CAP_PROP_MODE Backend-specific value indicating the current capture mode.
(9-后端特定值,指示当前捕获模式)
• CV_CAP_PROP_BRIGHTNESS Brightness of the image (only for cameras).
(10-图像的亮度--仅适用于相机)
• CV_CAP_PROP_CONTRAST Contrast of the image (only for cameras).
(11-对比度--仅用于相机)
• CV_CAP_PROP_SATURATION Saturation of the image (only for cameras).
(12-饱和度--仅用于相机)
• CV_CAP_PROP_HUE Hue of the image (only for cameras).
(13-色调--仅用于相机)
• CV_CAP_PROP_GAIN Gain of the image (only for cameras).
(14-增益--仅用于相机)
• CV_CAP_PROP_EXPOSURE Exposure (only for cameras).
(15-曝光--仅用于相机)
• CV_CAP_PROP_CONVERT_RGB Boolean flags indicating whether images should be converted to RGB.
(16-布尔标志,指示是否应将图像转换为RGB。)
• CV_CAP_PROP_WHITE_BALANCE Currently unsupported
(17-当前不受支持)
• CV_CAP_PROP_RECTIFICATION Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently)
(18-立体摄像机的校正标志(注:目前仅受DC1394 v 2.x后端支持))
对应的,使用 cap.set(propId,value) 来修改视频属性,value 就是你想要设置成的新值。
2.保存视频
OpenCV保存视频稍稍有点麻烦,因为保存视频的时候涉及到一个格式的问题,普通的视频格式对应的编码器不一样,这里还需提供编码器。不多说了,直接上代码,从代码中学习。
import numpy as np import cv2 import sys cap = cv2.VideoCapture(r'testvideo.rmvb') #适用于OpenCV3,OpenCV2用cv2.cv.FOURCC(*'MJPG') #写成这样也行cv2.cv.FOURCC('M','J','P','G') fourcc = cv2.VideoWriter_fourcc(*'MJPG') out = cv2.VideoWriter('output.avi',fourcc,20.0,(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))) while cap.isOpened(): ret,frame = cap.read() if ret: out.write(frame) cv2.imshow('frame',frame) if cv2.waitKey(1) == ord('q'): break else: break cap.release() out.release() cv2.destroyAllWindows()
cv2.VideoWriter_fourcc(FourCC)
参数FourCC 就是一个 4 字节码,用来确定视频的编码格式。可用的编码列表可以从fourcc.org查到。这种编码格式是依赖于系统平台的,查到的许多编码不一定能用。
cv2.VideoWriter()
创建一个 VideoWriter
的对象。参数一:一个输出文件的名字;参数二:FourCC
编码;参数三:播放频率;参数四:帧的大小(视频的长和宽);参数五:是否为彩色,True
为彩色,False
为灰度。
接下来while
循环里就是读取每一帧,再向目标写入每一帧了,跟前面大致相同,这里就不多说了。
最后三行是关闭读取操作,写入操作和相应的显示窗口。
3.总结
视频操作的基本操作大体就这么多了,读者只要明白视频操作跟图像操作本质上没有区别。
还有一点不是很重要,但是不知道的话,有时遇到问题的话,会很头疼。在OpenCV中读取到彩色图片是BGR形式的,而不是通常所用的RGB形式的,有时用其他的图像处理库去显示OpenCV读取的图像,需要将BGR转为RGB, 颜色空间转换后面会详细讲的。
这里有人会问了,为什么读取的图片是BGR形式的,显示出来还是正常的RGB显示的呢?
其实,读者要弄明白一件事,在计算机中存储的图像,包括所有的图像处理时读取的图像,都是以数组或者说是矩阵的形式存在的。存储和读取的时候,计算机和人们并不关心这个数组或者矩阵是什么样子的,计算机和人只关心怎么去显示图像。比如,图片虽然存储成RGB形式的三通道矩阵,但计算机程序显示的时候,程序可以显示成RGB,BGR,GBR,BRG….,显示这一步完全是程序控制的。读者好好体会一下,其中的意思。