441 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			441 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | #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<int, ai_matrix::DataSourceConfig> 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<TransInfo> &vecAllTransInfo 待汇总取优的结果集 | |||
|  | *         : TargetMaxLen iMaxLen                    目标最大长度   | |||
|  | * outParam: N/A | |||
|  | * return  : 最优长度 | |||
|  | */ | |||
|  | int SelectBestChkDateEngine::GetBestLength(std::vector<TransInfo> &vecAllTransInfo, TargetMaxLen iMaxLen) | |||
|  | { | |||
|  |     //1.获取结果中每种长度出现的次数
 | |||
|  |     std::map<int, int> 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<TransInfo> &vecAllTransInfo 待汇总取优的结果集 | |||
|  | *         : TargetMaxLen iMaxLen                    目标最大长度  | |||
|  | * outParam: N/A | |||
|  | * return  : 最优结果 | |||
|  | */ | |||
|  | std::string SelectBestChkDateEngine::GetBest(std::vector<TransInfo> &vecAllTransInfo, TargetMaxLen iMaxLen) | |||
|  | { | |||
|  |     std::string strValue = ""; | |||
|  |     if (vecAllTransInfo.size() <= 0) | |||
|  |     { | |||
|  |         return strValue; | |||
|  |     } | |||
|  | 
 | |||
|  |     //优先使用校验通过的数据选优。
 | |||
|  |     std::vector<TransInfo> 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<std::string, int> 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<ChkDate> pChkDate, std::shared_ptr<ProcessData> 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<ProcessData> pProcessData           :处理帧数据 | |||
|  |           : TransSubData &transSubData                          :转换后子数据 | |||
|  | * outParam: N/A | |||
|  | * return  : N/A | |||
|  | */ | |||
|  | void SelectBestChkDateEngine::ChkDateAddSelectBestMap(std::shared_ptr<ProcessData> 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<void> pVoidData0 = nullptr; | |||
|  |         iRet = inputQueMap_[strPort0_]->pop(pVoidData0); | |||
|  |         if (nullptr == pVoidData0) | |||
|  |         { | |||
|  |             usleep(1000); | |||
|  |             continue; | |||
|  |         } | |||
|  |         std::shared_ptr<ProcessData> pProcessData = std::static_pointer_cast<ProcessData>(pVoidData0); | |||
|  |         std::shared_ptr<TransData> pTransData = std::static_pointer_cast<TransData>(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<ChkDate> pChkDate = std::make_shared<ChkDate>(); | |||
|  |             GetChkDateBest(pChkDate, pProcessData); | |||
|  | 
 | |||
|  |             //push端口0
 | |||
|  |             outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pChkDate)); | |||
|  |             outputQueMap_[strPort1_]->push(std::static_pointer_cast<void>(pChkDate)); | |||
|  | 
 | |||
|  |             //初始化参数变量
 | |||
|  |             InitParam(); | |||
|  |         } | |||
|  |     } | |||
|  |     return APP_ERR_OK; | |||
|  | } |