当前位置: 首页 > news >正文

opencv 之 视频类 VideoCapture、VideoWriter详细介绍

opencv 之 视频类 VideoCapture、VideoWriter 详细介绍

  • VideoCapture 用于打开视频文件或者摄像头及设置相关属性
  • VideoWriter 用于保存视频文件及设置相关属性

1. VideoCapture

  • cv::VideoCapture 是 OpenCV 中用于从视频文件、图像序列或摄像头捕获视频的类。它是 OpenCV 视频处理模块的核心类之一。

  • cv::VideoCapture 提供了以下主要功能:

    • 从视频文件(如 .avi, .mp4 等)读取帧
    • 摄像头捕获实时视频流
    • 从图像序列(一系列编号图像)读取帧
    • 获取和设置视频属性(如帧率、分辨率等)
  • 构造函数

// 默认构造函数
cv::VideoCapture();// 从文件或设备构造
cv::VideoCapture(const String& filename, int apiPreference = CAP_ANY);
cv::VideoCapture(int index, int apiPreference = CAP_ANY);参数说明:filename:视频文件名或图像序列模式(如 "img_%02d.jpg")
index:摄像头索引(0 通常是默认摄像头)
apiPreference:指定使用的后端 API(如 CAP_FFMPEG, CAP_V4L2 等)
  • 常用方法
//打开视频源
bool open(const String& filename, int apiPreference = CAP_ANY);
bool open(int index, int apiPreference = CAP_ANY);//检查是否成功打开
bool isOpened() const;
//读取帧
// 读取下一帧到 image
bool read(OutputArray image);// 等同于 read(),但返回是否成功
VideoCapture& operator >> (Mat& image);// 抓取下一帧(不解码)
bool grab();// 解码并返回抓取的帧
bool retrieve(OutputArray image, int flag = 0);
//获取/设置属性
double get(int propId) const;
bool set(int propId, double value);//常用属性 ID(在 cv::VideoCaptureProperties 中定义):
CAP_PROP_FRAME_WIDTH - 帧宽度
CAP_PROP_FRAME_HEIGHT - 帧高度
CAP_PROP_FPS - 帧率
CAP_PROP_FRAME_COUNT - 总帧数(视频文件)
CAP_PROP_POS_FRAMES - 当前帧位置
CAP_PROP_POS_MSEC - 当前时间位置(毫秒)
//释放资源
void release();

使用示例

//示例1:从摄像头捕获
#include <opencv2/opencv.hpp>int main() {cv::VideoCapture cap(0); // 打开默认摄像头if (!cap.isOpened()) {std::cerr << "无法打开摄像头" << std::endl;return -1;}cv::Mat frame;while (true) {cap >> frame; // 或 cap.read(frame);if (frame.empty()) break;cv::imshow("摄像头", frame);if (cv::waitKey(30) >= 0) break;}cap.release();return 0;
}
//示例2:从视频文件读取
#include <opencv2/opencv.hpp>int main() {cv::VideoCapture cap("video.mp4");if (!cap.isOpened()) {std::cerr << "无法打开视频文件" << std::endl;return -1;}// 获取视频属性double fps = cap.get(cv::CAP_PROP_FPS);int width = cap.get(cv::CAP_PROP_FRAME_WIDTH);int height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);std::cout << "视频信息: " << width << "x" << height << ", " << fps << " FPS" << std::endl;cv::Mat frame;while (cap.read(frame)) {cv::imshow("视频播放", frame);if (cv::waitKey(1000/fps) >= 0) break; // 按正确帧率显示}cap.release();return 0;
}
//示例3:从图像序列读取
cv::VideoCapture cap("img_%02d.jpg"); // 读取 img_00.jpg, img_01.jpg, ...
注意事项:
- 使用后务必调用 release() 释放资源
- 检查 isOpened() 确保视频源已正确打开
- 对于大视频文件,考虑使用 grab() + retrieve() 以提高性能
- 不同视频格式和编解码器的支持取决于安装的 OpenCV 版本和编解码器
- 在多线程环境中使用时需要注意线程安全
  • 高级用法
