16.OpenCV摄像头捕获、视频读取与保存

OpenCV摄像头捕获、视频读取与保存

在计算机视觉和图像处理领域,视频处理是非常常见的任务。无论是实时监控、视频分析,还是数据采集与存储,OpenCV 都提供了简单易用的接口。本文将详细介绍如何使用 OpenCV C++ 实现以下功能:

  • 摄像头捕获与显示:利用摄像头实时获取视频流并显示到窗口上。
  • 实时视频保存:将捕获的视频实时写入文件。
  • 视频读取与播放:从保存的视频文件中读取并显示视频内容。

下面我们将逐步讲解这些操作的原理、主要函数及示例代码。
过多API参考官方文档opencv API文档

1. 摄像头捕获与显示

利用 OpenCV 中的 cv::VideoCapture 类,可以方便地从摄像头(或其它视频源)中读取视频帧。常用步骤如下:

  1. 创建 VideoCapture 对象:通过设备索引(例如 0 表示默认摄像头)打开摄像头。
  2. 循环读取视频帧:使用 read>> 操作符获取每一帧图像。
  3. 显示视频帧:利用 imshow 函数在窗口中实时显示视频内容。
  4. 退出条件:一般通过检测按键(例如 ESC 键)实现退出循环。
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    // 打开默认摄像头(设备索引为 0)
    VideoCapture cap(0);
    if (!cap.isOpened()) {
        cerr << "无法打开摄像头!" << endl;
        return -1;
    }

    // 设置摄像头分辨率(可选)
    cap.set(CAP_PROP_FRAME_WIDTH, 640);
    cap.set(CAP_PROP_FRAME_HEIGHT, 480);

    Mat frame;
    while (true) {
        // 读取当前帧
        cap >> frame;
        if (frame.empty()) {
            cerr << "读取帧失败!" << endl;
            break;
        }

        // 显示当前帧
        imshow("摄像头实时视频", frame);

        // 按 ESC 键退出循环
        if (waitKey(30) == 27)
            break;
    }

    cap.release();
    destroyAllWindows();
    return 0;
}

在该示例中,我们通过循环不断读取摄像头视频帧,并在窗口中显示。当用户按下 ESC 键时,退出程序。

2. 实时视频保存

为了将实时视频保存到文件中,OpenCV 提供了 cv::VideoWriter 类。使用步骤如下:

  1. 定义输出视频文件名和编码器:可以通过 FOURCC 码指定视频编码格式(如 XVIDMJPG 等)。
  2. 创建 VideoWriter 对象:指定输出文件名、编码器、帧率和视频尺寸。
  3. 在捕获循环中写入视频帧:使用 write 方法将当前帧写入视频文件。
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    // 打开默认摄像头
    VideoCapture cap(0);
    if (!cap.isOpened()) {
        cerr << "无法打开摄像头!" << endl;
        return -1;
    }

    // 获取视频帧尺寸
    int frame_width = static_cast<int>(cap.get(CAP_PROP_FRAME_WIDTH));
    int frame_height = static_cast<int>(cap.get(CAP_PROP_FRAME_HEIGHT));
    Size frameSize(frame_width, frame_height);

    // 定义视频编码器及输出文件名(例如保存为 output.avi)
    int codec = VideoWriter::fourcc('X', 'V', 'I', 'D');
    double fps = 30.0; // 设置帧率
    VideoWriter writer("output.avi", codec, fps, frameSize, true);
    if (!writer.isOpened()) {
        cerr << "无法打开视频写入对象!" << endl;
        return -1;
    }

    Mat frame;
    while (true) {
        cap >> frame;
        if (frame.empty()) {
            cerr << "读取帧失败!" << endl;
            break;
        }

        // 写入视频帧到文件
        writer.write(frame);

        // 显示当前帧
        imshow("摄像头实时视频", frame);
        if (waitKey(30) == 27)
            break;
    }

    cap.release();
    writer.release();
    destroyAllWindows();
    return 0;
}

3. 视频读取与播放

除了实时捕获摄像头视频,OpenCV 也可以读取已经保存的视频文件进行播放和处理。使用步骤如下:

  1. 创建 VideoCapture 对象:传入视频文件路径打开视频文件。
  2. 循环读取视频帧:读取每一帧并显示。
  3. 结束条件:检测到视频结束或按键退出循环。
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    // 打开视频文件(请确保文件路径正确)
    string videoPath = "output.avi";
    VideoCapture cap(videoPath);
    if (!cap.isOpened()) {
        cerr << "无法打开视频文件:" << videoPath << endl;
        return -1;
    }
    
    // 获取视频基本信息
    int frame_width  = static_cast<int>(cap.get(CAP_PROP_FRAME_WIDTH));
    int frame_height = static_cast<int>(cap.get(CAP_PROP_FRAME_HEIGHT));
    int frame_count  = static_cast<int>(cap.get(CAP_PROP_FRAME_COUNT));
    double fps       = cap.get(CAP_PROP_FPS);
    
    cout << "视频基本信息:" << endl;
    cout << "    分辨率: " << frame_width << " x " << frame_height << endl;
    cout << "    总帧数: " << frame_count << endl;
    cout << "    帧率:   " << fps << " fps" << endl;
    
    // 创建显示窗口
    namedWindow("视频播放", WINDOW_AUTOSIZE);
    
    Mat frame;
    // 根据视频帧率计算延时(单位:毫秒),避免播放过快
    int delay = (fps > 0) ? cvRound(1000.0 / fps) : 30;
    
    while (true) {
        cap >> frame;
        if (frame.empty()) {
            cout << "视频播放结束!" << endl;
            break;
        }
        
        imshow("视频播放", frame);
        
        // 按 ESC 键退出
        if (waitKey(delay) == 27)
            break;
    }
    
    cap.release();
    destroyAllWindows();
    return 0;
}

在这个示例中,我们从保存的 “output.avi” 文件中读取视频帧和基本信息,并通过窗口播放。当视频结束或用户按下 ESC 键时,程序退出。

4. 小结

本文详细介绍了 OpenCV C++ 中摄像头捕获、视频保存以及视频读取与播放的基本方法和示例代码,主要内容包括:

  • 摄像头捕获与显示:利用 cv::VideoCapture 读取实时视频帧并通过 imshow 显示。
  • 实时视频保存:使用 cv::VideoWriter 将视频帧写入文件,实现视频保存功能。
  • 视频读取与播放:通过 cv::VideoCapture 打开视频文件并循环读取显示视频帧。

通过掌握这些基础操作,开发者可以轻松构建实时监控、视频处理和数据采集等应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值