Forráskód Böngészése

V0.3.7
1、添加了部分的人员计数功能

Apple 5 hónapja
szülő
commit
0ab418a159

+ 5 - 0
SecurePlayAuxServer/Application/PersonCount.cpp

@@ -0,0 +1,5 @@
+#include "PersionCount.h"
+
+
+
+

+ 22 - 0
SecurePlayAuxServer/Application/PersonCount.h

@@ -0,0 +1,22 @@
+#ifndef PERSONCOUNT_H
+#define PERSONCOUNT_H
+
+
+
+
+/* 区域人员检测(人员计数),检测这个区域内的人数,不能少于多少人,不能多余多少人 */
+class PersonCount
+{
+public:
+    PersonCount();
+    ~PersonCount();
+    void task();        /* 任务线程 */
+
+private:
+    
+
+
+};
+
+
+#endif /* PERSONCOUNT_H */

+ 5 - 2
SecurePlayAuxServer/CMakeLists.txt

@@ -28,6 +28,7 @@ target_include_directories(${execName1} PRIVATE
     ${CMAKE_CURRENT_SOURCE_DIR}/common/LHLog
     ${CMAKE_CURRENT_SOURCE_DIR}/communication
     ${CMAKE_CURRENT_SOURCE_DIR}/GlobalInfo
+    ${CMAKE_CURRENT_SOURCE_DIR}/Application
 
     ${CMAKE_SOURCE_DIR}/External/common
     ${CMAKE_SOURCE_DIR}/External/common/FmtLog
@@ -41,6 +42,7 @@ target_include_directories(${execName1} PRIVATE
     ${LHHTTPAPI_SOURCE_DIRS}
     ${SM_INCLUDE_DIR}
     ${CURL_INCLUDE_DIR}
+    ${spdlog_INCLUDE_DIR}
 )
 #链接Qt库
 target_link_libraries(${execName1} PRIVATE
@@ -51,12 +53,13 @@ target_link_libraries(${execName1} PRIVATE
 )
 #链接外部库
 target_link_libraries(${execName1} PRIVATE
-    fmt::fmt
-    spdlog::spdlog
+    # fmt::fmt
+    # spdlog::spdlog
     # CURL::libcurl
     ${SM_LIBRARY}
     hiredis::hiredis
     ${CURL_LIBRARY}
+    ${spdlog_LIBRARY}
 )
 
 #连接stdc++fs库,如果编译器版本低于GCC9.0,则需要连接这个库

+ 16 - 5
SecurePlayAuxServer/GlobalInfo/GlobalInfo.cpp

@@ -286,7 +286,7 @@ RoomFaceInfo* ListRoomFaceInfo::findRoomFaceInfo(int ChannelID, int RoomID, int
     return nullptr;
 }
 
-IllegalInvasionInfo::IllegalInvasionInfo(IllegalInvasionInfo& other)
+IllegalInvasionInfo::IllegalInvasionInfo(const IllegalInvasionInfo& other)
 {
     isInsertEQM = other.isInsertEQM;
     PKID = other.PKID;
@@ -299,7 +299,7 @@ IllegalInvasionInfo::IllegalInvasionInfo(IllegalInvasionInfo& other)
     strImageInfo = other.strImageInfo;
 }
 
-IllegalInvasionInfo& IllegalInvasionInfo::operator=(IllegalInvasionInfo& other)
+IllegalInvasionInfo& IllegalInvasionInfo::operator=(const IllegalInvasionInfo& other)
 {
     if(this != &other)
     {
@@ -380,7 +380,7 @@ void ListIllegalInvasionInfo::deleteIllInfo(int roomID, int roomType)
 }
 
 
-RoomIllegalInvasionInfo::RoomIllegalInvasionInfo(RoomIllegalInvasionInfo& o)
+RoomIllegalInvasionInfo::RoomIllegalInvasionInfo(const RoomIllegalInvasionInfo& o)
 {
     isAlarm = o.isAlarm;
     RoomID = o.RoomID;
@@ -437,8 +437,12 @@ RoomIllegalInvasionInfo* ListRoomIll::findRoom(int RoomID, int RoomType)
 
 
 
-AlarmRuleInfo::AlarmRuleInfo()
+PersonCountRuleInfo::PersonCountRuleInfo()
 {
+    ChannelID = -1;
+    week = 0;
+    RuleType = 0;
+
     LiveMinEnable = false;
     LiveMaxEnable = false;
     DicMinEnable = false;
@@ -454,10 +458,17 @@ AlarmRuleInfo::AlarmRuleInfo()
     RuleName = "";
 }
 
-AlarmRuleInfo& AlarmRuleInfo::operator=(AlarmRuleInfo& other)
+PersonCountRuleInfo& PersonCountRuleInfo::operator=(PersonCountRuleInfo& other)
 {
     if(this != &other)
     {
+        ChannelID = other.ChannelID;
+        week = other.week;
+        RuleType = other.RuleType;
+        PeriodName = other.PeriodName;
+        StartTime = other.StartTime;
+        EndTime = other.EndTime;
+
         LiveMinEnable = other.LiveMinEnable;
         LiveMaxEnable = other.LiveMaxEnable;
         DicMinEnable = other.DicMinEnable;

+ 14 - 7
SecurePlayAuxServer/GlobalInfo/GlobalInfo.h

@@ -47,7 +47,7 @@ enum class AppFunction
     APP_CONTRABAND,             /* 违禁品识别 */
     APP_ILLEGAL,                /* 非法入侵检测 */
     APP_FATIGUE,                /* 疲劳检测 */
-    APP_REGIONAL,               /* 区域人员检测(需要多个摄像机配合) */
+    APP_REGIONAL,               /* 区域人员检测,人员计数(需要多个摄像机配合) */
     APP_MOUSE,                  /* 老鼠识别 */
     APP_PLAYPHONE,              /* 玩手机识别 */
     APP_NOMASK,                 /* 未戴口罩识别 */
@@ -339,8 +339,8 @@ struct IllegalInvasionInfo
     std::string strImageInfo;           /* 图片信息 */
 
     IllegalInvasionInfo() = default;
-    IllegalInvasionInfo(IllegalInvasionInfo& other);
-    IllegalInvasionInfo& operator=(IllegalInvasionInfo& other);
+    IllegalInvasionInfo(const IllegalInvasionInfo& other);
+    IllegalInvasionInfo& operator=(const IllegalInvasionInfo& other);
 };
 
 /**
@@ -381,7 +381,7 @@ struct RoomIllegalInvasionInfo
     std::vector<PersonInfo> vecPersonInfo;  /* 人员信息 */
 
     RoomIllegalInvasionInfo() = default;
-    RoomIllegalInvasionInfo(RoomIllegalInvasionInfo& o);
+    RoomIllegalInvasionInfo(const RoomIllegalInvasionInfo& o);
     RoomIllegalInvasionInfo& operator=(RoomIllegalInvasionInfo& o);
 };
 
@@ -404,8 +404,15 @@ struct ListRoomIll
  * @brief 报警规则
  * 
  */
-struct AlarmRuleInfo
+struct PersonCountRuleInfo
 {
+    int ChannelID;              /* 通道ID */
+    std::string PeriodName;     /* 时间段名称 */
+    QDateTime StartTime;        /* 开始时间 */
+    QDateTime EndTime;          /* 结束时间 */
+    int week;                   /* 星期 */
+    int RuleType;               /* 规则类型,0表示所有时段,1表示按天,2表示按周 */
+
     bool LiveMinEnable;         /* 启用直播间最小人数 */
     bool LiveMaxEnable;         /* 启用直播间最大人数 */
     bool DicMinEnable;          /* 启用导播间最小人数 */
@@ -420,8 +427,8 @@ struct AlarmRuleInfo
     int LiveDicMax;             /* 直播间和导播间最大人数 */
     std::string RuleName;       /* 规则名称 */
 
-    AlarmRuleInfo();
-    AlarmRuleInfo& operator=(AlarmRuleInfo& other);
+    PersonCountRuleInfo();
+    PersonCountRuleInfo& operator=(PersonCountRuleInfo& other);
 };
 
 /**

+ 82 - 8
SecurePlayAuxServer/SPAServer.cpp

@@ -936,6 +936,10 @@ void SPAServer::threadActPersonWork(FuncActionInfo* RFAInfo)
             2、无权限人员识别:报警判断条件:当判断出区域非法入侵行为时,依据人脸识别结果,判断是否为人脸库人
               员,非人脸库的人员时判断为非法入侵行为(背影需要报警需要结合区域人员检测算法判断)
             3、人员计数和人脸识别数不相等时,判断为非法入侵行为
+        
+        检测逻辑:
+            1、先检测非法的人脸信息
+            2、再检测人员计数和人脸识别数不相等
  * 
  * @param info 
  */
@@ -1129,8 +1133,8 @@ void SPAServer::threadActIllegalInvasion(FuncActionInfo* RFAInfo)
                         if(insertRet)
                         {
                             std::string actionName = g_actionList.getActionName(ai.ActionID);
-                            SPDLOG_LOGGER_INFO(m_logger, "☆ 新增报警信息,频道[{}],房间[{}],摄像头[{}],{},{},有{}个区域,有{}个人脸,{}", 
-                            pIll->ChannelID, pIll->RoomID, pIll->CameraID, actionName, ai.ActionDes, ai.listBbox, ai.FaceIDList.size(), ai.ImageInfo);
+                            SPDLOG_LOGGER_INFO(m_logger, "☆ 新增报警信息,频道[{}],房间[{}],摄像头[{}],{},{},有{}个区域,有{}个人脸,{}", 
+                            pIll->ChannelID, pIll->RoomID, pIll->CameraID, actionName, ai.ActionDes, ai.listBbox.size(), ai.FaceIDList.size(), ai.ImageInfo);
                         }
                     }
                     /* 删除这个非法入侵信息 */
@@ -1164,22 +1168,28 @@ void SPAServer::threadActRegionalPersonnelDetection(FuncActionInfo* RFAInfo)
     std::shared_ptr<FromRedis> fromRedis = std::make_shared<FromRedis>();
     /* 创建写入数据库实例 */
     std::shared_ptr<ToEQMDataBase> toEQMDataBase = std::make_shared<ToEQMDataBase>();
-    /* 局部变量 */
+    /* 局部变量,线程功能需要的信息 */
     std::shared_ptr<FuncActionInfo> pRFAInfo = std::make_shared<FuncActionInfo>();
     *pRFAInfo = *RFAInfo;
     /* 保存每个摄像机的报警信息 */
     std::shared_ptr<std::list<AlarmInfo>> pListAlarmInfo = std::make_shared<std::list<AlarmInfo>>();
+    /* 报警时间段 */
+    std::shared_ptr<std::vector<PersonCountRuleInfo>> pPersonCountRuleInfo = std::make_shared<std::vector<PersonCountRuleInfo>>();
+
+    /* 获取报警规则信息 */
+    toEQMDataBase->getPersonCountRuleInfo(*pPersonCountRuleInfo);
     
     while (m_threadRunning)
     {
-        /* 更新线程信息 */
+        std::this_thread::sleep_for(std::chrono::milliseconds(g_config.ThreadSleepMS));
+        /************ 更新线程信息 ************/
         updateFuncInfo(pRFAInfo);
         if(pRFAInfo->appFunction == AppFunction::APP_NONE)
         {
             break;
         }
 
-        /* 读取Redis数据 */
+        /************ 读取Redis数据 ************/
         pListAlarmInfo->clear();
         for(const auto& RoomInfo : pRFAInfo->listRoomCamActInfo)
         {
@@ -1190,7 +1200,6 @@ void SPAServer::threadActRegionalPersonnelDetection(FuncActionInfo* RFAInfo)
                 if(!fromRedis->getRedisString(strKey, strRetValue))
                 {
                     SPDLOG_LOGGER_ERROR(m_logger, "读取Redis数据失败, Key:{}", strKey);
-                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                     continue;
                 }
                 /* 解析数据 */
@@ -1201,16 +1210,81 @@ void SPAServer::threadActRegionalPersonnelDetection(FuncActionInfo* RFAInfo)
                 if(isEventTimeVaild(alarmInfo.EventTime))
                 {
                     SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, alarmInfo.EventTime);
-                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                     continue;
                 }
                 pListAlarmInfo->push_back(alarmInfo);
             }
         }
+        /************ 获取报警规则(从数据库更新?) ************/
+        if(!toEQMDataBase->getPersonCountRuleInfo(*pPersonCountRuleInfo))
+        {
+            SPDLOG_LOGGER_ERROR(m_logger, "《人员计数》获取报警规则失败");
+            continue;
+        }
+        if(pPersonCountRuleInfo->size() == 0)
+        {
+            SPDLOG_LOGGER_ERROR(m_logger, "《人员计数》无报警规则");
+            break;
+        }
+        /* 获取这个频率的报警信息 */
+        PersonCountRuleInfo personCountRuleInfo;
+        for(auto& it : *pPersonCountRuleInfo)
+        {
+            if(it.ChannelID == pRFAInfo->ChannelID)
+            {
+                personCountRuleInfo = it;
+                break;
+            }
+        }
+        if(personCountRuleInfo.ChannelID < 0)
+        {
+            SPDLOG_LOGGER_ERROR(m_logger, "《人员计数》获取报警规则失败, ChannelID:{}", pRFAInfo->ChannelID);
+            break;
+        }
 
+        /************ 判断是否在检测时间内 ************/
+        QDateTime now = QDateTime::currentDateTime();
+        /* 判断检测时间类型 */
+        if(personCountRuleInfo.RuleType == 0)
+        {
+            /* 所有时段 */
+        }
+        else if(personCountRuleInfo.RuleType == 1)
+        {
+            /* 按天检测 */
+            if(personCountRuleInfo.StartTime <= now && personCountRuleInfo.EndTime >= now)
+            {
+                /* 在检测时间内 */
+            } else
+            {
+                /* 不在检测时间内 */
+                continue;
+            }
+        }
+        else if (personCountRuleInfo.RuleType == 2)
+        {
+            /* 按周检测 */
+            if(personCountRuleInfo.week != now.date().dayOfWeek())
+            {
+                /* 不在检测时间内 */
+                continue;
+            }
+            /* 在检测时间内 */
+            if(personCountRuleInfo.StartTime.time() <= now.time() && personCountRuleInfo.EndTime.time() >= now.time())
+            {
+                /* 在检测时间内 */
+            } else
+            {
+                /* 不在检测时间内 */
+                continue;
+            }
+        }
+
+        /************ 挨个房间检测人数 ************/
         
 
-        std::this_thread::sleep_for(std::chrono::milliseconds(g_config.ThreadSleepMS));
+        /************ 检测频率直播间 + 导播间房间的人数 ************/
+
     }
     setThreadState(pRFAInfo, RunTimeState::RUN_STATE_STOP);
     SPDLOG_LOGGER_INFO(m_logger, "关闭 {} 线程,ChannelID:{}", pRFAInfo->strFunctionName, pRFAInfo->ChannelID);

+ 13 - 3
SecurePlayAuxServer/communication/ToEQMDataBase.cpp

@@ -891,10 +891,10 @@ bool ToEQMDataBase::updateAlarmEndTime(const AlarmInfo& alarmInfo)
 }
 
 /* 获取报警规则表 */
