OpenCV摄像头捕获、视频读取与保存
在计算机视觉和图像处理领域,视频处理是非常常见的任务。无论是实时监控、视频分析,还是数据采集与存储,OpenCV 都提供了简单易用的接口。本文将详细介绍如何使用 OpenCV C++ 实现以下功能:
- 摄像头捕获与显示:利用摄像头实时获取视频流并显示到窗口上。
- 实时视频保存:将捕获的视频实时写入文件。
- 视频读取与播放:从保存的视频文件中读取并显示视频内容。
下面我们将逐步讲解这些操作的原理、主要函数及示例代码。
过多API参考官方文档opencv API文档
1. 摄像头捕获与显示
利用 OpenCV 中的 cv::VideoCapture
类,可以方便地从摄像头(或其它视频源)中读取视频帧。常用步骤如下:
- 创建 VideoCapture 对象:通过设备索引(例如 0 表示默认摄像头)打开摄像头。
- 循环读取视频帧:使用
read
或>>
操作符获取每一帧图像。 - 显示视频帧:利用
imshow
函数在窗口中实时显示视频内容。 - 退出条件:一般通过检测按键(例如 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
类。使用步骤如下:
- 定义输出视频文件名和编码器:可以通过 FOURCC 码指定视频编码格式(如
XVID
、MJPG
等)。 - 创建 VideoWriter 对象:指定输出文件名、编码器、帧率和视频尺寸。
- 在捕获循环中写入视频帧:使用
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 也可以读取已经保存的视频文件进行播放和处理。使用步骤如下:
- 创建 VideoCapture 对象:传入视频文件路径打开视频文件。
- 循环读取视频帧:读取每一帧并显示。
- 结束条件:检测到视频结束或按键退出循环。
#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
打开视频文件并循环读取显示视频帧。
通过掌握这些基础操作,开发者可以轻松构建实时监控、视频处理和数据采集等应用。