Ver Fonte

V0.5.2
1、完成了人员计数的最大人数检测功能

Apple há 1 mês atrás
pai
commit
0102f3b25c

+ 228 - 3
SecurePlayAuxServer/Application/FuncRegionalPerson.cpp

@@ -5,6 +5,9 @@
 #include "GlobalConfig.h"
 #include "GlobalVariable.h"
 #include "UniversalFunc.h"
+#include "bundled/core.h"
+#include "spdlog.h"
+#include <string>
 
 
 PersonCountRuleInfo::PersonCountRuleInfo()
@@ -115,6 +118,7 @@ RoomPeopleInfo::RoomPeopleInfo()
 {
     RoomID = -1;
     RoomType = Enum_RoomType::ROOM_NONE;
+    RoomName = "";
     MaxNum = 0;
     imagePath = "";
 }
@@ -123,20 +127,68 @@ RoomPeopleInfo::RoomPeopleInfo(const RoomPeopleInfo& other)
 {
     RoomID = other.RoomID;
     RoomType = other.RoomType;
+    RoomName = other.RoomName;
     MaxNum = other.MaxNum;
     imagePath = other.imagePath;
 }
 
-RoomPeopleInfo& RoomPeopleInfo::operator=(const RoomPeopleInfo& other) {
+RoomPeopleInfo& RoomPeopleInfo::operator=(const RoomPeopleInfo& other) 
+{
     if (this != &other) {
         RoomID = other.RoomID;
         RoomType = other.RoomType;
+        RoomName = other.RoomName;
         MaxNum = other.MaxNum;
         imagePath = other.imagePath;
     }
     return *this;
 }
 
+AlarmBuffer::AlarmBuffer()
+{
+    isMax = false;
+    // isInsertDB = false;
+    ChannelID = -1;
+    RoomID = -1;
+    RoomType = Enum_RoomType::ROOM_NONE;
+    PeopleNum = 0;
+    PKID = 0;
+    AlarmTime = QDateTime();
+    imagePath = "";
+    actionDecs = "";
+}
+
+AlarmBuffer::AlarmBuffer(const AlarmBuffer& other)
+{
+    isMax = other.isMax;
+    // isInsertDB = other.isInsertDB;
+    ChannelID = other.ChannelID;
+    RoomID = other.RoomID;
+    RoomType = other.RoomType;
+    PeopleNum = other.PeopleNum;
+    PKID = other.PKID;
+    AlarmTime = other.AlarmTime;
+    imagePath = other.imagePath;
+    actionDecs = other.actionDecs;
+}
+
+AlarmBuffer& AlarmBuffer::operator=(const AlarmBuffer& other)
+{
+    if (this != &other) {
+        isMax = other.isMax;
+        // isInsertDB = other.isInsertDB;
+        ChannelID = other.ChannelID;
+        RoomID = other.RoomID;
+        RoomType = other.RoomType;
+        PeopleNum = other.PeopleNum;
+        PKID = other.PKID;
+        AlarmTime = other.AlarmTime;
+        imagePath = other.imagePath;
+        actionDecs = other.actionDecs;
+    }
+    return *this;
+}
+
 
 
 FuncRegionalPersonCount::FuncRegionalPersonCount()
@@ -255,6 +307,7 @@ void FuncRegionalPersonCount::task()
             RoomPeopleInfo peopleInfo;
             peopleInfo.RoomID = RoomInfo.RoomID;
             peopleInfo.RoomType = RoomInfo.RoomType;
+            peopleInfo.RoomName = RoomInfo.strRoomName;
             /* 获取该房间内最大人数 */
             getRoomMaxNum(RoomInfo.RoomID, peopleInfo.MaxNum, peopleInfo.imagePath);
 
@@ -262,7 +315,11 @@ void FuncRegionalPersonCount::task()
         }
         
         /************ 单独判断每个房间内人数的最大值和最小值 ************/
-
+        for(const auto& it : m_mapRoomPeople)
+        {
+            /* 处理房间内的人数最大值 */
+            handleRoomMaxNum(it.second);
+        }
 
         /************ 检测频率直播间 + 导播间房间的人数 ************/
 
@@ -433,9 +490,177 @@ bool FuncRegionalPersonCount::getRoomMaxNum(int roomID, int& maxNum, std::string
 }
 
 /* 处理房间内的人数最大值 */