//使用特定后端 API
cv::VideoCapture cap("video.mp4", cv::CAP_FFMPEG);//设置缓冲区大小
cap.set(cv::CAP_PROP_BUFFERSIZE, 1); // 减少延迟//多摄像头同步
cv::VideoCapture cap1(0), cap2(1);
cap1.grab(); cap2.grab(); // 同步抓取
cv::Mat frame1, frame2;
cap1.retrieve(frame1);
cap2.retrieve(frame2);

2. cv::VideoWriter

  • cv::VideoWriter 是 OpenCV 中用于写入视频文件或图像序列的类,与 cv::VideoCapture 相对应,用于视频的保存和输出。

  • cv::VideoWriter 提供以下主要功能:

    • 将帧序列写入视频文件
    • 支持多种视频格式(如 .avi, .mp4 等)
    • 可设置视频编码器、帧率、分辨率等参数
    • 支持多通道图像写入
  • 构造函数

// 默认构造函数
cv::VideoWriter();// 带参数的构造函数
cv::VideoWriter(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true);参数说明:
filename:输出视频文件名
fourcc:四字符编码的编解码器(如 "MJPG", "X264")
fps:输出视频的帧率
frameSize:视频帧的大小(宽度和高度)
isColor:是否为彩色视频(默认为 true
  • 常用方法
//打开视频写入器
bool open(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true);//检查是否成功打开
bool isOpened() const;
  • 写入帧
// 写入一帧
void write(InputArray image);// 等同于 write()
VideoWriter& operator << (const Mat& image);//释放资源
void release();
  • 四字符编码(FourCC)
FourCC 是视频编解码器的四字符代码,常见的有:"MJPG" - Motion-JPEG
"XVID" - XVID MPEG-4
"X264" - H.264/AVC
"MP4V" - MPEG-4
"AVC1" - H.264
"H264" - H.264
"VP80" - VP8
//可以使用 cv::VideoWriter::fourcc() 函数生成 FourCC 代码:
int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');

使用示例

示例1:创建并写入视频文件
#include <opencv2/opencv.hpp>int main() {// 创建一个 VideoWriter 对象cv::VideoWriter writer;// 设置视频参数int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G'); // 编解码器double fps = 30.0; // 帧率cv::Size frameSize(640, 480); // 帧大小// 打开视频文件writer.open("output.avi", fourcc, fps, frameSize, true);if (!writer.isOpened()) {std::cerr << "无法创建视频文件" << std::endl;return -1;}// 创建一些示例帧(这里用彩色渐变作为示例)for (int i = 0; i < 300; i++) { // 写入300帧cv::Mat frame(frameSize, CV_8UC3);// 创建渐变效果for (int y = 0; y < frame.rows; y++) {for (int x = 0; x < frame.cols; x++) {frame.at<cv::Vec3b>(y, x) = cv::Vec3b((x + i) % 256, // B(y + i) % 256, // G(x + y + i) % 256 // R);}}writer.write(frame); // 写入帧// 或者使用 writer << frame;cv::imshow("正在写入的视频", frame);if (cv::waitKey(30) >= 0) break;}writer.release(); // 释放资源cv::destroyAllWindows();return 0;
}
示例2:从摄像头捕获并保存视频
#include <opencv2/opencv.hpp>int main() {// 打开摄像头cv::VideoCapture cap(0);if (!cap.isOpened()) {std::cerr << "无法打开摄像头" << std::endl;return -1;}// 获取摄像头参数int frame_width = cap.get(cv::CAP_PROP_FRAME_WIDTH);int frame_height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);double fps = cap.get(cv::CAP_PROP_FPS);if (fps <= 0) fps = 30; // 如果获取不到帧率,使用默认值// 创建 VideoWriterint fourcc = cv::VideoWriter::fourcc('X', 'V', 'I', 'D'); // XVID 编码cv::VideoWriter writer("camera_output.avi", fourcc, fps, cv::Size(frame_width, frame_height));if (!writer.isOpened()) {std::cerr << "无法创建视频文件" << std::endl;return -1;}cv::Mat frame;while (true) {cap >> frame; // 从摄像头捕获一帧if (frame.empty()) break;writer.write(frame); // 写入视频文件cv::imshow("摄像头捕获", frame);if (cv::waitKey(30) >= 0) break; // 按任意键退出}cap.release();writer.release();cv::destroyAllWindows();return 0;
}
示例3:使用不同编解码器
// 使用 H.264 编码
int fourcc = cv::VideoWriter::fourcc('H', '2', '6', '4');
cv::VideoWriter writer("h264_output.mp4", fourcc, 30.0, cv::Size(640, 480));// 使用 VP8 编码
int fourcc = cv::VideoWriter::fourcc('V', 'P', '8', '0');
cv::VideoWriter writer("vp8_output.webm", fourcc, 30.0, cv::Size(640, 480));
  • 注意事项

    • 1.​​编解码器支持​​:不是所有编解码器在所有系统上都可用,取决于安装的 OpenCV 版本和编解码器库
    • 2.文件扩展名​​:文件扩展名应与编解码器匹配(如 .avi 用于 MJPG,.mp4 用于 H.264)
    • ​​3.帧大小一致性​​:所有写入的帧必须与构造函数中指定的大小相同
    • ​​4.颜色格式​​:如果构造函数中指定 isColor=true,则必须写入 3 通道 (BGR) 图像
    • ​​5.性能考虑​​:视频编码可能很耗资源,高分辨率/高帧率视频可能需要优化
    • ​​6.释放资源​​:务必调用 release() 以确保视频文件正确关闭
  • 高级用法

