123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- #include "FuncIllegalInvasion.h"
- #include "GlobalVariable.h"
- #include "GlobalConfig.h"
- #include "FromRedis.h"
- #include "FromWebAPI.h"
- #include "UniversalFunc.h"
- RoomIllegalInvasionInfo::RoomIllegalInvasionInfo(const RoomIllegalInvasionInfo& o)
- {
- isAlarm = o.isAlarm;
- RoomID = o.RoomID;
- RoomType = o.RoomType;
- numMaxFace = o.numMaxFace;
- numMaxPerson = o.numMaxPerson;
- listBBox = o.listBBox;
- strMessage = o.strMessage;
- strImage = o.strImage;
- CameraID = o.CameraID;
- }
- RoomIllegalInvasionInfo& RoomIllegalInvasionInfo::operator=(const RoomIllegalInvasionInfo& o)
- {
- if(this != &o) {
- isAlarm = o.isAlarm;
- RoomID = o.RoomID;
- RoomType = o.RoomType;
- numMaxFace = o.numMaxFace;
- numMaxPerson = o.numMaxPerson;
- listBBox = o.listBBox;
- strMessage = o.strMessage;
- strImage = o.strImage;
- CameraID = o.CameraID;
- }
- return *this;
- }
- /* 添加房间 */
- void ListRoomIll::addRoom(int RoomID, Enum_RoomType RoomType)
- {
- auto p = findRoom(RoomID, RoomType);
- if(p == nullptr)
- {
- RoomIllegalInvasionInfo ill;
- ill.RoomID = RoomID;
- ill.RoomType = RoomType;
- listRoomIll.push_back(ill);
- }
- }
- /* 查找是否有相同的房间 */
- RoomIllegalInvasionInfo* ListRoomIll::findRoom(int RoomID, Enum_RoomType RoomType)
- {
- for(auto& it : listRoomIll)
- {
- if(it.RoomID == RoomID && it.RoomType == RoomType)
- {
- return ⁢
- }
- }
- return nullptr;
- }
- IllegalInvasionInfo::IllegalInvasionInfo(const IllegalInvasionInfo& other)
- {
- isInsertEQM = other.isInsertEQM;
- PKID = other.PKID;
- CameraID = other.CameraID;
- RoomID = other.RoomID;
- ChannelID = other.ChannelID;
- RoomType = other.RoomType;
- FirstTime = other.FirstTime;
- strActionDec = other.strActionDec;
- strImageInfo = other.strImageInfo;
- }
- IllegalInvasionInfo& IllegalInvasionInfo::operator=(const IllegalInvasionInfo& other)
- {
- if(this != &other)
- {
- isInsertEQM = other.isInsertEQM;
- PKID = other.PKID;
- CameraID = other.CameraID;
- RoomID = other.RoomID;
- ChannelID = other.ChannelID;
- RoomType = other.RoomType;
- FirstTime = other.FirstTime;
- strActionDec = other.strActionDec;
- strImageInfo = other.strImageInfo;
- }
- return *this;
- }
- /* 添加信息 */
- void ListIllegalInvasionInfo::addIllInfo(IllegalInvasionInfo& info)
- {
- if(findIllInfo(info) == nullptr)
- {
- listIll.push_back(info);
- }
- }
- /* 查找相同的信息 */
- IllegalInvasionInfo* ListIllegalInvasionInfo::findIllInfo(IllegalInvasionInfo& info)
- {
- for(auto& it : listIll)
- {
- if(it.RoomID == info.RoomID && it.RoomType == info.RoomType)
- {
- return ⁢
- }
- }
- return nullptr;
- }
- IllegalInvasionInfo* ListIllegalInvasionInfo::findIllInfo(int roomID, Enum_RoomType roomType)
- {
- for(auto& it : listIll)
- {
- if(it.RoomID == roomID && it.RoomType == roomType)
- {
- return ⁢
- }
- }
- return nullptr;
- }
- /* 删除报警信息 */
- void ListIllegalInvasionInfo::deleteIllInfo(IllegalInvasionInfo& info)
- {
- for(auto it = listIll.begin(); it != listIll.end();)
- {
- if(it->RoomID == info.RoomID && it->RoomType == info.RoomType)
- {
- it = listIll.erase(it);
- }else {
- ++it;
- }
- }
- }
- void ListIllegalInvasionInfo::deleteIllInfo(int roomID, Enum_RoomType roomType)
- {
- for(auto it = listIll.begin(); it != listIll.end();)
- {
- if(it->RoomID == roomID && it->RoomType == roomType)
- {
- it = listIll.erase(it);
- }else {
- ++it;
- }
- }
- }
- /* ===================================================================================
- * 功能类:FuncIllegalInvasion
- * =================================================================================== */
- FuncIllegalInvasion::FuncIllegalInvasion()
- {
- m_logger = spdlog::get("SPAServer");
- if(m_logger == nullptr)
- {
- SPDLOG_ERROR("SPAServer logger is nullptr");
- return;
- }
- m_pListIllInfo = std::make_shared<ListIllegalInvasionInfo>();
- }
- FuncIllegalInvasion::~FuncIllegalInvasion()
- {
- if(m_pListIllInfo != nullptr)
- {
- m_pListIllInfo.reset();
- m_pListIllInfo = nullptr;
- }
- }
- /* 是否报警 */
- bool FuncIllegalInvasion::isAlarm(const std::list<PersonInfo>& listPersion)
- {
- for(const auto& it : listPersion)
- {
- if(it.PersonID == "-1")
- {
- return true;
- }
- }
- return false;
- }
- /* 线程功能 */
- void FuncIllegalInvasion::task()
- {
- std::string strFaceActionID; /* 人脸识别的Action */
- std::string strCountActionID; /* 人员计数的Action */
- while (GThreadInfo.getRunning())
- {
- std::this_thread::sleep_for(std::chrono::milliseconds(GVariable.ThreadSleepMS()));
- /* 更新线程信息 */
- GThreadInfo.updateFuncInfo(m_funcThreadInfo);
- if(m_funcThreadInfo.RunState == RunTimeState::RUN_STATE_STOP)
- {
- break;
- }
- /* 判断是否在检测时间段内 */
- if(!isInDetectTime(m_periodInfo))
- {
- continue;
- }
- /* 更新算法ActionID */
- {
- GVariable.mutexRW.lockForRead();
- strFaceActionID = GVariable.ActFaceIdentify();
- strCountActionID = GVariable.ActPersonCount();
- GVariable.mutexRW.unlock();
- }
- /* -----------------------------------------------------------------------
- * 读取Redis数据
- * ----------------------------------------------------------------------- */
- readRedisData(m_listSrcAlarm);
- /* 找出房间的个数,按照房间进行判断 */
- ListRoomIll listRoomIll;
- for(auto& it : m_funcThreadInfo.listRoomCamActInfo)
- {
- listRoomIll.addRoom(it.RoomID, it.RoomType);
- }
- /* -----------------------------------------------------------------------
- * 处理读取到的数据
- * ----------------------------------------------------------------------- */
- /* 根据房间解析人脸识别的非法入侵,检测到了非法人脸,就可以直接报警了 */
- for(auto& room : listRoomIll.getData())
- {
- /* 对获取到的数据挨个判断 */
- for(const auto& alarm : m_listSrcAlarm.listAlarmInfo)
- {
- if(room.RoomID != alarm->RoomID)
- {
- continue;
- }
- /* 统计这个房间内《人脸算法》检测到的最大人员数 */
- if(alarm->ActionID == strFaceActionID)
- {
- if(alarm->listPersonInfo.size() > room.numMaxFace)
- {
- room.numMaxFace = alarm->listPersonInfo.size();
- room.listBBox = alarm->listBbox;
- room.listPersonInfo = alarm->listPersonInfo;
- }
- }
- /* 判断有没有非法入侵人员 */
- if(isAlarm(alarm->listPersonInfo))
- {
- room.isAlarm = true;
- room.strMessage = "人员非法入侵(未知人员)";
- if( !alarm->ImageInfo.empty() )
- {
- room.strImage = alarm->ImageInfo;
- }
- room.CameraID = alarm->DeviceID;
- }
- }
-
- }
- /* 判断《人脸算法》识别到的数目和《人员计数算法》识别到的人数是否相等,如果上面报警了,这里就不用检测了 */
- for(auto& room : listRoomIll.getData())
- {
- if(room.isAlarm)
- {
- /* 上面的人脸识别算法已经识别到非法入侵了 */
- continue;
- }
- /* 这个房间的人脸算法没有识别到非法入侵 */
- for(const auto& alarm : m_listSrcAlarm.listAlarmInfo)
- {
- if(room.RoomID != alarm->RoomID)
- {
- continue;
- }
- /* 人员计数 */
- if(alarm->ActionID == strCountActionID)
- {
- /* 统计这个房间内《人员计数算法》检测到的最大人员数 */
- if(alarm->listBbox.size() > room.numMaxPerson)
- {
- room.numMaxPerson = alarm->listBbox.size();
- room.listBBox = alarm->listBbox;
- if(!alarm->ImageInfo.empty())
- {
- room.strImage = alarm->ImageInfo;
- }
- room.CameraID = alarm->DeviceID;
- }
- }
- }
- /* 判断人数是否一致 */
- if(room.numMaxFace != room.numMaxPerson)
- {
- room.strMessage = fmt::format("非法入侵(人员计数 {} 和人脸数 {} 不一致)", room.numMaxPerson, room.numMaxFace);
- room.isAlarm = true;
- }
- }
- /* 将非法入侵的信息存储到数组缓存中,等待报警结束后判断是否需要写入EQM数据库 */
- for(auto& room : listRoomIll.getData())
- {
- if(room.isAlarm)
- {
- auto pIll = m_pListIllInfo->findIllInfo(room.RoomID, room.RoomType);
- /* 正在报警,检查缓存中是否有这个报警信息 */
- if(pIll == nullptr)
- {
- IllegalInvasionInfo info;
- info.ChannelID = m_funcThreadInfo.ChannelID;
- info.CameraID = room.CameraID;
- info.RoomID = room.RoomID;
- info.RoomType = room.RoomType;
- info.strActionDec = room.strMessage;
- info.strImageInfo = room.strImage;
- info.FirstTime = QDateTime::currentDateTime();;
- m_pListIllInfo->addIllInfo(info);
- }
- }
- else
- {
- auto pIll = m_pListIllInfo->findIllInfo(room.RoomID, room.RoomType);
- if(pIll == nullptr)
- {
- /* 没有报警,继续下一个房间 */
- continue;
- }
- /* 没有报警,检查是否是报警结束了,是否符合写入数据库的条件 */
- QDateTime currTime = QDateTime::currentDateTime();
- int secs = currTime.toSecsSinceEpoch() - pIll->FirstTime.toSecsSinceEpoch();
- if(secs >= GVariable.AppIllInvasion_Time)
- {
- if(!pIll->strImageInfo.empty())
- {
- /* 超过非法入侵的时间,写入数据库 */
- AlarmInfo ai;
- ai.ChannelID = m_funcThreadInfo.ChannelID;
- ai.RoomID = pIll->RoomID;
- ai.ActionID = GVariable.ActPersonCount();
- ai.ActionDes = pIll->strActionDec;
- ai.ImageInfo = pIll->strImageInfo;
- ai.StartTime = pIll->FirstTime;
- ai.EndTime = currTime;
- ai.EventTime = pIll->FirstTime;
- ai.listPersonInfo = room.listPersonInfo;
- ai.listBbox = room.listBBox;
- bool insertRet = m_fromWebAPI->insertAlarmInfo(ai);
- if(insertRet)
- {
- std::string actionName = GVariable.getActionName(ai.ActionID);
- SPDLOG_LOGGER_INFO(m_logger, "☆ 新增报警信息,频道[{}],房间[{}],摄像头[{}],{},{},有{}个区域,有{}个人脸,{}",
- pIll->ChannelID, pIll->RoomID, pIll->CameraID, actionName, ai.ActionDes, ai.listBbox.size(), ai.FaceIDList.size(), ai.ImageInfo);
- }
- }
- else {
- SPDLOG_LOGGER_WARN(m_logger, "× 取消新增报警信息,因为没有图片,频道[{}],房间[{}],摄像头[{}],{},{},有{}个区域,有{}个人脸",
- pIll->ChannelID, pIll->RoomID, pIll->CameraID, pIll->strActionDec, pIll->strImageInfo, room.listBBox.size(), room.listPersonInfo.size());
- }
- /* 删除这个非法入侵信息 */
- m_pListIllInfo->deleteIllInfo(*pIll);
- }
- }
- }
- }
- m_listSrcAlarm.clearAlarmInfo();
- }
- /* 读取Redis数据 */
- // void FuncIllegalInvasion::readRedisData()
- // {
- // m_listSrcAlarm.clearAlarmInfo();
- // /* 读取Redis数据 */
- // for(const auto& roomInfo : m_funcThreadInfo.listRoomCamActInfo)
- // {
- // for(const auto& cam : roomInfo.mapCameraAction)
- // {
- // for(const auto act : cam.second)
- // {
- // /* 读取Redis数据 */
- // std::string strKey = std::to_string(cam.first) + ":" + act;
- // std::string strRetValue;
- // // SPDLOG_LOGGER_DEBUG(m_logger, "读取Redis数据, Key:{}", strKey);
- // if(!m_fromRedis->getRedisString(strKey, strRetValue))
- // {
- // // SPDLOG_LOGGER_ERROR(m_logger, "读取Redis数据失败, Key:{}", strKey);
- // std::this_thread::sleep_for(std::chrono::milliseconds(10));
- // continue;
- // }
- // /* 解析数据,先设置基础数据 */
- // AlarmInfo newAlarmInfo;
- // newAlarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
- // newAlarmInfo.appFunction = m_funcThreadInfo.appFunction;
- // newAlarmInfo.RoomID = roomInfo.RoomID;
- // newAlarmInfo.DeviceID = cam.first;
- // newAlarmInfo.ActionID = act;
-
- // parseRedisBaseData(strRetValue, newAlarmInfo);
- // parseRedisBBoxesData(strRetValue, newAlarmInfo);
- // /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
- // if(!isEventTimeVaild(newAlarmInfo.EventTime))
- // {
- // /* 事件时间超过600秒,可能是超脑挂了 */
- // SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, newAlarmInfo.EventTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
- // std::this_thread::sleep_for(std::chrono::milliseconds(100));
- // continue;
- // }
- // m_listSrcAlarm.addAlarmInfo(newAlarmInfo);
- // SPDLOG_LOGGER_DEBUG(m_logger, "报警数据: {}, 房间ID: {}, 报警时间: {}, bBox数目: {}, Person数目: {}",
- // strKey, roomInfo.RoomID, newAlarmInfo.EventTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(),
- // newAlarmInfo.listBbox.size(), newAlarmInfo.listPersonInfo.size());
- // }
- // }
- // }
- // }
|