-void FuncRegionalPersonCount::handleRoomMaxNum(RoomPeopleInfo& peopleInfo)
+void FuncRegionalPersonCount::handleRoomMaxNum(const RoomPeopleInfo& peopleInfo)
 {
+    std::string roomName = "";
+    int maxNum = 0;
     /* 判断当前房间是否开启了最大人员检测功能 */
+    if(peopleInfo.RoomType == Enum_RoomType::ROOM_LIVE)
+    {
+        if(!m_personCountRule.LiveMaxEnable)
+        {
+            SPDLOG_LOGGER_DEBUG(m_logger, "{} 直播间最大人数检测功能未开启", m_baseLog);
+            return;
+        }
+        /* 判断有没有名称 */
+        if(peopleInfo.RoomName.empty())
+        {
+            roomName = "直播间";
+        } else {
+            roomName = peopleInfo.RoomName;
+        }
+        maxNum = m_personCountRule.LiveMax;
+    }
+    else if(peopleInfo.RoomType == Enum_RoomType::ROOM_DIC)
+    {
+        if(!m_personCountRule.DicMaxEnable)
+        {
+            SPDLOG_LOGGER_DEBUG(m_logger, "{} 导播间最大人数检测功能未开启", m_baseLog);
+            return;
+        }
+        /* 判断有没有名称 */
+        if(peopleInfo.RoomName.empty())
+        {
+            roomName = "导播间";
+        } else {
+            roomName = peopleInfo.RoomName;
+        }
+        maxNum = m_personCountRule.DicMax;
+    } 
+    else if(peopleInfo.RoomType == Enum_RoomType::ROOM_ALL)
+    {
+        if(!m_personCountRule.LiveDicMaxEnable)
+        {
+            SPDLOG_LOGGER_DEBUG(m_logger, "{} 直播间+导播间最大人数检测功能未开启", m_baseLog);
+            return;
+        }
+        /* 判断有没有名称 */
+        if(peopleInfo.RoomName.empty())
+        {
+            roomName = "直播间+导播间";
+        } else {
+            roomName = peopleInfo.RoomName;
+        }
+        maxNum = m_personCountRule.LiveDicMax;
+    }
+    else
+    {
+        SPDLOG_LOGGER_WARN(m_logger, "{} 房间类型错误", m_baseLog);
+        return;
+    }
+
+    /* 查找房间信息 */
+    RoomCamActInfo roomInfo;
+    if(!findRoomInfo(peopleInfo.RoomID, roomInfo))
+    {
+        SPDLOG_LOGGER_ERROR(m_logger, "房间ID:{},房间信息不存在", peopleInfo.RoomID);
+        return;
+    }
+
+    /* 开启了最大人数的检测,判断是否超过最大人数 */
+    if(peopleInfo.MaxNum > maxNum)
+    {
+        /* 超过了最大人数,判断是否已经加入了内存缓冲区 */
+        AlarmBuffer alarmBuffer;
+        if(findAlarmBuffer(peopleInfo.RoomID, alarmBuffer))
+        {
+            /* 更新时间,这里只更新时间吗?最大人数和图片不更新吗? */
+            alarmBuffer.AlarmTime = m_nowTime;
+        }else 
+        {
+            /* 没有加入缓冲区,先写入数据库,再加入缓冲区 */
+            AlarmInfo alarmInfo;
+            alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
+            alarmInfo.appFunction = m_funcThreadInfo.appFunction;
+            alarmInfo.RoomID = peopleInfo.RoomID;
+            alarmInfo.DeviceID = roomInfo.mapCameraAction.begin()->first;
+            alarmInfo.ImageInfo = peopleInfo.imagePath;
+            alarmInfo.ActionID = roomInfo.mapCameraAction.begin()->second.front();
+            alarmInfo.EventTime = m_nowTime.toString("yyyy-MM-dd hh:mm:ss.zzz").toStdString();
+            alarmInfo.Is_Alarm = true;
+            alarmInfo.ActionDes = fmt::format("{}人数为{},已超过最大人数{}限制", 
+                                                roomName, peopleInfo.MaxNum, maxNum);
+            for(auto& it : roomInfo.mapCameraAction)
+            {
+                alarmInfo.listBbox.push_back(GConfig.getCameraName(it.first));
+            }
+            int pkid = 0;
+            if(!m_fromWebAPI->insertAlarmInfo(alarmInfo, pkid))
+            {
+                SPDLOG_LOGGER_ERROR(m_logger, "{} 写入报警信息失败", m_baseLog);
+                return;
+            }
+            /* 将报警信息写入缓存中 */
+            alarmBuffer.isMax = true;
+            // alarmBuffer.isInsertDB = true;
+            alarmBuffer.ChannelID = m_funcThreadInfo.ChannelID;
+            alarmBuffer.RoomID = peopleInfo.RoomID;
+            alarmBuffer.PKID = pkid;
+            alarmBuffer.RoomType = peopleInfo.RoomType;
+            alarmBuffer.PeopleNum = peopleInfo.MaxNum;
+            alarmBuffer.AlarmTime = m_nowTime;
+            alarmBuffer.imagePath = peopleInfo.imagePath;
+            alarmBuffer.actionDecs = alarmInfo.ActionDes;
+            m_mapAlarmBuffer.insert(std::make_pair(peopleInfo.RoomID, alarmBuffer));
+        }
+    }else 
+    {
+        /* 未超过最大人数,判断是否已经写入的数据库,如果已经写入了数据库,就结束报警 */
+        AlarmBuffer alarmBuffer;
+        if(findAlarmBuffer(peopleInfo.RoomID, alarmBuffer))
+        {
+            /* 已写入数据库,结束报警,但是需要注意,人数少于一定时间后才结束报警,不会立马结束 */
+            if(alarmBuffer.AlarmTime.secsTo(m_nowTime) > GVariable.AppPeopleCount_LessTime)
+            {
+                SPDLOG_LOGGER_INFO(m_logger, "{} 房间: {},超过最大人数{},报警结束", 
+                                    m_baseLog, roomName, maxNum);
+                /* 结束报警 */
+                if(!m_fromWebAPI->endAlarmInfoByPKID(alarmBuffer.PKID, m_nowTime))
+                {
+                    SPDLOG_LOGGER_ERROR(m_logger, "{} 结束超过最大人数报警失败,PKID: {}", m_baseLog, alarmBuffer.PKID);
+                    return;
+                }
+                /* 删除报警缓冲区 */
+                m_mapAlarmBuffer.erase(peopleInfo.RoomID);
+            }
+        }
+    }
+}
+
+/* 根据房间ID查找报警缓冲区 */
+bool FuncRegionalPersonCount::findAlarmBuffer(int roomID, AlarmBuffer& alarmBuffer)
+{
+    if(m_mapAlarmBuffer.empty())
+    {
+        return false;
+    }
+    for(auto& it : m_mapAlarmBuffer)
+    {
+        if(it.first == roomID)
+        {
+            alarmBuffer = it.second;
+            return true;
+        }
+    }
+    return false;
+}
+
+/* 根据房间ID查找房间信息 */
+bool FuncRegionalPersonCount::findRoomInfo(int roomID, RoomCamActInfo& roomInfo)
+{
+    if(m_listRoomCamAct.empty())
+    {
+        return false;
+    }
+    for(auto& it : m_listRoomCamAct)
+    {
+        if(it.RoomID == roomID)
+        {
+            roomInfo = it;
+            return true;
+        }
+    }
+    return false;
 }
 
 

