⚠️这个系列是自己瞎翻的,文法很丑,跳着跳着捡重要的部分翻,翻错了不负责,就这样。
⚠️基于3.4.3,Getting Started with Videos,附原文。
目标
- 学到读取视频,显示视频,并保存视频。
- 学会从摄像头捕捉视频并且显示它。
- 你会学到如下方法:cv.VideoCapture(), cv.VideoWriter()
从摄像头捕捉视频
通常,我们必须用摄像头捕捉到正在活动的流。OpenCV提供了一个非常简单的接口来干这件事儿。让我们从摄像头来捕捉流吧。 (我使用的是我自己本本上的内置摄像头),把它转换成灰度视频并且显示出来。只是一个入门级的简单任务。
要捕捉到摄像头,你需要创建一个 VideoCapture 对象。它的参数要么是一个摄像头设备的序号,要么是诗歌视频文件的文件名。摄像头设备的序号只是一个指定是哪一个摄像头的数字。通常也就连接一个摄像头,(我就是这样)。所以我简单的传入0 (或者 -1)。 你可以穿入1来选择第二个摄像头,等等。之后,你可以一帧一帧的捕获到摄像头,但到了最后,不要忘记释放捕获。
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
while(True):
# 逐帧捕获
ret, frame = cap.read()
# 我们对这帧图像进行操作
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 显示灰度以后的结果帧
cv.imshow('frame',gray)
if cv.waitKey(1) & 0xFF == ord('q'):
break
# 完事儿之后,释放捕捉。
cap.release()
cv.destroyAllWindows()
cap.read()
返回一个布尔值 (True
/False
)。如果这帧图像被正确读取,它就会是True。所以查看这个返回值,你可以知道我们是否已经逐帧走到了视频的结尾。
有时候,cap对象可能没有正确的被初始化捕捉。如果出现这种状况,这个代码会报错。你可以通过方法cap.isOpened()检测它是否正常的被初始化了。如果它返回True那就好,否则就用cap.open() 方法把它打开吧。
你可以通过使用 cap.get(propId) 方法来获取这个视频的一些特性,propId是从0到18的一些数字。每个数字都只是处了这个视频的一些属性(如果对于这个视频来说可用的话),然后完整的详情可以看这里 cv::VideoCapture::get() 。它们当中的某些值可 i被set方法 cap.set(propId, value) 该表称你想要的新值。
比如我可以查看某一帧的宽度和高度用 cap.get(cv.CAP_PROP_FRAME_WIDTH)
和 cap.get(cv.CAP_PROP_FRAME_HEIGHT)
。默认他给我640x480。点我想要把它改为320x240。我们只要使用 ret = cap.set(cv.CAP_PROP_FRAME_WIDTH,320)
以及 ret = cap.set(cv.CAP_PROP_FRAME_HEIGHT,240)。
提示
如果你遇到了报错,用其他的摄像头应用来确保你的摄像头是正常工作的(比如Linux的Cheese)。
从文件播放视频
和从摄像头捕获视频一样,只要把摄像头序号换成文件名。当逐帧显示视频的时候,也要为 cv.waitKey()
方法设置合适的参数。如果它的参数设置的太小,视频会播放的特别快,反之播放的就很慢(当然,如果你要用慢动作播放视频那么这就是方案)。正常情况下这个参数设置成 25 毫秒是比较合适的。
import numpy as np
import cv2 as cv
cap = cv.VideoCapture('vtest.avi')
while(cap.isOpened()):
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
cv.imshow('frame',gray)
if cv.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv.destroyAllWindows()
提示
确保你安装了 ffmpeg 或者 gstreamer 合适的版本。有时候,和错误安装的 ffmpeg 或者 gstreamer 一起工作是件头疼的事情。
保存视频
现在我们已经捕捉了视频,逐帧处理了它,现在我们像保存我们处理之后的视频。
对于图片来说,非常简单,只要使用 cv.imwrite() 。视频这里则需要一些额外的工作。
这次我们创建一个 VideoWriter 对象。我们需要指定一个输出文件的名字 (比如: output.avi)。然后我们需要指定 FourCC 码(译者注:FourCC/四字符码)详情在下一节讲。然后是每秒帧数 (译者注:fps/帧率) 也需要被当作参数传入。还有最后一个参数是 isColor 标记。如果它是True,译码器就会尝试彩色帧,否则就是灰度帧。
FourCC 是一个4字节的码,用于指定视频的编译码器。允许的码的列表可以查 fourcc.org。 它依赖这些模版。下面的这些编译码器在我电脑上是正常工作的。
- In Fedora: DIVX, XVID, MJPG, X264, WMV1, WMV2. (XVID 更胜一筹。MJPG 的结果更高清。 X264 则把视频压缩的很小。)
- In Windows: DIVX (More to be tested and added)
- In OSX: MJPG (.mp4), DIVX (.avi), X264 (.mkv).
FourCC 码像这样传入 cv.VideoWriter_fourcc('M','J','P','G') 或者
cv.VideoWriter_fourcc(*'MJPG') 。
接下来的代码从摄像头捕获,从垂直方向上点击每一帧并且保存它。
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
# Define the codec and create VideoWriter object
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv.flip(frame,0)
# write the flipped frame
out.write(frame)
cv.imshow('frame',frame)
if cv.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv.destroyAllWindows()