使用 OpenCV 从相机捕获实时视频

183 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

前言

在本节中,我们将学习如何使用 OpenCV 库捕获视频并提取图像帧,同时我们将捕获摄像机(例如,笔记本电脑的内置网络摄像头或 USB 摄像头)录制的实时视频流。

使用 OpenCV 从相机捕获实时视频

首先导入所需的库:

import cv2
import matplotlib.pyplot as plt

要使用 OpenCV 捕获视频,我们需要创建一个 VideoCapture 对象,它的参数可以是设备索引(实时视频)或视频文件的名称(本地文件):

vc = cv2.VideoCapture(0)
plt.ion()
if vc.isOpened(): # 读取第一帧
    is_capturing, frame = vc.read()    
    webcam_preview = plt.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))    
else:
    is_capturing = False

设备索引是指定摄像机的整数数字,通常,如果只有一台相机连接到计算机,只需传递 0 作为参数即可,如果有两台相机,则可以通过传递 1 来选择第二台相机,依次类推。

我们可以使用 isOpened() 方法检查 VideoCapture 对象是否正确初始化,如果正确初始化则返回 true。如果返回 true,那么我们可以使用函数 read() 读取第一帧以及所有后续帧。

read() 函数是从设备捕获数据的最方便的方法,它返回捕获的视频帧。如果没有捕获到任何帧(摄像机已断开连接,或者视频文件中没有更多帧),则该方法返回 false;使用布尔变量 is_capturing 确定是否可以捕获帧。

一旦第一帧被正确读取,我们就可以在 while 循环中逐帧捕获,直到视频的最后一帧。最后,一定要调用 VideoCapture 对象上的 release() 函数来释放设备。

以下代码演示了如何捕获实时视频流的前十帧。需要注意的是,OpenCV 使用 BGR 颜色格式,要显示具有真实 RGB 颜色的视频帧,必须使用转换函数 `cv2.cvtColor(frame, cv2.color_BGR2RGB):

frame_index = 1
while is_capturing:
    if frame_index > 10: break

    is_capturing, frame = vc.read()
    image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    webcam_preview.set_data(image)
    plt.title('Frame {0:d} '.format(frame_index))
    plt.draw()
    frame_index += 1
    try:    # 避免由 plt.pause 引起的 NotImplementedError
        plt.pause(2)
    except Exception:
        Pass
vc.release()

如果连接到计算机的相机设备可以正常工作,那么运行以上代码时,就可以看到相机捕获到的实时图像。此外, cv2.VideoCapture() 函数也可用于从磁盘读取视频文件,相对应的,可以使用 cv2.VideoWriter() 函数可将视频文件保存到本地磁盘文件中。