检查编解码器支持
// 检查特定编解码器是否可用
if (!writer.isOpened()) {std::cerr << "编解码器不可用,尝试其他编解码器" << std::endl;fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');writer.open("output.avi", fourcc, fps, frameSize);
}
写入灰度视频
// 创建灰度视频写入器
cv::VideoWriter writer("gray_output.avi", fourcc, fps, frameSize, false);// 写入灰度帧
cv::Mat grayFrame;
cv::cvtColor(colorFrame, grayFrame, cv::COLOR_BGR2GRAY);
writer.write(grayFrame);
设置视频质量
// 对于某些编解码器,可以设置质量参数
writer.set(cv::VIDEOWRITER_PROP_QUALITY, 95); // 质量百分比 (0-100)
多线程视频写入
// 在一个线程捕获,另一个线程写入
std::thread writerThread([&]() {while (!frames.empty() || capturing) {if (!frames.empty()) {writer.write(frames.front());frames.pop();}}
});

cv::VideoWriter 是 OpenCV 视频输出的核心类,熟练掌握它可以实现各种视频录制和保存功能。根据实际需求选择合适的编解码器和参数,可以优化视频质量和文件大小。

相关文章:

  • 【论文阅读33】滑坡易发性 PINN ( EG2025 )
  • 论文笔记 <交通灯><多智能体>CoLight管理交通灯
  • 当机床开始“思考”,传统“制造”到“智造”升级路上的法律暗礁
  • “第三届全国技能大赛”倒计时100天—千眼狼高速摄像机为焊接与增材制造项目提供可视化评判依据
  • Cloud Events:事件驱动架构的未来标准化
  • 腐烂之息-(Breath of Decay VR ) 硬核VR游戏
  • 欧洲宇航局如何为航天员提供虚拟现实训练内容
  • vue3 解析excel字节流文件 以表格形式显示页面上 带公式
  • Java + easyexcel 新旧数据对比,单元格值标红
  • 穿越时空的刀剑之旅:走进VR刀剑博物馆​
  • 720云vr全景怎么制作?720全景制作费用?
  • PHP基础-控制结构
  • 【Zephyr 系列 22】从单机开发到平台化:构建你自己的 Zephyr 物联网开发平台
  • 实战案例-JESD204B 多器件同步
  • 网络原理:网段划分
  • 北斗导航 | 基于MATLAB的卫星导航单点定位算法(卡尔曼滤波增强)
  • 对称加密和非对称加密
  • Python 数据分析10
  • 【Python 进阶系列】第4篇:初探 Python Pandas 数据分析的世界
  • 大模型驱动数据分析革新:美林数据智能问数解决方案破局传统 BI 痛点
  • 陕西住房和建设部网站首页/培训网站建设
  • 做网站赚多少/抖音营销软件
  • 台州知名的网站建设/站长域名查询工具
  • 在人才网站做业务/114网址大全
  • 网站学做糕点的课程/搜索引擎有哪些分类
  • 做水晶接单在哪个网站接/阿里域名注册网站