-bool ToEQMDataBase::getAlarmRuleInfo(std::vector<AlarmRuleInfo>& vecInfo)
+bool ToEQMDataBase::getPersonCountRuleInfo(std::vector<PersonCountRuleInfo>& vecInfo)
 {
     nJson json0;
-    json0["opName"] = "SPSS_SelectFromAlarmRule";
+    json0["opName"] = "SPSS_GetPersonCountRule";
     QString strCmd = QString::fromStdString(json0.dump());
     QString strRet;
     auto ret = m_httpApi->DBQDoInterface(enDBOperatorType::EDBOT_Select, strCmd, strRet);
@@ -917,9 +917,19 @@ bool ToEQMDataBase::getAlarmRuleInfo(std::vector<AlarmRuleInfo>& vecInfo)
         {
             return false;
         }
+        vecInfo.clear();
         for(const auto& it : result)
         {
-            AlarmRuleInfo info;
+            PersonCountRuleInfo info;
+            info.ChannelID = it["chnId"].get<int>();
+            info.RuleName = it["periodName"].get<std::string>();
+            QString strStart = QString::fromStdString(it["startTime"].get<std::string>());
+            info.StartTime = QDateTime::fromString(strStart, "yyyy-MM-ss hh:mm:ss");
+            QString strEnd = QString::fromStdString(it["endTime"].get<std::string>());
+            info.EndTime = QDateTime::fromString(strEnd, "yyyy-MM-ss hh:mm:ss");
+            info.week = it["week"].get<int>();
+            info.RuleType = it["type"].get<int>();
+
             info.RuleName = it["ruleName"].get<std::string>();
             info.LiveMinEnable = it["liveMinEnable"].get<bool>();
             info.LiveMaxEnable = it["liveMaxEnable"].get<bool>();

+ 2 - 3
SecurePlayAuxServer/communication/ToEQMDataBase.h

@@ -50,14 +50,13 @@ public:
     /* 更新报警结束时间 */
     bool updateAlarmEndTime(const AlarmInfo& alarmInfo);
 
-    /* 获取报警规则表 */
-    bool getAlarmRuleInfo(std::vector<AlarmRuleInfo>& vecInfo);
+    /* 获取人员计数规则 */
+    bool getPersonCountRuleInfo(std::vector<PersonCountRuleInfo>& vecInfo);
     /* 获取报警时段,也同时获取报警的应用信息 */
     bool getAlarmAppInfo(std::list<AppAndTimeInfo>& listInfo);
 
     /* 写入在岗信息 */
     bool insertOnWorkInfo(const RoomFaceInfo& onWorkInfo);
-    
 
 private:
     std::shared_ptr<spdlog::logger> m_logger = nullptr;