generated from zhangwei/Train_Identify
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;
|
|||
|
|
}
|