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;
|
||
}
|