在C++项目中添加录像功能:从摄像头捕获到视频文件的保存

在C++项目中添加录像功能:从摄像头捕获到视频文件的保存

在这篇博客中,我们将介绍如何在一个现有的C++项目中添加录像功能,具体包括如何从摄像头捕获图像并将其保存为视频文件。我们将使用OpenCV库来处理图像捕获和视频写入。

目录

  1. 引言
  2. 准备工作
  3. 包含必要的头文件
  4. 添加录像功能的变量
  5. 初始化录像功能
  6. 在主循环中添加录像逻辑
  7. 控制录像的开始和停止
  8. 释放资源
  9. 完整示例代码

1. 引言

在计算机视觉应用中,常常需要从摄像头捕获图像并进行处理。为了记录这些图像,我们可以将其保存为视频文件。使用OpenCV库,我们可以轻松实现这一功能。本文将逐步讲解如何在你的C++项目中集成录像功能。

2. 准备工作

在开始之前,请确保你已经安装了OpenCV库,并且你的开发环境已经配置好以使用OpenCV。如果还没有安装,可以参考OpenCV官方网站获取安装和配置指南。

3. 包含必要的头文件

首先,确保你的代码中包含了OpenCV和其他必要的头文件。以下是示例代码的头文件部分:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <QString>
#include <chrono>
#include <thread>
#include "UdpUtil.h"
#include "lcmUtil.h"
#include "mythread.h"
#include "colorgroup.h"using namespace std;
using namespace std::chrono;
using namespace cv;

4. 添加录像功能的变量

我们需要一些变量来控制录像功能,例如一个VideoWriter对象来保存视频文件,以及一个布尔标志来控制录像的开始和停止:

bool isRecording = false;
VideoWriter videoWriter;
std::string outputVideoFile = "output.avi";

5. 初始化录像功能

在摄像头成功打开后,我们需要初始化VideoWriter对象。以下是初始化的代码片段:

