OpenCV 4.11.0
开源计算机视觉库
加载中…
搜索中…
无匹配项
视频入门

目标

从摄像头捕获视频

通常,我们需要用摄像头捕获实时视频流。OpenCV提供了一个非常简单的接口来实现这一点。让我们从摄像头(我使用的是笔记本电脑内置的网络摄像头)捕获视频,将其转换为灰度视频并显示它。只是一个简单的入门任务。

要捕获视频,你需要创建一个VideoCapture对象。它的参数可以是设备索引或视频文件的名称。设备索引只是一个数字,用于指定哪个摄像头。通常会连接一个摄像头(像我的情况一样)。所以我只需传入0(或-1)。你可以通过传入1等来选择第二个摄像头。之后,你可以逐帧捕获。但在最后,不要忘记释放捕获。

import numpy as np
import cv2 as cv
if not cap.isOpened()
print("无法打开摄像头")
exit()
while True
# 逐帧捕获
ret, frame = cap.read()
# 如果帧读取正确,ret为True
if not ret
print("无法接收帧(流结束?)。退出…")
break
# 对帧的操作在此处进行
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 显示结果帧
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q')
break
# 完成所有操作后,释放捕获
cap.release()
用于从视频文件、图像序列或摄像头捕获视频的类。
定义 videoio.hpp:766
void imshow(const String &winname, InputArray mat)
在指定的窗口中显示图像。
int waitKey(int delay=0)
等待按下按键。
void destroyAllWindows()
销毁所有HighGUI窗口。
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0, AlgorithmHint hint=cv::ALGO_HINT_DEFAULT)
将图像从一种颜色空间转换为另一种颜色空间。

cap.read()返回一个布尔值(True/False)。如果帧读取正确,则为True。因此,你可以通过检查此返回值来检查视频的结尾。

有时,cap可能没有初始化捕获。在这种情况下,此代码会显示错误。你可以通过cap.isOpened()方法检查它是否已初始化。如果为True,则表示已初始化。否则,使用cap.open()打开它。

你还可以使用cap.get(propId)方法访问此视频的一些功能,其中propId是从0到18的数字。每个数字都表示视频的一个属性(如果适用于该视频)。完整的详细信息可以在这里查看:cv::VideoCapture::get()。其中一些值可以使用cap.set(propId, value)修改。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()
# 如果帧读取正确,ret为True
if not ret
print("无法接收帧(流结束?)。退出…")
break
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q')
break
cap.release()
注意
确保安装了正确的ffmpeg或gstreamer版本。有时使用视频捕获会很麻烦,主要是因为ffmpeg/gstreamer安装错误。

保存视频

因此,我们捕获视频并逐帧处理它,并且我们想要保存该视频。对于图像,这非常简单:只需使用cv.imwrite()。在这里,需要做更多的工作。

这次我们创建一个VideoWriter对象。我们应该指定输出文件名(例如:output.avi)。然后我们应该指定FourCC代码(下一段详细介绍)。然后应该传递每秒帧数 (fps) 和帧大小。最后一个是isColor标志。如果为True,则编码器期望彩色帧,否则它使用灰度帧。

FourCC是一个4字节代码,用于指定视频编解码器。可在fourcc.org找到可用代码的列表。它是平台相关的。以下编解码器对我来说运行良好。

  • 在Fedora上:DIVX、XVID、MJPG、X264、WMV1、WMV2。(XVID更可取。MJPG会导致视频大小很大。X264生成的视频大小非常小)
  • 在Windows上:DIVX(更多需要测试和添加)
  • 在OSX上:MJPG(.mp4)、DIVX(.avi)、X264(.mkv)。

FourCC代码作为’cv.VideoWriter_fourcc('M','J','P','G')`或`cv.VideoWriter_fourcc(*'MJPG')`传递给MJPG。

以下代码捕获摄像头画面,垂直翻转每一帧,并保存视频。

import numpy as np
import cv2 as cv
# 定义编解码器并创建 VideoWriter 对象
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("无法接收帧(流结束?)。退出…")
break
frame = cv.flip(frame, 0)
# 写入翻转后的帧
out.write(frame)
cv.imshow('frame', frame)
if cv.waitKey(1) == ord('q')
break
# 如果作业完成,释放所有资源
cap.release()
out.release()
视频写入器类。
定义 videoio.hpp:1065
void flip(InputArray src, OutputArray dst, int flipCode)
围绕垂直轴、水平轴或同时围绕两个轴翻转二维数组。