保存到一半了

This commit is contained in:
2025-11-19 16:55:29 +08:00
parent 18885439e6
commit f6bb0bd55f
6 changed files with 79 additions and 2113 deletions

Binary file not shown.

View File

@@ -13,9 +13,10 @@
#include <nlohmann/json.hpp>
#include <mutex>
#include <vector>
#include <queue>
#include <queue> //队列
#include <condition_variable>
#include <atomic>
#include <deque> //双端队列
#include "Netra.hpp"
@@ -24,15 +25,13 @@ using namespace QCL;
using namespace cv;
using namespace chrono_literals;
// 全局变量
VideoCapture cap(0);
Mat handleFrame; // 存放处理后的帧
// 路径和接口
const string mqtt_url = "tcp://192.168.12.1:1883";
const string clientId = "video_subData";
const string Topic = "/video/PersonData";
const string filePath = "../../InitAuth/conf/.env"; // 配置保存路径
const int Qos = 0;
mqtt::async_client client(mqtt_url, clientId);
const string warningPath = "/mnt/save/warning/"; // 报警图片保存路径
const string videoPath = "/mnt/save/video/"; // 报警视频保存路径
// 保存检测结果
struct Dection
@@ -49,15 +48,26 @@ struct dangerDistance
int safe;
} dis;
mutex detMutex; // 保护latestDection的互斥锁
vector<Dection> latestDection; // 保存最新接收到的检测结果
// 全局变量和对象
VideoCapture cap(0);
Mat handleFrame; // 存放处理后的帧
const int Qos = 0;
mqtt::async_client client(mqtt_url, clientId);
mutex detMutex; // 保护latestDection的互斥锁
vector<Dection> latestDection; // 保存最新接收到的检测结果
mutex alertMutex; // 保护alertQueue的互斥锁
condition_variable alertcv; // 通知报警线程有新任务
queue<nlohmann::json> alertQueue; // 存放解析后的数据
std::atomic<bool> alertWorkerRunning{false}; // 工作线程运行标志
atomic<bool> outPutMode = false; // 保存报警输出false--电平
// atomic<bool> currentFrameHasDanger{false}; // 是否进行了报警
// 视频相关
const int FPS = 30; // 帧率
const int PRE_RECORD_SECONDS = 10; // 预录制时长
const int MAX_BUFFER_SIZE = FPS * PRE_RECORD_SECONDS; // 缓冲区最大帧数
mutex bufferMutex; // 保护缓冲区的锁
deque<Mat> videoDeque; // 环形缓冲区,存储最近十秒的画面帧
atomic<bool> isRecording{false}; // 是否正在写入文件
// mqtt初始化
void MqttInit();
@@ -81,8 +91,12 @@ void warnThread();
bool GetDistance();
// 调用报警输出程序
void setGPIOLevel(int level);
// // 状态机
// void warnStatus();
// 获取当前时间字符串做文件名
string getCurrentTimeStr();
// 保存图片
void saveAlarmImage();
// 保存视频
void saveAlarmVideo();
int main()
{
@@ -111,6 +125,50 @@ int main()
return 0;
}
// 保存图片
void saveAlarmImage(const Mat &frame)
{
// 保存路径
string fileName = warningPath + "alarm_" + getCurrentTimeStr() + ".jpg";
imwrite(fileName, frame);
}
// 保存视频
void saveAlarmVideo(deque<Mat> bufferSnapshot)
{
thread([bufferSnapshot]()
{
string fileName = videoPath + "alarm_" + getCurrentTimeStr() + ".mp4";
// 初始化视频写入器
VideoWriter write;
int codec = write.fourcc('H', '2', '6', '4');
Size size(1920, 1080);
if (!bufferSnapshot.empty())
{
size = bufferSnapshot.front().size();
}
write.open(fileName, codec, FPS, size, true);
// 写入缓冲区的所有帧
for (auto &ii : bufferSnapshot)
{
write.write(ii);
}
//退出清理
write.release(); })
.detach();
}
// 获取当前时间字符串做文件名
string getCurrentTimeStr()
{
auto now = chrono::system_clock::now();
auto time_t_now = chrono::system_clock::to_time_t(now);
stringstream ss;
ss << put_time(localtime(&time_t_now), "%Y%m%d_%H%M%S");
return ss.str();
}
// 调用报警输出程序
void setGPIOLevel(int level)
{
@@ -118,19 +176,6 @@ void setGPIOLevel(int level)
system(cmd.c_str());
}
// // 状态机
// void warnStatus()
// {
// thread([]()
// {
// bool isAlarm = false;
// auto lastDangerTime = chrono::steady_clock::now();
// while(alertWorkerRunning.load())
// {
// } });
// }
// 报警线程
void warnThread()
{
@@ -201,13 +246,13 @@ void warnThread()
}
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
lk.lock(); //重新上锁,以继续处理下个任务
lk.lock(); //重新上锁,以继续处理下个任务
}
//逻辑处理,状态机
@@ -446,6 +491,12 @@ bool processFrame(VideoCapture &cap, FILE *pipe, Mat &frame, int64 &count, chron
latestDection.clear();
}
// 短锁进行保存
{
lock_guard<mutex> lk(bufferMutex);
videoDeque.push_back(handleFrame);
}
// 可选:显示窗口
// imshow("测试画面", frame);