#include "SelectBestChkDateEngine.h" #include "myutils.h" using namespace ai_matrix; SelectBestChkDateEngine::SelectBestChkDateEngine() {} SelectBestChkDateEngine::~SelectBestChkDateEngine() {} APP_ERROR SelectBestChkDateEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; iSelectBestMode_ = MyYaml::GetIns()->GetIntValue("gc_select_best_mode"); //获取几个摄像头识别定检期 std::map mapUseDataSouceCfg = MyYaml::GetIns()->GetUseDataSourceConfig(); for (auto iter = mapUseDataSouceCfg.begin(); iter != mapUseDataSouceCfg.end(); iter++) { if (iter->second.strTarget.find("CHKDATE") != std::string::npos) { LogDebug << "DataSource:" << iter->first << " deal CHKDATE"; mapDataSourceIsEnd_[iter->first] = false; } } InitParam(); LogInfo << "SelectBestChkDateEngine Init ok"; return APP_ERR_OK; } APP_ERROR SelectBestChkDateEngine::DeInit() { LogInfo << "SelectBestChkDateEngine DeInit ok"; return APP_ERR_OK; } /** * 初始化定检期参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void SelectBestChkDateEngine::InitChkDateParam() { mapChkDateInfo_.clear(); strBestChkDateImg_ = ""; i64TimeStampChkDate_ = 0; fMaxScoreSumChkDate_ = 0; memset(&step1LocationBestChkDate_, 0, sizeof(step1LocationBestChkDate_)); iDataSourceChkDate_ = 0; } /** * 初始化参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void SelectBestChkDateEngine::InitParam() { iChkDateIndex_ = 1; InitChkDateParam(); for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++) { iter->second = false; } } /** * 获取最优长度 * inParam : std::vector &vecAllTransInfo 待汇总取优的结果集 * : TargetMaxLen iMaxLen 目标最大长度 * outParam: N/A * return : 最优长度 */ int SelectBestChkDateEngine::GetBestLength(std::vector &vecAllTransInfo, TargetMaxLen iMaxLen) { //1.获取结果中每种长度出现的次数 std::map mapResultSize; for (size_t i = 0; i < vecAllTransInfo.size(); i++) { int iNowSize = vecAllTransInfo[i].vecValue.size(); if (mapResultSize.find(iNowSize) != mapResultSize.end()) { mapResultSize[iNowSize]++; continue; } mapResultSize[iNowSize] = 1; } int iBestLen = 0; //2.获取最优长度 if (iSelectBestMode_ == FREQUENCY) { //2.1 按长度出现的频次最多,作为最优长度 int iCnt = 0; for (auto it = mapResultSize.begin(); it != mapResultSize.end(); it++) { if (iCnt < it->second) { iCnt = it->second; iBestLen = it->first; } } } else if(iSelectBestMode_ == LENGTH) { //2.2 按最长长度且不能大于最大长度,作为最优长度 for (auto rit = mapResultSize.rbegin(); rit != mapResultSize.rend(); rit++) { if (rit->first <= iMaxLen) { iBestLen = rit->first; break; } } } LogDebug << "iBestLen:" << iBestLen; return iBestLen; } /** * 获取最优结果 * inParam : std::vector &vecAllTransInfo 待汇总取优的结果集 * : TargetMaxLen iMaxLen 目标最大长度 * outParam: N/A * return : 最优结果 */ std::string SelectBestChkDateEngine::GetBest(std::vector &vecAllTransInfo, TargetMaxLen iMaxLen) { std::string strValue = ""; if (vecAllTransInfo.size() <= 0) { return strValue; } //优先使用校验通过的数据选优。 std::vector vecTransInfoTemp; for (size_t i = 0; i < vecAllTransInfo.size(); i++) { TransInfo transInfo = vecAllTransInfo[i]; if (transInfo.IsChkFlag) { vecTransInfoTemp.emplace_back(transInfo); } } if (vecTransInfoTemp.size() > 0) { vecAllTransInfo = vecTransInfoTemp; } //获取最优长度 int iBestLen = GetBestLength(vecAllTransInfo, iMaxLen); //初始化最优结果 TransInfo transInfoBest; transInfoBest.vecScore.reserve(iBestLen); transInfoBest.vecValue.reserve(iBestLen); for (int i = 0; i < iBestLen; i++) { transInfoBest.vecScore.emplace_back(0); transInfoBest.vecValue.emplace_back(""); } std::map mapResult; //符合最优长度的结果集 [key:结果; value:结果出现次数] for (size_t iIndex = 0; iIndex < vecAllTransInfo.size(); iIndex++) { if (vecAllTransInfo[iIndex].vecValue.size() != iBestLen) { continue; } std::string strValueTemp; for (int j = 0; j < iBestLen; j++) { strValueTemp += vecAllTransInfo[iIndex].vecValue[j]; if (transInfoBest.vecScore[j] < vecAllTransInfo[iIndex].vecScore[j]) { transInfoBest.vecScore[j] = vecAllTransInfo[iIndex].vecScore[j]; transInfoBest.vecValue[j] = vecAllTransInfo[iIndex].vecValue[j]; } } if (mapResult.find(strValueTemp) != mapResult.end()) { mapResult[strValueTemp]++; } else { mapResult[strValueTemp] = 1; } } //按字符最高得分汇总结果 for (size_t i = 0; i < transInfoBest.vecValue.size(); ++i) { strValue += transInfoBest.vecValue[i]; } //按出现次数汇总结果 int iMaxCnt = 0; std::string strValue2; for (auto iter = mapResult.begin(); iter != mapResult.end(); iter++) { if (iter->second > iMaxCnt) { iMaxCnt = iter->second; strValue2 = iter->first; } } //最高得分汇总和最高次数汇总不相等,且识别同一结果次数大于等于3次,则使用按次数汇总结果。 if (strValue != strValue2) { LogWarn << "engineId:" << engineId_ << " value1:" << strValue << " value2:" << strValue2 << " not equal value2cnt:" << iMaxCnt; if (iMaxCnt >= 3) { strValue = strValue2; } } return strValue; } /** * 校验日期的合理性 * inParam : std::string &strDate 日期 * outParam: N/A * return : true/false */ bool SelectBestChkDateEngine::ChkValidDate(std::string &strDate) { bool bChkFlag = false; //2010年~2040年 if (strDate.length() >= 3) { if (atoi(strDate.substr(0, 2).c_str()) >= 10 && atoi(strDate.substr(0, 2).c_str()) <= 40) { // 1月~12月 if (atoi(strDate.substr(2).c_str()) >= 1 && atoi(strDate.substr(2).c_str()) <= 12) { bChkFlag = true; } } } return bChkFlag; } /** * 获取定检期截至日期 * inParam : std::string &strChkDate 定检期内容 * outParam: N/A * return : 定检期截至日期 */ std::string SelectBestChkDateEngine::GetChkDateDeadLine(std::string &strChkDate) { bool bFlag = false; std::string strDeadLine; if (strChkDate.length() >= 8) { //正常的yymmyymm bFlag = true; strDeadLine = strChkDate.substr(0, 4); } else if (strChkDate.length() == 7 || strChkDate.length() <= 5) { //yymyymm; yymmyym; 8位少识别1位 std::string strTemp1 = strChkDate.substr(0, 4); std::string strTemp2 = strChkDate.substr(0, 3); if (ChkValidDate(strTemp1)) { strDeadLine = strTemp1; bFlag = true; } else if (ChkValidDate(strTemp2)) { strDeadLine = strTemp2; bFlag = true; } else { strDeadLine = strTemp1; } } else if (strChkDate.length() == 6) { //yymyym; 8位少识别2位; 7位少识别1位 std::string strTemp1 = strChkDate.substr(0, 3); std::string strTemp2 = strChkDate.substr(0, 4); if (ChkValidDate(strTemp1)) { strDeadLine = strTemp1; bFlag = true; } else if (ChkValidDate(strTemp2)) { strDeadLine = strTemp2; bFlag = true; } else { strDeadLine = strTemp1; } } else if (strChkDate.length() == 5) { //5位及5位以下按4位,3位截取; 同7位处理 } if (strDeadLine.length() >= 3 && bFlag) { char szDeadLine[16] = {0}; sprintf(szDeadLine, "%d-%02d", atoi(strDeadLine.substr(0, 2).c_str()), atoi(strDeadLine.substr(2).c_str())); return std::string(szDeadLine); } return strDeadLine; } /** * 汇总单节车厢-定检期最佳值 * inParam : N/A * outParam: N/A * return : N/A */ void SelectBestChkDateEngine::GetChkDateBest(std::shared_ptr pChkDate, std::shared_ptr pProcessData) { pChkDate->iDataSource = iDataSourceChkDate_; pChkDate->bIsEnd = pProcessData->bIsEnd; pChkDate->strTrainDate = pProcessData->strTrainDate; pChkDate->strTrainName = pProcessData->strTrainName; pChkDate->iCarXH = pProcessData->iTrainIndex; //定检期1(段修) if(mapChkDateInfo_.find(0) != mapChkDateInfo_.end()) { pChkDate->strChkDate1 = GetBest(mapChkDateInfo_.at(0), CHKDATE_MAXLEN); } //定检期2(厂修) if (mapChkDateInfo_.find(1) != mapChkDateInfo_.end()) { pChkDate->strChkDate2 = GetBest(mapChkDateInfo_.at(1), CHKDATE_MAXLEN); } pChkDate->strBestImg = strBestChkDateImg_; pChkDate->fScoreSum = fMaxScoreSumChkDate_; pChkDate->iCarXH = iChkDateIndex_++; pChkDate->step1Location = step1LocationBestChkDate_; pChkDate->i64TimeStamp = i64TimeStampChkDate_; pChkDate->strChkDate1DeadLine = GetChkDateDeadLine(pChkDate->strChkDate1); //初始化车号信息 InitChkDateParam(); } /** * 定检期数据加入到待选优集合中 * inParam : std::shared_ptr pProcessData :处理帧数据 : TransSubData &transSubData :转换后子数据 * outParam: N/A * return : N/A */ void SelectBestChkDateEngine::ChkDateAddSelectBestMap(std::shared_ptr pProcessData, TransSubData &transSubData) { for (size_t i = 0; i < transSubData.vecTransInfo.size(); i++) { TransInfo transInfo = transSubData.vecTransInfo[i]; mapChkDateInfo_[transInfo.iLine].emplace_back(transInfo); } //最高分和最优帧号 if (fMaxScoreSumChkDate_ < transSubData.fScoreSum) { fMaxScoreSumChkDate_ = transSubData.fScoreSum; strBestChkDateImg_ = std::to_string(pProcessData->iFrameId) + ".jpg"; i64TimeStampChkDate_ = pProcessData->i64TimeStamp; step1LocationBestChkDate_ = transSubData.step1Location; iDataSourceChkDate_ = pProcessData->iDataSource; } } APP_ERROR SelectBestChkDateEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { //pop端口0 std::shared_ptr pVoidData0 = nullptr; iRet = inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr == pVoidData0) { usleep(1000); continue; } std::shared_ptr pProcessData = std::static_pointer_cast(pVoidData0); std::shared_ptr pTransData = std::static_pointer_cast(pProcessData->pVoidData); if (pProcessData->bIsEnd) { mapDataSourceIsEnd_[pProcessData->iDataSource] = pProcessData->bIsEnd; } for (size_t i = 0; i < pTransData->vecTransSubData.size(); i++) { TransSubData transSubData = pTransData->vecTransSubData[i]; //定检期 if (transSubData.iBigClassId == 7) { //定检期加入待汇总集合中 ChkDateAddSelectBestMap(pProcessData, transSubData); } } // 3. 结束帧,需汇总 bool bAllEnd = true; for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++) { bAllEnd = bAllEnd && iter->second; } //3. 结束帧,需汇总 if (bAllEnd) { std::shared_ptr pChkDate = std::make_shared(); GetChkDateBest(pChkDate, pProcessData); //push端口0 outputQueMap_[strPort0_]->push(std::static_pointer_cast(pChkDate)); outputQueMap_[strPort1_]->push(std::static_pointer_cast(pChkDate)); //初始化参数变量 InitParam(); } } return APP_ERR_OK; }