#include "AbandClipStrategy.h" #include "ClipCfg.h" #include "AbandObjCfg.h" #include "AbandClipCfg.h" #include "OSTime.h" #include "SysUtils.h" NAMESPACE_MAS_BEGIN NAMESPACE_ABANDCLIP_BEGIN AbandClipStrategy::AbandClipStrategy() : Strategy("AbandClip", "遗留物检测判定策略") {} AbandClipStrategy::~AbandClipStrategy() { this->Dispose(); } TZ_INT AbandClipStrategy::Initialize() { m_inited = TRUE; return MEC_OK; } TZ_INT AbandClipStrategy::Dispose() { m_inited = FALSE; return MEC_OK; } TZ_INT AbandClipStrategy::SetStrategyCfg(const std::string & param) { if (!m_inited) return MEC_NOT_INITED; AbandClipCfg cfg; AbandClipCfg::fromJson(param, cfg); m_featureThreshold = cfg.FeatureThreshold; std::ifstream file(cfg.FeatureFilePath); if (!file.is_open()) { TZLogError("Open file failed!!!"); return MEC_FAILED; } std::string jsonContent((std::istreambuf_iterator(file)), std::istreambuf_iterator()); if (jsonContent.empty()) { TZLogError("Json content is empty!!!"); return MEC_FAILED; } file.close(); tzc::json::JsonDoc document; document.Parse(jsonContent.c_str()); if (document.HasParseError()) { TZLogError("Parse json failed!!!"); return MEC_FAILED; } for (auto it = document.MemberBegin(); it != document.MemberEnd(); ++it) { if (!it->name.IsString() || !it->value.IsArray()) { continue; } TextFeature feature; feature.text = it->name.GetString(); // 提取数组内容 for (const auto& v : it->value.GetArray()) { if (v.IsNumber()) { DataItem dataItem; dataItem.val = v.GetFloat(); feature.features.push_back(dataItem); } } m_textFeatureList.push_back(feature); } return MEC_OK; } TZ_INT AbandClipStrategy::DoStrategy(SPtr & streamInfo) { if (!m_inited) return MEC_NOT_INITED; auto & detMap = streamInfo->GetAllDetRst(); StraRst rst; rst.RstType = SRT_ALARM; if (detMap.count("Clip")) { m_clipLock.Lock(); m_qClipQueue.push(detMap["Clip"]->Result); m_clipLock.Unlock(); } else { TZLogWarn("Rst not found!!!"); streamInfo->SetStraRst(m_key, rst, streamInfo->GetMediaRsc()); return MEC_FAILED; } m_clipLock.Lock(); if (m_qClipQueue.empty()) { m_clipLock.Unlock(); streamInfo->SetStraRst(m_key, rst, streamInfo->GetMediaRsc()); return MEC_OK; } std::string jClipRst = m_qClipQueue.front(); m_qClipQueue.pop(); m_clipLock.Unlock(); // Clip Start clip::ClipDetectResult clipRst; clip::ClipDetectResult::fromJson(jClipRst, clipRst); std::vector abandobjFeature; for (const auto& data : clipRst.output_data) { abandobjFeature.push_back(data.val); TZLogInfo("AbandObjFeature: %f", data.val); } if (abandobjFeature.empty()) { TZLogWarn("AbandObjFeature is empty!!!"); streamInfo->SetStraRst(m_key, rst, streamInfo->GetMediaRsc()); return MEC_FAILED; } // Clip End const TZ_FLOAT MIN_DOT_PRODUCT = std::numeric_limits::lowest(); TZ_FLOAT maxDotProduct = MIN_DOT_PRODUCT; std::string bestMatchText; for (const auto& textFeature : m_textFeatureList) { std::vector featureValues; for (const auto& dataItem : textFeature.features) { featureValues.push_back(dataItem.val); } TZ_FLOAT dotProduct = calculateDotProduct(featureValues, abandobjFeature); if (dotProduct > maxDotProduct && dotProduct > m_featureThreshold) { maxDotProduct = dotProduct; bestMatchText = textFeature.text; } } if (!bestMatchText.empty()) { rst.RstType = SRT_ALARM; std::ostringstream oss; oss << "Detected left-behind item, class: " << bestMatchText; rst.RstName = oss.str(); rst.BeginTime = TIME_STAMP_NOW; } else { rst.RstType = SRT_ALARM; rst.RstName = "Detected left-behind, class: Unknown"; } streamInfo->SetStraRst(m_key, rst, streamInfo->GetMediaRsc()); return MEC_OK; } TZ_FLOAT AbandClipStrategy::calculateDotProduct(const std::vector& matrix1, const std::vector& matrix2) { TZ_FLOAT dotProduct = 0.0f; for (TZ_INT i = 0; i < 512; ++i) { dotProduct += matrix1[i] * matrix2[i]; } return dotProduct; } NAMESPACE_ABANDCLIP_END NAMESPACE_MAS_END