+ 27 - 2
SecurePlayAuxServer/Application/FuncRegionalPerson.h

@@ -2,6 +2,8 @@
 #define FUNCREGIONALPERSON_H
 
 #include "FuncBase.h"
+#include <cstdint>
+#include <qdatetime.h>
 #include <string>
 #include "GlobalVariable.h"
 
@@ -63,6 +65,7 @@ struct RoomPeopleInfo
 {
     int RoomID;                 /* 房间ID */
     Enum_RoomType RoomType;     /* 房间类型 */
+    std::string RoomName;       /* 房间名称 */
     int MaxNum;                 /* 最大人数 */
     std::string imagePath;      /* 图片路径 */
 
@@ -73,6 +76,23 @@ struct RoomPeopleInfo
 };
 
 
+struct AlarmBuffer
+{
+    bool isMax;                 /* 是否最大人数,false是最小人数 */
+    // bool isInsertDB;            /* 是否已经插入数据库 */
+    int ChannelID;              /* 通道ID */
+    int RoomID;                 /* 房间ID */
+    Enum_RoomType RoomType;     /* 房间类型 */
+    int PeopleNum;              /* 人数 */
+    uint64_t PKID;              /* 报警编号,在数据库中的编号 */
+    QDateTime AlarmTime;        /* 报警时间 */
+    std::string imagePath;      /* 图片路径 */
+    std::string actionDecs;     /* 报警描述 */
+
+    AlarmBuffer();
+    AlarmBuffer(const AlarmBuffer& other);
+    AlarmBuffer& operator=(const AlarmBuffer& other);
+};
 
 /**
  * @brief 区域人员检测,检测这个区域内的人数,不能少于多少人,不能多余多少人
@@ -109,19 +129,24 @@ private:
     bool getRoomMaxNum(int roomID, int& maxNum, std::string& strImagePath);
 
     /* 处理房间内的人数最大值 */
