当前位置:网站首页>保存视频 opencv::VideoWriter
保存视频 opencv::VideoWriter
2022-07-02 06:34:00 【懵懂的梦花火】
// 视频参数
m_videoInfo.fps = m_capture.get(cv::CAP_PROP_FPS);
m_videoInfo.width = m_capture.get(cv::CAP_PROP_FRAME_WIDTH);
m_videoInfo.height = m_capture.get(cv::CAP_PROP_FRAME_HEIGHT);
// 初始化VideoWriter
m_mapVideoWriter[_strVideoName] = cv::VideoWriter(_strVideoName,
cv::VideoWriter::fourcc('X', 'V', 'I', 'D'),
m_videoInfo.fps,
cv::Size(m_videoInfo.width, m_videoInfo.height)
);
// 写数据
for (auto videoWriter : m_mapVideoWriter)
{
videoWriter.second << _mat;
}
视频保存结果
while(true)
{
for (auto videoWriter : m_mapVideoWriter)
{
videoWriter.second << _mat;
funtion();
}
}
写数据的操作,运行如下,保存数据正常的前提,funtion()执行一次的时间不能过长(保存图片的频率要满足一定要求,120ms的保存会出错,其它没有测试)。上图video.mp4为正常保存的视频,15_9_36_model_zhiyin.mp4为错误保存的结果,打开会有下图错误。
VideoSaveFunTool文件夹创建,文件名称拼接类
VideoSaveFunTool.h
#pragma once
/*
保存视频中,文件路径处理类
*/
#ifndef VIDEOSAVEFUNTOOL_H
#define VIDEOSAVEFUNTOOL_H
#include <ctime>
#include <string>
namespace UsbCamera
{
class VideoSaveFunTool
{
public:
VideoSaveFunTool();
void GetSaveVidePath(std::string& _strVideoDir);
private:
std::string GetVideoDir();
bool CreateDir(std::string & _strDir);
void UpdateTime();
std::string m_fileDir;
struct tm* m_pTime; // 存储时间,用于保存视频文件
};
}
#endif // !VIDEOSAVEFUNTOOL_H
VideoSaveFunTool.cpp
#include "VideoSaveFunTool.h"
#include "io.h"
#include <ctime>
#include <direct.h>
#include <iostream>
#include "tinyxml2.h"
namespace UsbCamera
{
#define PATH_DELIMITER '\\'
void VideoSaveFunTool::UpdateTime()
{
time_t nowtime;
time(&nowtime);
//使用该函数就可得到当前系统时间,使用该函数需要将传入time_t类型变量nowtime的地址值。
m_pTime = localtime(&nowtime);
m_pTime->tm_year += 1900;
}
bool VideoSaveFunTool::CreateDir(std::string & _strDir)
{
std::string folder_builder;
std::string sub;
sub.reserve(_strDir.size());
for (auto it = _strDir.begin(); it != _strDir.end(); ++it) {
const char c = *it;
sub.push_back(c);
if (c == PATH_DELIMITER || it == _strDir.end() - 1) {
folder_builder.append(sub);
if (0 != ::_access(folder_builder.c_str(), 0)) {
// this folder not exist
if (0 != ::_mkdir(folder_builder.c_str())) {
// create failed
return false;
}
}
sub.clear();
}
}
return true;
}
std::string VideoSaveFunTool::GetVideoDir()
{
// 新建一个空文档
tinyxml2::XMLDocument xmlDoc;
// 读取指定的xml文件并判断读取是否成功
tinyxml2::XMLError eResult = xmlDoc.LoadFile("config/VideoFileConfig.cas");
if (eResult != tinyxml2::XML_SUCCESS)
{
printf("error code :%d\n", tinyxml2::XML_ERROR_FILE_NOT_FOUND);
return "";
}
// 获得该文件的第一个节点(根节点)
tinyxml2::XMLNode * pRoot = xmlDoc.FirstChildElement("VideoFileConfig");
if (pRoot == nullptr)
{
printf("error code :%d\n", tinyxml2::XML_ERROR_FILE_READ_ERROR);
return "";
}
else
{
tinyxml2::XMLElement * pVideoDirElement = pRoot->FirstChildElement("VideoDir");
return pVideoDirElement->GetText();
}
}
VideoSaveFunTool::VideoSaveFunTool()
{
m_fileDir = GetVideoDir();
if (m_fileDir == "")
m_fileDir = "D:\\Video";
}
void VideoSaveFunTool::GetSaveVidePath(std::string& _strVideoDir)
{
struct tm time; // 时间
std::string filePath; // 保存的路径
// 更新时间
UpdateTime();
// 构建存储目录
filePath = m_fileDir + "\\" + std::to_string(m_pTime->tm_year) + "\\" + std::to_string(m_pTime->tm_mon) + "\\"
+ std::to_string(m_pTime->tm_mday);
CreateDir(filePath);
filePath = filePath + "\\" + std::to_string(m_pTime->tm_hour) + "_" + std::to_string(m_pTime->tm_min)
+ "_" + std::to_string(m_pTime->tm_sec);
_strVideoDir = filePath;
}
}
边栏推荐
- Taking the upgrade of ByteDance internal data catalog architecture as an example, talk about the performance optimization of business system
- Solution to amq4036 error in remote connection to IBM MQ
- Mysql默认事务隔离级别及行锁
- Elastic Stack之Beats(Filebeat、Metricbeat)、Kibana、Logstash教程
- Watermelon book -- Chapter 5 neural network
- Activity的创建和跳转
- Knife4j 2. Solution to the problem of file control without selection when uploading x version files
- 分享一篇博客(水一篇博客)
- Number structure (C language -- code with comments) -- Chapter 2, linear table (updated version)
- Microservice practice | teach you to develop load balancing components hand in hand
猜你喜欢

The channel cannot be viewed when the queue manager is running

Typora安装包分享

How to install PHP in CentOS

Matplotlib swordsman - a stylist who can draw without tools and code

知识点很细(代码有注释)数构(C语言)——第三章、栈和队列

微服务实战|手把手教你开发负载均衡组件
![[go practical basis] how to set the route in gin](/img/23/f38d68c4fd238d453b9a7670483002.png)
[go practical basis] how to set the route in gin

Flink - use the streaming batch API to count the number of words

微服务实战|原生态实现服务的发现与调用

一次聊天勾起的回忆
随机推荐
Hystrix implements request consolidation
Learn combinelatest through a practical example
How to use pyqt5 to make a sensitive word detection tool
Jingdong senior engineer has developed for ten years and compiled "core technology of 100 million traffic website architecture"
互联网API接口幂等设计
机器学习实战:《美人鱼》属于爱情片还是动作片?KNN揭晓答案
Matplotlib剑客行——布局指南与多图实现(更新)
道阻且长,行则将至
ClassFile - Attributes - Code
Knife4j 2. Solution to the problem of file control without selection when uploading x version files
图像识别-数据标注
Creation and jump of activity
概念到方法,绝了《统计学习方法》——第三章、k近邻法
[go practical basis] how to verify request parameters in gin
盘点典型错误之TypeError: X() got multiple values for argument ‘Y‘
Navicat 远程连接Mysql报错1045 - Access denied for user ‘root‘@‘222.173.220.236‘ (using password: YES)
Ora-12514 problem solving method
Solutions to Chinese garbled code in CMD window
Chrome视频下载插件–Video Downloader for Chrome
自定義Redis連接池