- 基本的视频读取和显示
// 创建视频捕获对象
cv::VideoCapture cap;
// 打开视频文件
cap.open("test_video.mp4");
// 检查是否成功打开
if (!cap.isOpened()) {
std::cout << "无法打开视频文件!" << std::endl;
return;
}
// 获取视频属性
double fps = cap.get(cv::CAP_PROP_FPS);
int width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
int height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
int totalFrames = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_COUNT));
std::cout << "视频信息:" << std::endl;
// 1102 x 720
std::cout << "分辨率: " << width << " x " << height << std::endl;
// 25
std::cout << "帧率: " << fps << " FPS" << std::endl;
// 10206
std::cout << "总帧数: " << totalFrames << std::endl;
// 408.24
std::cout << "时长: " << totalFrames / fps << " 秒" << std::endl;
cv::Mat frame;
int frameCount = 0;
while (true) {
// 读取一帧
cap >> frame;
// 检查帧是否为空
if (frame.empty()) {
std::cout << "视频播放结束!" << std::endl;
break;
}
frameCount++;
// 在帧上显示信息
cv::putText(frame,
"Frame: " + std::to_string(frameCount) +
"/" + std::to_string(totalFrames),
cv::Point(20, 40),
cv::FONT_HERSHEY_SIMPLEX, 1,
cv::Scalar(0, 255, 0), 2);
// 显示帧
cv::imshow("视频播放器", frame);
// 按ESC退出,按空格暂停
// 1000 / fps为每帧间隔时间
int key = cv::waitKey(1000 / fps);
// ESC退出程序
if (key == 27) {
break;
}
// 空格
else if (key == 32) {
cv::waitKey(0);
}
}
// 释放资源
cap.release();
cv::destroyAllWindows();
- 视频写入
// 输入视频
cv::VideoCapture cap("test_video.mp4");
if (!cap.isOpened()) {
std::cout << "无法打开输入视频!" << std::endl;
return;
}
// 获取输入视频属性
double fps = cap.get(cv::CAP_PROP_FPS);
int width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
int height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
// 创建视频写入对象
cv::VideoWriter writer;
// 设置编码器和参数
int fourcc = cv::VideoWriter::fourcc('X', '2', '6', '4'); // H.264编码
// int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G'); // Motion-JPEG
// int fourcc = cv::VideoWriter::fourcc('X', 'V', 'I', 'D'); // XVID
writer.open("test_video.avi", fourcc, fps, cv::Size(width, height));
if (!writer.isOpened()) {
std::cout << "无法创建输出视频文件!" << std::endl;
return;
}
std::cout << "开始处理视频..." << std::endl;
std::cout << "输出格式: " << width << "x" << height << " @" << fps << "fps" << std::endl;
cv::Mat frame;
int processedFrames = 0;
while (true) {
cap >> frame;
if (frame.empty()) break;
// 可选:对帧进行处理
// cv::cvtColor(frame, frame, cv::COLOR_BGR2GRAY);
// cv::cvtColor(frame, frame, cv::COLOR_GRAY2BGR);
// 写入帧
writer.write(frame);
processedFrames++;
// 显示进度
if (processedFrames % 30 == 0) {
std::cout << "已处理 " << processedFrames << " 帧" << std::endl;
}
// 显示处理过程
cv::imshow("处理中", frame);
// ESC退出
if (cv::waitKey(1) == 27) break;
}
std::cout << "视频处理完成! 共处理 " << processedFrames << " 帧" << std::endl;
cap.release();
writer.release();
cv::destroyAllWindows();
- 实时捕获摄像头:
// 打开默认摄像头
cv::VideoCapture cap(0);
if (!cap.isOpened()) {
std::cout << "无法打开摄像头!" << std::endl;
return;
}
// 设置摄像头参数
cap.set(cv::CAP_PROP_FRAME_WIDTH, 1280);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 720);
cap.set(cv::CAP_PROP_FPS, 30);
std::cout << "摄像头信息:" << std::endl;
std::cout << "分辨率: " << cap.get(cv::CAP_PROP_FRAME_WIDTH)
<< " x " << cap.get(cv::CAP_PROP_FRAME_HEIGHT) << std::endl;
std::cout << "帧率: " << cap.get(cv::CAP_PROP_FPS) << std::endl;
std::cout << "按ESC退出,按s保存图片,按r开始/停止录制" << std::endl;
cv::Mat frame;
bool recording = false;
cv::VideoWriter recorder;
int recordedFrames = 0;
while (true) {
cap >> frame;
if (frame.empty()) break;
// 显示状态信息
std::string status = recording ? "recording - " + std::to_string(recordedFrames) + "frames" : "ready";
cv::putText(frame, status, cv::Point(20, 40),
cv::FONT_HERSHEY_SIMPLEX, 0.7, cv::Scalar(0, 0, 255), 2);
cv::putText(frame, "ESC:exit s:take photo r:recording", cv::Point(20, frame.rows - 20),
cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(255, 255, 255), 1);
cv::imshow("摄像头", frame);
int key = cv::waitKey(1);
if (key == 27) { // ESC
break;
}
else if (key == 's' || key == 'S') { // 保存图片
std::string filename = "capture_" + std::to_string(time(0)) + ".jpg";
cv::imwrite(filename, frame);
std::cout << "图片已保存: " << filename << std::endl;
}
else if (key == 'r' || key == 'R') { // 开始/停止录制
if (!recording) {
// 开始录制
int fourcc = cv::VideoWriter::fourcc('X', '2', '6', '4');
recorder.open("recording_" + std::to_string(time(0)) + ".avi",
fourcc, 30.0, frame.size());
if (recorder.isOpened()) {
recording = true;
recordedFrames = 0;
std::cout << "开始录制..." << std::endl;
}
}
else {
// 停止录制
recording = false;
recorder.release();
std::cout << "录制停止,共录制 " << recordedFrames << " 帧" << std::endl;
}
}
// 录制帧
if (recording) {
recorder.write(frame);
recordedFrames++;
}
}
if (recording) {
recorder.release();
}
cap.release();
cv::destroyAllWindows();