九、OpenCV中视频的录制

文章目录

一、OpenCV 视频录制概述

在 OpenCV 中,视频录制主要靠 cv::VideoWriter 类。它可以把连续的 cv::Mat 帧写入一个视频文件(如 .avi、.mp4 等)。

VideoWriter类

构造函数:

cpp 复制代码
VideoWriter::VideoWriter(const String &filename,
                         int fourcc,
                         double fps,
                         Size frameSize,
                         bool isColor = true);

参数说明:

  • filename:保存的视频文件名,例如 "output.avi"
  • fourcc:视频编码方式,如 CV_FOURCC('M','J','P','G') 或 VideoWriter::fourcc('M','J','P','G')
  • fps:帧率(帧每秒)
  • frameSize:视频每帧的尺寸,Size(width, height)
  • isColor:是否为彩色视频,true 彩色,false 灰度

常用编码(fourcc):

cpp 复制代码
int fourcc = VideoWriter::fourcc('M','J','P','G'); // AVI 常用
int fourcc_mp4 = VideoWriter::fourcc('a','v','c','1'); // MP4 H264

二、示例代码

示例 1:从摄像头录制视频

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

int main() {
    VideoCapture cap(0); // 打开摄像头
    if (!cap.isOpened()) {
        cout << "Cannot open camera" << 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));
    VideoWriter writer("output.avi",
                       VideoWriter::fourcc('M','J','P','G'),
                       30, Size(frame_width, frame_height));

    Mat frame;
    while (true) {
        cap >> frame;
        if (frame.empty()) break;

        writer.write(frame); // 写入视频

        imshow("Camera", frame);
        if (waitKey(1) == 27) break; // 按 ESC 停止
    }

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

示例 2:将视频文件处理后保存

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

int main() {
    VideoCapture cap("opencv_demo.mp4");
    if (!cap.isOpened()) return -1;

    int width = cap.get(CAP_PROP_FRAME_WIDTH);
    int height = cap.get(CAP_PROP_FRAME_HEIGHT);
    VideoWriter writer("output_processed.avi",
        VideoWriter::fourcc('M', 'J', 'P', 'G'),
        30, Size(width, height));

    Mat frame;
    while (true) {
        cap >> frame;
        if (frame.empty()) break;

        // 处理帧,例如灰度
        cvtColor(frame, frame, COLOR_BGR2GRAY);
        cvtColor(frame, frame, COLOR_GRAY2BGR); // 保持三通道以写入

        writer.write(frame);
    }
    cap.release();
    writer.release();
    return 0;
}

示例3:自动读取指定文件夹下所有图片生成视频

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>
#include <filesystem>
#include <vector>
#include <algorithm>
using namespace cv;
using namespace std;
namespace fs = std::filesystem;

int main() {
    string folderPath = "images"; // 图片文件夹路径
    string outputVideo = "output_video.avi";
    double fps = 30.0; // 帧率

    vector<string> imgFiles;

    // 遍历文件夹,收集图片路径
    for (const auto& entry : fs::directory_iterator(folderPath)) {
        if (entry.is_regular_file()) {
            string ext = entry.path().extension().string();
            // 支持 jpg/png/bmp
            if (ext == ".jpg" || ext == ".png" || ext == ".bmp")
                imgFiles.push_back(entry.path().string());
        }
    }

    if (imgFiles.empty()) {
        cout << "No images found in folder!" << endl;
        return -1;
    }

    // 按文件名排序
    sort(imgFiles.begin(), imgFiles.end());

    // 读取第一张图片获取尺寸
    Mat firstImg = imread(imgFiles[0]);
    if (firstImg.empty()) {
        cout << "Failed to read " << imgFiles[0] << endl;
        return -1;
    }
    Size frameSize(firstImg.cols, firstImg.rows);

    // 创建 VideoWriter
    VideoWriter writer(outputVideo,
                       VideoWriter::fourcc('M','J','P','G'),
                       fps,
                       frameSize,
                       true);

    if (!writer.isOpened()) {
        cout << "Cannot open VideoWriter!" << endl;
        return -1;
    }

    // 写入每张图片
    for (const auto& file : imgFiles) {
        Mat img = imread(file);
        if (img.empty()) {
            cout << "Failed to read " << file << endl;
            continue;
        }

        // 尺寸不一致就 resize
        if (img.size() != frameSize) {
            resize(img, img, frameSize);
        }

        writer.write(img);
    }

    writer.release();
    cout << "Video saved as " << outputVideo << endl;
    return 0;
}
相关推荐
技术支持者python,php7 小时前
物体识别:分类器模型
人工智能·opencv·计算机视觉
雍凉明月夜8 小时前
视觉opencv学习笔记Ⅳ
笔记·opencv·学习·计算机视觉
棒棒的皮皮10 小时前
【OpenCV】Python图像处理之图像表示方法
图像处理·python·opencv
棒棒的皮皮10 小时前
【OpenCV】Python图像处理之通道拆分与合并
图像处理·python·opencv·计算机视觉
向上的车轮10 小时前
图像处理OpenCV与深度学习框架YOLOv8的主要区别是什么?
图像处理·深度学习·opencv·yolov8
棒棒的皮皮10 小时前
【OpenCV】Python图像处理之像素操作
图像处理·python·opencv
向上的车轮10 小时前
基于深度学习与OpenCV的物体计数技术全解析
人工智能·深度学习·opencv
xrn199710 小时前
Android OpenCV SDK 编译教程(WSL2 Ubuntu 22.04 环境)
android·c++·opencv
棒棒的皮皮1 天前
【OpenCV】Python图像处理之读取与保存
图像处理·python·opencv
棒棒的皮皮1 天前
【OpenCV】Python图像处理之特征提取
图像处理·python·opencv