#include "DetUtils.h" #include "ClipDetector.h" #include "Logger.h" #include "OSTime.h" #include "SysUtils.h" NAMESPACE_MAS_BEGIN NAMESPACE_CLIP_BEGIN ClipDetector::ClipDetector(const std::string& key, const std::string& name): Detector(key, name), m_clip(nullptr) {} ClipDetector::~ClipDetector() { this->Dispose(); } TZ_INT ClipDetector::Initialize(const std::string& initParam) { if (m_inited) { TZLogInfo("ClipDetector has been initialized~~~"); return MEC_OK; } m_clip = ClipApp::Instance(); m_clip->Initialize(initParam); this->Start(); m_inited = TRUE; TZLogInfo("ClipDetector initialized~~~"); return MEC_OK; } TZ_INT ClipDetector::Dispose() { if (!m_inited) { return MEC_NOT_INITED; } this->StopAndWait(); m_inited = FALSE; return MEC_OK; } TZ_INT ClipDetector::TurnOnGPU() { m_useGPU = TRUE; return MEC_OK; } TZ_INT ClipDetector::TurnOffGPU() { m_useGPU = FALSE; return MEC_OK; } TZ_INT ClipDetector::DoDetect( SPtr& media, fDetCallback callback, void* ctx) { if (!m_inited || !callback || !media) { TZLogWarn("detector state is not active!!!"); return MEC_FAILED; } if (m_sema.Count() > 3000) { TZLogInfo("sema is more than 3000~~~"); return MEC_FAILED; } m_cntLock.Lock(); ++m_detCount; if (m_detCount != m_detSample) { m_cntLock.Unlock(); this->skipFrame(media, callback, ctx); return MEC_OK; } m_detCount = 0; m_cntLock.Unlock(); m_listLock.Lock(); m_waitList.push_back({media, callback, ctx}); if (m_waitList.size() > MAX_WAIT_LIST_LEN) { TZLogInfo("m_waitList.size = %d", m_waitList.size()); } m_listLock.Unlock(); m_sema.Signal(); return MEC_OK; } TZ_INT ClipDetector::SetDetectCfg(const std::string& conf) { if (!m_inited) return MEC_NOT_INITED; ClipCfg cfgParam; ClipCfg::fromJson(conf, cfgParam); m_detSample = detutils::GetDetSample(cfgParam.freq); return MEC_OK; } void ClipDetector::Entry() { while (!this->IsStop()) { if (!m_sema.Wait(CLIP_WAIT_MSECOND)) continue; m_listLock.Lock(); TZ_INT skipCnt = m_waitList.size() - MAX_WAIT_LIST_LEN; if (skipCnt > 0) { TZLogInfo("m_waitList.size=%d, will skip %d frames", m_waitList.size(), skipCnt); } else { skipCnt = 0; } m_listLock.Unlock(); while (skipCnt > 0) { m_listLock.Lock(); auto front = m_waitList.front(); m_waitList.pop_front(); m_listLock.Unlock(); SPtr media = std::get<0>(front); fDetCallback callback = std::get<1>(front); void* ctx = std::get<2>(front); this->skipFrame(media, callback, ctx); --skipCnt; } m_listLock.Lock(); if (m_waitList.empty()) { m_listLock.Unlock(); continue; } auto front = m_waitList.front(); m_waitList.pop_front(); m_listLock.Unlock(); SPtr media = std::get<0>(front); fDetCallback callback = std::get<1>(front); void* ctx = std::get<2>(front); SPtr data = media->GetMediaRsc(); if (!data || !data->Mem) { TZLogWarn("MediaRsc is nullptr!!!"); this->skipFrame(media, callback, ctx); continue; } cv::Mat image(cv::Mat(data->Height, data->Width, CV_8UC3, data->Mem)); auto & detMap = media->GetAllDetRst(); if (detMap.count("AbandObj")) { m_abandObjLock.Lock(); m_qAbandObjQueue.push(detMap["AbandObj"]->Result); m_abandObjLock.Unlock(); } ClipDetectResult detRes; if (!m_qAbandObjQueue.empty()) { m_abandObjLock.Lock(); std::string jAbandObjRst = m_qAbandObjQueue.front(); m_qAbandObjQueue.pop(); m_abandObjLock.Unlock(); abandobj::AbandObjDetectResult abandObjRst; abandobj::AbandObjDetectResult::fromJson(jAbandObjRst, abandObjRst); std::vector abandObjProposals = abandObjRst.proposals; if (!abandObjProposals.empty()) { for (const auto& proposal : abandObjProposals) { AbandObjBox box; box.x = proposal.x; box.y = proposal.y; box.w = proposal.w; box.h = proposal.h; detRes.boxes.push_back(box); } cropImageByProposals(image, abandObjProposals); m_clip->DoDetect(image, detRes); } } m_rstLock.Lock(); m_cacheJson = detRes.toJson(); m_cacheDraw.clear(); media->AddDetRst(m_key, m_cacheJson, data, m_cacheDraw); m_rstLock.Unlock(); callback(media, ctx); } } void ClipDetector::skipFrame( SPtr & media, fDetCallback callback, void * ctx) { m_rstLock.Lock(); media->AddDetRst(m_key, m_cacheJson, media->GetMediaRsc(), m_cacheDraw); m_rstLock.Unlock(); callback(media, ctx); } void ClipDetector::cropImageByProposals(const cv::Mat& image, const std::vector& proposals) { for (const auto& proposal : proposals) { // 根据 proposal 获取裁切的矩形区域 int x = static_cast(proposal.x); int y = static_cast(proposal.y); int w = static_cast(proposal.w); int h = static_cast(proposal.h); // 确保裁切区域在图像范围内 x = std::max(0, std::min(x, image.cols - 1)); y = std::max(0, std::min(y, image.rows - 1)); w = std::max(0, std::min(w, image.cols - x)); h = std::max(0, std::min(h, image.rows - y)); // 裁切图像 cv::Rect roi(x, y, w, h); } } NAMESPACE_CLIP_END NAMESPACE_MAS_END