在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);

        // 初始化VideoWriter
        videoWriter.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++项目中成功添加录像功能,将摄像头捕获的图像保存为视频文件。希望这篇博客能对你有所帮助!

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元素之窗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值