Train_Identify_arm/nvidia_ascend_engine/common_engine/SelectBestEngine/SelectBestChkDateEngine.cpp

441 lines
13 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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