九、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;
}
相关推荐
春日见9 小时前
眼在手上外参标定保姆级教学(vscode + opencv)
linux·运维·服务器·数码相机·opencv·ubuntu·3d
AI_567811 小时前
从“3秒一帧”到“实时识别”——ARM平台OpenCV优化实战
arm开发·人工智能·opencv
Jerryhut15 小时前
Opencv总结2——图像金字塔与轮廓检测
人工智能·opencv·计算机视觉
那雨倾城16 小时前
用 YOLO Pose + Segmentation 在PiscCode构建“语义佛光”:一次实时视觉语义融合实验
图像处理·python·opencv·算法·yolo·计算机视觉·视觉检测
编码小哥17 小时前
OpenCV仿射变换与透视变换实战
人工智能·opencv·计算机视觉
棒棒的皮皮1 天前
【OpenCV】Python图像处理形态学之膨胀
图像处理·python·opencv·计算机视觉
智驱力人工智能2 天前
仓库园区无人机烟雾识别:构建立体化、智能化的早期火灾预警体系 无人机烟雾检测 无人机动态烟雾分析AI系统 无人机辅助火灾救援系统
人工智能·opencv·算法·目标检测·架构·无人机·边缘计算
格林威2 天前
双目视觉标定:消除视差误差的7种核心方案,附OpenCV+Halcon实现代码!
人工智能·数码相机·opencv·计算机视觉·视觉检测·制造
却道天凉_好个秋2 天前
OpenCV(四十四):SIFT计算描述子
人工智能·opencv·计算机视觉
智驱力人工智能2 天前
森林防火无人机火焰监测系统 构建“天空地”一体化智能防火体系 无人机火焰检测,支持红色火焰检测 城市高层建筑无人机火焰识别
人工智能·深度学习·opencv·算法·目标检测·无人机·边缘计算