cv.VideoCapture() | 从视频文件、图像序列或相机中捕获视频的类 |
cv.VideoWriter() | 捕获一个视频并逐帧处理它,保存想要的视频 |
通常,我们必须用相机捕捉实时流。OpenCV 提供了一个非常简单的接口来执行此操作。让我们从相机中捕捉视频(我使用笔记本电脑上的内置网络摄像头),将其转换为灰度视频并显示。只需一个简单的任务即可开始。
要捕获视频,您需要创建一个VideoCapture对象。它的参数可以是设备索引或视频文件的名称。设备索引只是指定哪个相机的数字。通常会连接一台相机(如我的情况)。所以我只是传递0(或-1)。您可以通过传递 1 来选择第二个相机,依此类推。之后,您可以逐帧捕获。但最后,不要忘记释放捕获。
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# Capture frame-by-frame(逐帧捕捉)
ret, frame = cap.read()
# if frame is read correctly ret is True(如果帧被正确读取 ret 为 Tru)
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# Our operations on the frame come here(我们对帧的操作到这里)
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# Display the resulting frame(显示结果帧)
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q'):
break
# When everything done, release the capture(一切完成后,释放捕获)
cap.release()
cv.destroyAllWindows()
cap.read()返回一个布尔值 ( True
/ False
)。如果帧被正确读取,它将是True
. 因此,您可以通过检查此返回值来检查视频的结尾。
有时,cap 可能没有初始化捕获。在这种情况下,此代码显示错误。您可以通过cap.isOpened()方法检查它是否已初始化。如果是True
,好的。否则使cap.open()打开它。
您还可以使用cap.get(propId)方法访问此视频的某些功能,其中 propId 是从 0 到 18 的数字。每个数字表示视频的一个属性(如果它适用于该视频)。完整的细节可以在这里看到cv::VideoCapture::get()。其中一些值可以使用cap.set(propId, value)进行修改。值是您想要的新值。
例如,我可以通过和检查框架的宽度和高度。默认情况下它给我 640x480。但我想将其修改为 320x240。只需使用cap.get(cv.CAP_PROP_FRAME_WIDTH)cap.get(cv.CAP_PROP_FRAME_HEIGHT)
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()
# if frame is read correctly ret is True(如果帧被正确读取 ret 为 True)
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q'):
break
cap.release()
cv.destroyAllWindows()
笔记
确保安装了正确版本的 ffmpeg 或 gstreamer。有时使用视频捕获很头疼,主要是由于 ffmpeg/gstreamer 安装错误。
所以我们捕获一个视频并逐帧处理它,我们想要保存该视频。对于图像,它非常简单:只需使cv.imwrite(). 在这里,需要做更多的工作。
这次我们创建了一个VideoWriter对象。我们应该指定输出文件名(例如:output.avi)。然后我们应该指定FourCC代码(下一段中的详细信息)。然后应传递每秒帧数 (fps) 和帧大小。最后一个是isColor标志。如果是True
,编码器期望彩色帧,否则它适用于灰度帧。
FourCC是一个 4 字节的代码,用于指定视频编解码器。可用代码列表可fourcc.org中找到。它依赖于平台。以下编解码器对我来说很好用。
FourCC 代码作为 MJPG 的 `cv.VideoWriter_fourcc('M','J','P','G') or
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 not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
frame = cv.flip(frame, 0)
# write the flipped frame
out.write(frame)
cv.imshow('frame', frame)
if cv.waitKey(1) == ord('q'):
break
# Release everything if job is finished
cap.release()
out.release()