保存到一半了
This commit is contained in:
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
all:sendGpioSignal
|
all:sendGpioSignal
|
||||||
|
|
||||||
sendGpioSignal:
|
sendGpioSignal:
|
||||||
g++ -g -o sendGpioSignal sendGpioSignal.cpp //home/orangepi/RKApp/softWareInit/NetraLib/src/Netra.cpp -I/home/orangepi/RKApp/softWareInit/NetraLib/include -lwiringPi
|
g++ -g -o sendGpioSignal sendGpioSignal.cpp -lwiringPi
|
||||||
|
|
||||||
mv sendGpioSignal ../bin
|
mv sendGpioSignal ../bin
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,7 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <wiringPi.h>
|
#include <wiringPi.h>
|
||||||
|
|
||||||
#include "/home/orangepi/RKApp/softWareInit/NetraLib/include/Netra.hpp"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace QCL;
|
|
||||||
|
|
||||||
const string SetFile = "/home/orangepi/RKApp/InitAuth/conf/.env";
|
|
||||||
|
|
||||||
// 初始化GPIO引脚
|
// 初始化GPIO引脚
|
||||||
int InitGpio(int GPIO_Pin1, int GPIO_Pin2);
|
int InitGpio(int GPIO_Pin1, int GPIO_Pin2);
|
||||||
@@ -19,9 +14,6 @@ int InitGpio(int GPIO_Pin1, int GPIO_Pin2);
|
|||||||
// 写入GPIO引脚
|
// 写入GPIO引脚
|
||||||
void WriteGpio(int GPIO_Pin, int value);
|
void WriteGpio(int GPIO_Pin, int value);
|
||||||
|
|
||||||
// 获取输出模式
|
|
||||||
bool GetOutValue(int &value);
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int GPIO_Pin1 = 7;
|
int GPIO_Pin1 = 7;
|
||||||
@@ -44,70 +36,6 @@ int main(int argc, char *argv[])
|
|||||||
WriteGpio(GPIO_Pin2, stoi(argv[1]));
|
WriteGpio(GPIO_Pin2, stoi(argv[1]));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// int value = 0;
|
|
||||||
// bool useArg = false;
|
|
||||||
|
|
||||||
// // 修改点:如果传入了参数,直接使用参数作为电平值 (1 或 0)
|
|
||||||
// if (argc > 1)
|
|
||||||
// {
|
|
||||||
// value = atoi(argv[1]);
|
|
||||||
// useArg = true;
|
|
||||||
// cout << "[sendGpioSignal] 使用命令行参数: " << value << endl;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// // 原有的读取文件逻辑
|
|
||||||
// cout << "[sendGpioSignal] 启动,读取配置: " << SetFile << endl;
|
|
||||||
// if (GetOutValue(value) == false)
|
|
||||||
// {
|
|
||||||
// cerr << "[sendGpioSignal] 未读取到 outPutMode,程序退出" << endl;
|
|
||||||
// return -1;
|
|
||||||
// }
|
|
||||||
// cout << "[sendGpioSignal] 读取到 outPutMode=" << (value == 1 ? "true" : "false") << endl;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 初始化GPIO引脚
|
|
||||||
// if (InitGpio(GPIO_Pin1, GPIO_Pin2) != 0)
|
|
||||||
// {
|
|
||||||
// cout << "Error: Failed to initialize GPIO pin " << endl;
|
|
||||||
// return 1;
|
|
||||||
// }
|
|
||||||
// // 写入GPIO引脚
|
|
||||||
// cout << "[sendGpioSignal] 设置 GPIO(" << GPIO_Pin1 << "," << GPIO_Pin2 << ") 为 "
|
|
||||||
// << (value == 1 ? "HIGH" : "LOW") << endl;
|
|
||||||
// WriteGpio(GPIO_Pin1, value);
|
|
||||||
// WriteGpio(GPIO_Pin2, value);
|
|
||||||
// cout << "[sendGpioSignal] 完成" << endl;
|
|
||||||
|
|
||||||
// this_thread::sleep_for(chrono::milliseconds(100));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取输出模式
|
|
||||||
bool GetOutValue(int &value)
|
|
||||||
{
|
|
||||||
bool flag = true;
|
|
||||||
// 读取文件
|
|
||||||
ReadFile rf(SetFile);
|
|
||||||
if (rf.Open() == false)
|
|
||||||
{
|
|
||||||
cerr << "读取文件失败" << endl;
|
|
||||||
flag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto str = rf.ReadLines();
|
|
||||||
for (auto &ii : str)
|
|
||||||
{
|
|
||||||
if (ii.find("outPutMode") != string::npos)
|
|
||||||
{
|
|
||||||
value = (ii.substr(string("outPutMode:").size()) == "true" ? 1 : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rf.Close();
|
|
||||||
return flag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化GPIO引脚
|
// 初始化GPIO引脚
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -13,9 +13,10 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <queue>
|
#include <queue> //队列
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <deque> //双端队列
|
||||||
|
|
||||||
#include "Netra.hpp"
|
#include "Netra.hpp"
|
||||||
|
|
||||||
@@ -24,15 +25,13 @@ using namespace QCL;
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace chrono_literals;
|
using namespace chrono_literals;
|
||||||
|
|
||||||
// 全局变量
|
// 路径和接口
|
||||||
VideoCapture cap(0);
|
|
||||||
Mat handleFrame; // 存放处理后的帧
|
|
||||||
const string mqtt_url = "tcp://192.168.12.1:1883";
|
const string mqtt_url = "tcp://192.168.12.1:1883";
|
||||||
const string clientId = "video_subData";
|
const string clientId = "video_subData";
|
||||||
const string Topic = "/video/PersonData";
|
const string Topic = "/video/PersonData";
|
||||||
const string filePath = "../../InitAuth/conf/.env"; // 配置保存路径
|
const string filePath = "../../InitAuth/conf/.env"; // 配置保存路径
|
||||||
const int Qos = 0;
|
const string warningPath = "/mnt/save/warning/"; // 报警图片保存路径
|
||||||
mqtt::async_client client(mqtt_url, clientId);
|
const string videoPath = "/mnt/save/video/"; // 报警视频保存路径
|
||||||
|
|
||||||
// 保存检测结果
|
// 保存检测结果
|
||||||
struct Dection
|
struct Dection
|
||||||
@@ -49,15 +48,26 @@ struct dangerDistance
|
|||||||
int safe;
|
int safe;
|
||||||
} dis;
|
} 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的互斥锁
|
mutex alertMutex; // 保护alertQueue的互斥锁
|
||||||
condition_variable alertcv; // 通知报警线程有新任务
|
condition_variable alertcv; // 通知报警线程有新任务
|
||||||
queue<nlohmann::json> alertQueue; // 存放解析后的数据
|
queue<nlohmann::json> alertQueue; // 存放解析后的数据
|
||||||
std::atomic<bool> alertWorkerRunning{false}; // 工作线程运行标志
|
std::atomic<bool> alertWorkerRunning{false}; // 工作线程运行标志
|
||||||
atomic<bool> outPutMode = false; // 保存报警输出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初始化
|
// mqtt初始化
|
||||||
void MqttInit();
|
void MqttInit();
|
||||||
@@ -81,8 +91,12 @@ void warnThread();
|
|||||||
bool GetDistance();
|
bool GetDistance();
|
||||||
// 调用报警输出程序
|
// 调用报警输出程序
|
||||||
void setGPIOLevel(int level);
|
void setGPIOLevel(int level);
|
||||||
// // 状态机
|
// 获取当前时间字符串做文件名
|
||||||
// void warnStatus();
|
string getCurrentTimeStr();
|
||||||
|
// 保存图片
|
||||||
|
void saveAlarmImage();
|
||||||
|
// 保存视频
|
||||||
|
void saveAlarmVideo();
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@@ -111,6 +125,50 @@ int main()
|
|||||||
return 0;
|
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)
|
void setGPIOLevel(int level)
|
||||||
{
|
{
|
||||||
@@ -118,19 +176,6 @@ void setGPIOLevel(int level)
|
|||||||
system(cmd.c_str());
|
system(cmd.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// // 状态机
|
|
||||||
// void warnStatus()
|
|
||||||
// {
|
|
||||||
// thread([]()
|
|
||||||
// {
|
|
||||||
// bool isAlarm = false;
|
|
||||||
// auto lastDangerTime = chrono::steady_clock::now();
|
|
||||||
// while(alertWorkerRunning.load())
|
|
||||||
// {
|
|
||||||
|
|
||||||
// } });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 报警线程
|
// 报警线程
|
||||||
void warnThread()
|
void warnThread()
|
||||||
{
|
{
|
||||||
@@ -201,13 +246,13 @@ void warnThread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch(const std::exception& e)
|
catch(const std::exception& e)
|
||||||
{
|
{
|
||||||
std::cerr << e.what() << '\n';
|
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();
|
latestDection.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 短锁进行保存
|
||||||
|
{
|
||||||
|
lock_guard<mutex> lk(bufferMutex);
|
||||||
|
videoDeque.push_back(handleFrame);
|
||||||
|
}
|
||||||
|
|
||||||
// 可选:显示窗口
|
// 可选:显示窗口
|
||||||
// imshow("测试画面", frame);
|
// imshow("测试画面", frame);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user