for (int i = 0; i <= 3; i++) {cap.open(i);if (!cap.isOpened()) {printf("打开摄像头失败:number=%d\n", i);if (i == 3) return 0;} else {printf("打开摄像头成功:number=%d\n", i);// 获取摄像头帧率double fps = cap.get(CAP_PROP_FPS);if (fps == 0) fps = 30; // 如果无法获取帧率,设置一个默认值// 获取帧的宽度和高度int frameWidth = cap.get(CAP_PROP_FRAME_WIDTH);int frameHeight = cap.get(CAP_PROP_FRAME_HEIGHT);// 初始化VideoWritervideoWriter.open(outputVideoFile, VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, Size(frameWidth, frameHeight), true);if (!videoWriter.isOpened()) {cerr << "无法打开视频文件进行写入\n";return -1;}break;}
}

6. 在主循环中添加录像逻辑

在主循环中,我们将每一帧写入视频文件。以下是代码示例:

while (1) {cap >> srcImage;if (!srcImage.empty()) {imageProcess(srcImage);  // 图像处理和指令发送lcmutil->send(v_des, gait_type, step_height, stand_height, rpy_des); // 发送步态指令logMode();  // 打印状态// 写入当前帧到视频文件if (isRecording) {videoWriter.write(srcImage);}if (flag) {colorgroup.showPicture(srcImage, 1);colorgroup.start();if (udpsocket.ifReceiveInfoFlag != 0) {switch (udpsocket.ifReceiveInfoFlag) {case 1: // 选择颜色并返回阈值colorgroup.chooseColor(udpsocket.color);colorgroup.sendColorThreadhold();colorgroup.ifRunContinueFlag = true;break;case 2: // 设置颜色阈值colorgroup.setColorThreadhold(udpsocket.colorThreadhold);break;case 3: // 保存颜色阈值colorgroup.save();break;}udpsocket.ifReceiveInfoFlag = 0;}}}QThread::msleep(20);
}

7. 控制录像的开始和停止

我们可以通过检查某些条件或命令行参数来控制录像的开始和停止。以下是一个示例,其中通过输入参数控制录像:

else if (argc >= 2) {inputParameters1 = argv[1];if (inputParameters1 == "record") {printf("录像模式\n");isRecording = true;}// 其他模式...
}

8. 释放资源

在程序结束时,确保释放VideoWriter对象和其他资源:

printf("程序运行结束\n");
cap.release();
if (videoWriter.isOpened()) {videoWriter.release();
}
return 0;

9. 完整示例代码

以下是集成了录像功能的完整示例代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <QString>
#include <chrono>
#include <thread>
#include "UdpUtil.h"
#include "lcmUtil.h"
#include "mythread.h"
#include "colorgroup.h"using namespace std;
using namespace std::chrono;
using namespace cv;int main(int argc, char* argv[]) {UdpUtil udpsocket;QString inputParameters1;QString inputParameters2;bool flag = false; // 该标志位用于是否显示图像bool isRecording = false; // 录像标志位VideoWriter videoWriter;std::string outputVideoFile = "output.avi";static steady_clock::time_point start;if (argc == 1) {printf("using default parameter mode is track\n");printf("mode is track\n");printf("default residenceColor is red\n");mythread.mode = track;residenceColor = "brown";} else if (argc >= 2) {inputParameters1 = argv[1];if (inputParameters1 == "track") {printf("mode is track\n");printf("default residenceColor is null\n");mythread.mode = track;} else if (inputParameters1 == "brown") {printf("mode is track\n");printf("input residenceColor is brown\n");mythread.mode = track;residenceColor = "brown";} else if (inputParameters1 == "violet") {printf("mode is track\n");printf("input residenceColor is violet\n");mythread.mode = track;residenceColor = "violet";} else if (inputParameters1 == "stop") {printf("mode is stop\n");mythread.mode = stop;} else {mythread.mode = track;printf("parameters error\n");printf("mode is track\n");}if (argc == 3) {inputParameters2 = argv[2];if (inputParameters2 == "red") {printf("mode is track\n");printf("input divergerColor is red\n");mythread.mode = track;divergerColor = "red"; printf("start to show image\n");flag = true;udpsocket.start();} else if (inputParameters2 == "green") {printf("mode is track\n");printf("input divergerColor is green\n");mythread.mode = track;divergerColor = "green"; printf("start to show image\n");flag = true;udpsocket.start();} else if (inputParameters2 == "showImage") {printf("start to show image\n");flag = true;udpsocket.start();} else if (inputParameters1 == "record") {printf("录像模式\n");isRecording = true;}}}for (int i = 0; i <= 3; i++) {cap.open(i);if (!cap.isOpened()) {printf("打开摄像头失败:number=%d\n", i);if (i == 3) return 0;} else {printf("打开摄像头成功:number=%d\n", i);double fps = cap.get(CAP_PROP_FPS);if (fps == 0) fps = 30;int frameWidth = cap.get(CAP_PROP_FRAME_WIDTH);int frameHeight = cap.get(CAP_PROP_FRAME_HEIGHT);videoWriter.open(outputVideoFile, VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, Size(frameWidth, frameHeight), true);if (!videoWriter.isOpened()) {cerr << "无法打开视频文件进行写入\n";return -1;}break;}}lcmUtil *lcmutil = new lcmUtil;mythread.start();while (1) {cap >> srcImage;if (!srcImage.empty()) {imageProcess(srcImage);lcmutil->send(v_des, gait_type, step_height, stand_height, rpy_des);logMode();if (isRecording) {videoWriter.write(srcImage);}if (flag) {colorgroup.showPicture(srcImage, 1);colorgroup.start();if (udpsocket.ifReceiveInfoFlag != 0) {switch (udpsocket.ifReceiveInfoFlag) {case 1:colorgroup.chooseColor(udpsocket.color);colorgroup.sendColorThreadhold();colorgroup.ifRunContinueFlag = true;break;case 2:colorgroup.setColorThreadhold(udpsocket.colorThreadhold);break;case 3:colorgroup.save();break;}udpsocket.ifReceiveInfoFlag = 0;}}}QThread::msleep(20);}printf("程序运行结束\n");cap.release();if (videoWriter.isOpened()) {videoWriter.release();}return 0;
}

通过以上步骤,你可以在你的C++项目中成功添加录像功能,将摄像头捕获的图像保存为视频文件。希望这篇博客能对你有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/43977.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python学习笔记35:进阶篇(二十四)pygame的使用之音频文件播放

前言 基础模块的知识通过这么长时间的学习已经有所了解&#xff0c;更加深入的话需要通过完成各种项目&#xff0c;在这个过程中逐渐学习&#xff0c;成长。 我们的下一步目标是完成python crash course中的外星人入侵项目&#xff0c;这是一个2D游戏项目。在这之前&#xff…

元组列表之案例

1.列表推导式 基本语法&#xff1a; [表达式 for语句1 if 语句1 for语句2 if语句2 ........ ] 1.零到九的平方列表 a [i*i for i in range(10)] print(a) 2.for 循环前面加if else #如果是偶数乘以2&#xff0c;如果是奇数直接输出 a [i*2 if i%2 0 else i for i in ran…

什么是生成器函数?

生成器函数&#xff08;Generator Function&#xff09;是 JavaScript 中一种特殊的函数&#xff0c;它可以在执行过程中暂停并在之后恢复执行。生成器函数使用 function* 语法定义&#xff0c;并且内部使用 yield 表达式来暂停函数执行并返回一个值。每次调用生成器函数返回的…

rabbitmq集群创建admin用户之后,提示can access virtual hosts是No access状态

问题描述&#xff1a; 因业务需要使用的rabbitmq是3.7.8版本的&#xff0c;rabbitmq在3.3.0之后就允许使用guest账号的权限了&#xff0c;所以需要创建一个administrator标签的用户。 如下操作创建的用户&#xff1a; 创建完成之后就提示如下的报错&#xff1a; 注&#xff1a…

php表单提交并自动发送邮件给某个邮箱(示例源码下载)

只需要将以下代码内容进行复制即可用到自己的程序/API接口中&#xff1a; <?php if(!empty($_POST[is_post]) && $_POST[is_post]1){$url "https://www.aoksend.com/index/api/send_email";$name $_POST[name];$email $_POST[email];$subject $_POS…

探索Mojo模型:解锁机器学习模型的可解释性之旅

探索Mojo模型&#xff1a;解锁机器学习模型的可解释性之旅 在人工智能和机器学习领域&#xff0c;模型的可解释性是一个至关重要的议题。随着模型变得越来越复杂&#xff0c;理解模型的决策过程成为了一个挑战。Mojo模型作为一种模型序列化格式&#xff0c;提供了一种方法来部…

Python 给存入 Redis 的键值对设置过期时间

Redis 是一种内存中的数据存储系统&#xff0c;与许多传统数据库相比&#xff0c;它具有一些优势&#xff0c;其中之一就是可以设置数据的过期时间。通过 Redis 的过期时间设置&#xff0c;可以为存储在 Redis 中的数据设置一个特定的生存时间。一旦数据到达过期时间&#xff0…

mybatis日志记录方案

首先对指定表进行监控 对表进行监控,那么就要使用的是statementInterceptor 拦截器 使用拦截器那么就要写intercepts写拦截条件进行拦截 监控只对与增删改 查询不进行监控 对于字段的监控,是谁修改了字段,那么就进行报警,或者提醒 消息提醒使用钉钉机器人进行消息提醒 P…

软链接node_modules

公司项目很多微应用的子项目公用同一套模板&#xff0c;也就会使用同一个node_modules 1.先创建3个同样的项目,并安装一个其中的一个node_modules给他丢到外边 2.win r -------> cmd --------> ctrlshift enter(已管理员身份打开cmd) 3.在窗口分别执行以下代码…

视频减小技巧:十大顶级视频压缩软件

视频压缩软件会尽可能地压缩视频&#xff0c;以便上传到各个网站。通常&#xff0c;4K 或更高质量的视频体积更大。压缩软件有助于压缩体积。在这里&#xff0c;我们来讨论一下 10 款最佳视频压缩软件。 十大顶级视频压缩软件 1. 奇客压缩宝 奇客压缩宝是由Geekersoft公司开发…

基于SpringBoot+MySQL的租房项目+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

数据库系统中的Undo和Redo

在数据库管理系统&#xff08;DBMS&#xff09;中&#xff0c;undo 和 redo 是两种用于事务管理和故障恢复的重要机制。它们主要涉及事务的提交、回滚以及系统故障后的数据恢复。 Undo&#xff08;撤销&#xff09; 作用&#xff1a;undo 用于撤销未提交事务所做的修改&#…

极狐Gitlab使用(1)

目录 续接上篇&#xff1a;极狐Gitlab安装部署-CSDN博客 1. 关闭注册功能 2. 创建群组 3. 创建用户 5. 邀请成员到群组 6. 设置导入导出项目源 7. 通过gitee导入库 8. 通过仓库URL导入 9. 自创建项目 10. 默认分支main的权限 11. 使用普通用户进入自建库 12. 创建用…

java的遍历的方法对比 效率对比

在 Java 中&#xff0c;遍历对象的方式主要取决于对象的类型和数据结构。以下是几种常见的遍历方式&#xff0c;以及它们的效率比较&#xff1a; 普通的 for 循环&#xff1a; 效率&#xff1a;高。使用普通的 for 循环可以直接根据索引来访问元素&#xff0c;适用于数组和实现…

Ubuntu系统上安装Apache和WordPress

** 第一步跟新系统包 ** 首先跟新系统包 sudo apt update sudo apt upgrade第二步下载安装apache sudo apt install apache2 ##查看apache的状态是否启动成功 sudo systemctl status apache2 ##查看服务器的ip地址 sudo ip a通过ip地址进行访问apache页面 第三步下载安装…

git patch怎么使用?

通常当我们提到 "patch" 时&#xff0c;我们可能指的是以下几种情况&#xff1a; 1. **应用补丁文件**&#xff1a; 如果你有一个 .patch 文件&#xff0c;你可以使用 git apply 命令来应用它。 bash git apply your-patch-file.patch 这会将补丁文件中的更改应用到…

软件架构之嵌入式系统设计

软件架构之嵌入式系统设计 第 12 章&#xff1a;嵌入式系统设计12.1 嵌入式系统概论12.2 嵌入式系统的组成12.2.1 硬件架构12.2.2 软件架构 12.3 嵌入式开发平台与调试环境12.3.1 嵌入式系统软件开发平台12.3.2 嵌入式开发调试 第 12 章&#xff1a;嵌入式系统设计 随着计算机…

力扣 1两数之和

nums [2,7,6,3] target 9 需要在这个中找到 nums中数字下标&#xff0c;累加和等于target 也就是说既要数字下标&#xff0c;又要nums中数字&#xff0c;还要查找 因此&#xff0c;考虑map这种既有key 又有value的哈希表 问题是 map,unordered_map, muti_map用哪一个呢&a…

人工智能时代,零基础学IT,我首推Python作为你编程入门语言!

人工智能时代为什么将 Python 称为第一语言&#xff1f; 因为python适应了人工智能时代&#xff1a; 人工智能时代对于代码的简便性有很大要求&#xff0c;像传统的C/CPP/Java学习较为复杂&#xff0c;学习路线长&#xff0c;对于很多零基础的人入门困难。python的兼容性&…

k8s集群部署mysql8主备

一、搜索mysql8版本 # helm search repo mysql# helm pull bitnami/mysql --version:11.1.2# tar -zxf mysql-11.1.2.tgz# cd mysql 二、修改value.ysqml文件 动态存储类自己提前搭建。 # helm install mysql8 -n mysql-cluster ./ -f values.yaml NAME: mysql8 LAST DEPLOYED…