-    void handleRoomMaxNum(RoomPeopleInfo& peopleInfo);
+    void handleRoomMaxNum(const RoomPeopleInfo& peopleInfo);
+
+    /* 根据房间ID查找报警缓冲区 */
+    bool findAlarmBuffer(int roomID, AlarmBuffer& alarmBuffer);
+    /* 根据房间ID查找房间信息 */
+    bool findRoomInfo(int roomID, RoomCamActInfo& roomInfo);
 
 private:
     ListAlarmInfo* m_pListAlarm = nullptr;                      /* 报警信息 */
     std::list<RoomCamActInfo> m_listRoomCamAct;                 /* 房间和算法ID关联列表,这里存储的是直播间和导播间的房间信息 */
     PersonCountRuleInfo m_personCountRule;                      /* 人员计数规则 */
-    // QDateTime m_nowTime;                                        /* 当前时间 */
 
     std::list<EndAlarmParam> m_listEndAlarmPara;                /* 报警列表 */
 
     int m_liveDicNum = 0;                                       /* 直播间和导播间的最大人数之和 */
     std::string m_strLiveDicImagePath;                          /* 直播间和导播间的报警图片路径 */
     std::map<int, RoomPeopleInfo> m_mapRoomPeople;              /* 房间内的人数信息,int是房间ID */
+    std::map<int, AlarmBuffer> m_mapAlarmBuffer;                /* 报警信息,int是房间ID */
 };
 
 

+ 2 - 2
SecurePlayAuxServer/GlobalInfo/GlobalConfig.cpp

@@ -223,7 +223,7 @@ bool GlobalConfig::readAppConfig(const QString& strConfigFile)
     GVariable.AppContraband_Time = settings.value("APPBADTHING", 50).toInt();                 /* 违禁物品出现的时间 */
     GVariable.AppBadMan_Time = settings.value("APPBADMAN", 50).toInt();                     /* 非法入侵 */
     GVariable.AppTired_Time = settings.value("APPTIRED", 50).toInt();                       /* 疲劳检测时间 */
-    GVariable.AppPeopleCont = settings.value("APPPEPOLECONT", 50).toInt();             /* 人员聚集时间 */
+    GVariable.AppPeopleCount_LessTime = settings.value("APPPEPOLECONT", 50).toInt();    /* 人员聚集时间 */
     GVariable.AppPlayPhone = settings.value("APPPLAYPHONE", 50).toInt();               /* 玩手机识别 */
     GVariable.AppMouse = settings.value("APPMOUSE", 50).toInt();                       /* 手势识别 */
     GVariable.AppMask = settings.value("APPMASK", 5).toInt();                         /* 戴口罩识别 */
@@ -245,7 +245,7 @@ void GlobalConfig::printAppConfig()
     SPDLOG_INFO("APPBADTHING:       {}", GVariable.AppContraband_Time);
     SPDLOG_INFO("APPBADMAN:         {}", GVariable.AppBadMan_Time);
     SPDLOG_INFO("APPTIRED:          {}", GVariable.AppTired_Time);
-    SPDLOG_INFO("APPPEOPLECONT:     {}", GVariable.AppPeopleCont);
+    SPDLOG_INFO("APPPEOPLECONT:     {}", GVariable.AppPeopleCount_LessTime);
     SPDLOG_INFO("APPPLAYPHONE:      {}", GVariable.AppPlayPhone);
     SPDLOG_INFO("APPMOUSE:          {}", GVariable.AppMouse);
     SPDLOG_INFO("APPMASK:           {}", GVariable.AppMask);

+ 1 - 1
SecurePlayAuxServer/GlobalInfo/GlobalConfig.h

@@ -32,7 +32,7 @@ public:
     int AppContraband_Time;                 /* 违禁物品出现的时间 */
     int AppBadMan_Time;                     /* 非法入侵超时时间 */
     int AppTired_Time;                      /* 疲劳检测时间 */
-    int AppPeopleCont;                      /* 区域人员统计 */
+    int AppPeopleCount_LessTime;            /* 区域人员统计少于多长时间会取消报警 */
     int AppPlayPhone;                       /* 玩手机识别 */
     int AppMouse;                           /* 老鼠识别 */
     int AppMask;                            /* 戴口罩识别 */