generated from zhangwei/Train_Identify
766 lines
24 KiB
C++
766 lines
24 KiB
C++
|
|
#include "SelectBestEngine.h"
|
|||
|
|
#include "myutils.h"
|
|||
|
|
|
|||
|
|
using namespace ai_matrix;
|
|||
|
|
|
|||
|
|
SelectBestEngine::SelectBestEngine() {}
|
|||
|
|
|
|||
|
|
SelectBestEngine::~SelectBestEngine() {}
|
|||
|
|
|
|||
|
|
APP_ERROR SelectBestEngine::Init()
|
|||
|
|
{
|
|||
|
|
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
|
|||
|
|
strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1";
|
|||
|
|
iSelectBestMode_ = MyYaml::GetIns()->GetIntValue("gc_select_best_mode");
|
|||
|
|
strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path");
|
|||
|
|
strBestPath_ = MyYaml::GetIns()->GetPathValue("gc_best_path");
|
|||
|
|
|
|||
|
|
//获取几个摄像头识别车号
|
|||
|
|
std::map<int, ai_matrix::DataSourceConfig> mapUseDataSouceCfg = MyYaml::GetIns()->GetUseDataSourceConfig();
|
|||
|
|
for (auto iter = mapUseDataSouceCfg.begin(); iter != mapUseDataSouceCfg.end(); iter++)
|
|||
|
|
{
|
|||
|
|
if (iter->second.strTarget.find("NUM") != std::string::npos)
|
|||
|
|
{
|
|||
|
|
mapDataSourceIsEnd_[iter->first] = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
InitParam();
|
|||
|
|
LogInfo << "SelectBestEngine Init ok";
|
|||
|
|
return APP_ERR_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
APP_ERROR SelectBestEngine::DeInit()
|
|||
|
|
{
|
|||
|
|
LogInfo << "SelectBestEngine DeInit ok";
|
|||
|
|
return APP_ERR_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* push数据到队列,队列满时则休眠一段时间再push
|
|||
|
|
* inParam : const std::string strPort push的端口
|
|||
|
|
: const std::shared_ptr<Train> &pTrain push的数据
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::PushData(const std::string &strPort, const std::shared_ptr<Train> &pTrain)
|
|||
|
|
{
|
|||
|
|
while (true)
|
|||
|
|
{
|
|||
|
|
int iRet = outputQueMap_[strPort]->push(std::static_pointer_cast<void>(pTrain));
|
|||
|
|
if (iRet != 0)
|
|||
|
|
{
|
|||
|
|
LogDebug << "num:" << pTrain->trainNum.strTrainNum << " push fail iRet:" << iRet;
|
|||
|
|
if (iRet == 2)
|
|||
|
|
{
|
|||
|
|
usleep(10000); // 10ms
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 初始化车号参数信息
|
|||
|
|
* inParam : N/A
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::InitNumParam()
|
|||
|
|
{
|
|||
|
|
mapTrainTypeId_.clear();
|
|||
|
|
mapNumInfo_.clear();
|
|||
|
|
strBestNumImg_ = "";
|
|||
|
|
i64TimeStampNum_ = 0;
|
|||
|
|
fMaxScoreSumNum_ = 0;
|
|||
|
|
memset(&step1LocationBestNum_, 0, sizeof(step1LocationBestNum_));
|
|||
|
|
iDataSourceNum_ = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 初始化属性参数信息
|
|||
|
|
* inParam : N/A
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::InitProParam()
|
|||
|
|
{
|
|||
|
|
mapProInfo_.clear();
|
|||
|
|
strBestProImg_ = "";
|
|||
|
|
i64TimeStampPro_ = 0;
|
|||
|
|
fMaxScoreSumPro_ = 0;
|
|||
|
|
memset(&step1LocationBestPro_, 0, sizeof(step1LocationBestPro_));
|
|||
|
|
iDataSourcePro_ = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 初始化车号参数信息(只有车结束调用)
|
|||
|
|
* inParam : N/A
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::InitHeadParam()
|
|||
|
|
{
|
|||
|
|
mapHeadInfo_.clear();
|
|||
|
|
strBestHeadImg_ = "";
|
|||
|
|
i64TimeStampHead_ = 0;
|
|||
|
|
fMaxScoreSumHead_ = 0;
|
|||
|
|
memset(&step1LocationBestHead_, 0, sizeof(step1LocationBestHead_));
|
|||
|
|
iDataSourceHead_ = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 初始化参数信息
|
|||
|
|
* inParam : N/A
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::InitParam()
|
|||
|
|
{
|
|||
|
|
iNumIndex_ = 1;
|
|||
|
|
iProIndex_ = 1;
|
|||
|
|
InitNumParam();
|
|||
|
|
InitProParam();
|
|||
|
|
InitHeadParam();
|
|||
|
|
|
|||
|
|
for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++)
|
|||
|
|
{
|
|||
|
|
iter->second = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取最优长度
|
|||
|
|
* inParam : std::vector<TransInfo> &vecAllTransInfo 待汇总取优的结果集
|
|||
|
|
* : TargetMaxLen iMaxLen 目标最大长度
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : 最优长度
|
|||
|
|
*/
|
|||
|
|
int SelectBestEngine::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 && it->first <= iMaxLen)
|
|||
|
|
{
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return iBestLen;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取最优结果
|
|||
|
|
* inParam : std::vector<TransInfo> &vecAllTransInfo 待汇总取优的结果集
|
|||
|
|
* : TargetMaxLen iMaxLen 目标最大长度
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : 最优结果
|
|||
|
|
*/
|
|||
|
|
std::string SelectBestEngine::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;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// 此处因车厢太脏。识别效果很差,难以与RFID识别结果融合,所以增加eles
|
|||
|
|
return strValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//获取最优长度
|
|||
|
|
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::shared_ptr<ProcessData> pProcessData :处理帧数据
|
|||
|
|
: TransSubData &transSubData :转换后子数据
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::NumAddSelectBestMap(std::shared_ptr<ProcessData> pProcessData, TransSubData &transSubData)
|
|||
|
|
{
|
|||
|
|
for (size_t i = 0; i < transSubData.vecTransInfo.size(); i++)
|
|||
|
|
{
|
|||
|
|
TransInfo transInfo = transSubData.vecTransInfo[i];
|
|||
|
|
mapNumInfo_[transInfo.iLine].emplace_back(transInfo);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//记录车厢类型ID
|
|||
|
|
if (mapTrainTypeId_.find(transSubData.iBigClassId) != mapTrainTypeId_.end())
|
|||
|
|
{
|
|||
|
|
mapTrainTypeId_[transSubData.iBigClassId]++;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
mapTrainTypeId_[transSubData.iBigClassId] = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//最高分和最优帧号
|
|||
|
|
if (fMaxScoreSumNum_ < transSubData.fScoreSum)
|
|||
|
|
{
|
|||
|
|
fMaxScoreSumNum_ = transSubData.fScoreSum;
|
|||
|
|
strBestNumImg_ = std::to_string(pProcessData->iFrameId) + ".jpg";
|
|||
|
|
i64TimeStampNum_ = pProcessData->i64TimeStamp;
|
|||
|
|
step1LocationBestNum_ = transSubData.step1Location;
|
|||
|
|
iDataSourceNum_ = pProcessData->iDataSource;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 属性数据加入到待选优集合中
|
|||
|
|
* inParam : std::shared_ptr<ProcessData> pProcessData :处理帧数据
|
|||
|
|
: TransSubData &transSubData :转换后子数据
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::ProAddSelectBestMap(std::shared_ptr<ProcessData> pProcessData, TransSubData &transSubData)
|
|||
|
|
{
|
|||
|
|
for (size_t i = 0; i < transSubData.vecTransInfo.size(); i++)
|
|||
|
|
{
|
|||
|
|
TransInfo transInfo = transSubData.vecTransInfo[i];
|
|||
|
|
mapProInfo_[transInfo.iLine].emplace_back(transInfo);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//最高分和最优帧号
|
|||
|
|
if (fMaxScoreSumPro_ < transSubData.fScoreSum)
|
|||
|
|
{
|
|||
|
|
fMaxScoreSumPro_ = transSubData.fScoreSum;
|
|||
|
|
strBestProImg_ = std::to_string(pProcessData->iFrameId) + ".jpg";
|
|||
|
|
i64TimeStampPro_ = pProcessData->i64TimeStamp;
|
|||
|
|
step1LocationBestPro_ = transSubData.step1Location;
|
|||
|
|
iDataSourcePro_ = pProcessData->iDataSource;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 车头数据加入到待选优集合中
|
|||
|
|
* inParam : std::shared_ptr<ProcessData> pProcessData :处理帧数据
|
|||
|
|
: TransSubData &transSubData :转换后子数据
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::HeadAddSelectBestMap(std::shared_ptr<ProcessData> pProcessData, TransSubData &transSubData)
|
|||
|
|
{
|
|||
|
|
for (size_t i = 0; i < transSubData.vecTransInfo.size(); i++)
|
|||
|
|
{
|
|||
|
|
TransInfo transInfo = transSubData.vecTransInfo[i];
|
|||
|
|
mapHeadInfo_[transInfo.iLine].emplace_back(transInfo);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//记录车头大框识别次数
|
|||
|
|
auto iter = mapTrainTypeId_.find(0);
|
|||
|
|
if (iter == mapTrainTypeId_.end())
|
|||
|
|
{
|
|||
|
|
mapTrainTypeId_.insert(std::make_pair(0, 1));
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
iter->second++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//最高分和最优帧号
|
|||
|
|
if (fMaxScoreSumHead_ < transSubData.fScoreSum)
|
|||
|
|
{
|
|||
|
|
fMaxScoreSumHead_ = transSubData.fScoreSum;
|
|||
|
|
strBestHeadImg_ = std::to_string(pProcessData->iFrameId) + ".jpg";
|
|||
|
|
i64TimeStampHead_ = pProcessData->i64TimeStamp;
|
|||
|
|
step1LocationBestHead_ = transSubData.step1Location;
|
|||
|
|
iDataSourceHead_ = pProcessData->iDataSource;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 汇总车头最佳值
|
|||
|
|
* inParam : N/A
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
bool SelectBestEngine::GetHeadBest(std::shared_ptr<ProcessData> pProcessData)
|
|||
|
|
{
|
|||
|
|
//2.无识别车头信息,不汇总
|
|||
|
|
if (mapHeadInfo_.empty())
|
|||
|
|
{
|
|||
|
|
LogDebug << "engineId:" << engineId_ << " no head info";
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::shared_ptr<Train> pTrain = std::make_shared<Train>();
|
|||
|
|
pTrain->trainNum.iDataSource = iDataSourceHead_;
|
|||
|
|
pTrain->trainNum.bIsEnd = pProcessData->bIsEnd;
|
|||
|
|
pTrain->trainNum.strTrainDate = pProcessData->strTrainDate;
|
|||
|
|
pTrain->trainNum.strTrainName = pProcessData->strTrainName;
|
|||
|
|
pTrain->trainNum.iDirection = pProcessData->iDirection;
|
|||
|
|
|
|||
|
|
//车头型号
|
|||
|
|
if (mapHeadInfo_.find(0) != mapHeadInfo_.end())
|
|||
|
|
{
|
|||
|
|
pTrain->trainNum.strTrainType = GetBest(mapHeadInfo_.at(0), TYPE_MAXLEN);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//车头编号
|
|||
|
|
if (mapHeadInfo_.find(1) != mapHeadInfo_.end())
|
|||
|
|
{
|
|||
|
|
pTrain->trainNum.strTrainNum = GetBest(mapHeadInfo_.at(1), NUM_MAXLEN);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pTrain->trainNum.strBestImg = strBestHeadImg_;
|
|||
|
|
pTrain->trainNum.iCarXH = 0;
|
|||
|
|
pTrain->trainNum.step1Location = step1LocationBestHead_;
|
|||
|
|
pTrain->trainNum.i64TimeStamp = i64TimeStampHead_;
|
|||
|
|
pTrain->trainNum.iTrainTypeId = 0; //车头
|
|||
|
|
|
|||
|
|
|
|||
|
|
//push端口1,车头属性
|
|||
|
|
pTrain->trainPro.iDataSource = iDataSourceHead_;
|
|||
|
|
pTrain->trainPro.bIsEnd = pProcessData->bIsEnd;
|
|||
|
|
pTrain->trainPro.strTrainDate = pProcessData->strTrainDate;
|
|||
|
|
pTrain->trainPro.strTrainName = pProcessData->strTrainName;
|
|||
|
|
pTrain->trainPro.iDirection = pProcessData->iDirection;
|
|||
|
|
pTrain->trainPro.iCarXH = 0;
|
|||
|
|
|
|||
|
|
pTrain->strTrainDate = pTrain->trainNum.strTrainDate;
|
|||
|
|
pTrain->strTrainName = pTrain->trainNum.strTrainName;
|
|||
|
|
pTrain->iDirection = pTrain->trainNum.iDirection;
|
|||
|
|
pTrain->iDataSource = pTrain->trainNum.iDataSource >= pTrain->trainPro.iDataSource ? pTrain->trainNum.iDataSource : pTrain->trainPro.iDataSource;
|
|||
|
|
|
|||
|
|
LogInfo << "\n ---汇总结果--- \n"
|
|||
|
|
<< "日期时间: " << pTrain->strTrainDate << " " << pTrain->strTrainName << "\n"
|
|||
|
|
<< "车厢序号: " << pTrain->iCarXH << "\n"
|
|||
|
|
<< "车型Id: " << pTrain->trainNum.iTrainTypeId << "\n"
|
|||
|
|
<< "车型: " << pTrain->trainNum.strTrainType << "\n"
|
|||
|
|
<< "车号: " << pTrain->trainNum.strTrainNum << "\n"
|
|||
|
|
<< "载重: " << pTrain->trainPro.strLoad << "\n"
|
|||
|
|
<< "自重: " << pTrain->trainPro.strSelf << "\n"
|
|||
|
|
<< "容积: " << pTrain->trainPro.strVolume << "\n"
|
|||
|
|
<< "换长: " << pTrain->trainPro.strChange << "\n"
|
|||
|
|
<< "容量记表: " << pTrain->trainPro.strVolumeSurface << "\n"
|
|||
|
|
<< "编号图片: " << pTrain->trainNum.strBestImg << "\n"
|
|||
|
|
<< "属性图片: " << pTrain->trainPro.strBestImg << "\n"
|
|||
|
|
<< "行驶方向: " << pTrain->iDirection << "\n"
|
|||
|
|
<< " ---汇总结果 END--- ";
|
|||
|
|
|
|||
|
|
//拷贝最优图片到最优路径下
|
|||
|
|
CopyBestImgToBestPath(pTrain);
|
|||
|
|
|
|||
|
|
std::shared_ptr<Train> pTrainToCsv = std::make_shared<Train>();
|
|||
|
|
*pTrainToCsv = *pTrain;
|
|||
|
|
PushData(strPort0_, pTrain);
|
|||
|
|
PushData(strPort1_, pTrainToCsv);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 汇总车号最佳值
|
|||
|
|
* inParam : std::shared_ptr<ProcessData> pProcessData
|
|||
|
|
* outParam: TrainNum &trainNum
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::GetNumBest(TrainNum &trainNum, std::shared_ptr<ProcessData> pProcessData)
|
|||
|
|
{
|
|||
|
|
trainNum.iDataSource = iDataSourceNum_;
|
|||
|
|
trainNum.bIsEnd = pProcessData->bIsEnd;
|
|||
|
|
trainNum.strTrainDate = pProcessData->strTrainDate;
|
|||
|
|
trainNum.strTrainName = pProcessData->strTrainName;
|
|||
|
|
trainNum.iDirection = pProcessData->iDirection;
|
|||
|
|
trainNum.iCarXH = pProcessData->iTrainIndex;
|
|||
|
|
|
|||
|
|
//车型
|
|||
|
|
if (mapNumInfo_.find(0) != mapNumInfo_.end())
|
|||
|
|
{
|
|||
|
|
trainNum.strTrainType = GetBest(mapNumInfo_.at(0), TYPE_MAXLEN);
|
|||
|
|
}
|
|||
|
|
//编号
|
|||
|
|
if (mapNumInfo_.find(1) != mapNumInfo_.end())
|
|||
|
|
{
|
|||
|
|
trainNum.strTrainNum = GetBest(mapNumInfo_.at(1), NUM_MAXLEN);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//按出现次数选车厢类型ID
|
|||
|
|
int iMaxCnt = 0;
|
|||
|
|
for (auto iter = mapTrainTypeId_.begin(); iter != mapTrainTypeId_.end(); iter++)
|
|||
|
|
{
|
|||
|
|
if (iter->second > iMaxCnt)
|
|||
|
|
{
|
|||
|
|
iMaxCnt = iter->second;
|
|||
|
|
trainNum.iTrainTypeId = iter->first;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
trainNum.strBestImg = strBestNumImg_;
|
|||
|
|
trainNum.fScoreSum = fMaxScoreSumNum_;
|
|||
|
|
trainNum.iCarXH = iNumIndex_++;
|
|||
|
|
trainNum.step1Location = step1LocationBestNum_;
|
|||
|
|
trainNum.i64TimeStamp = i64TimeStampNum_;
|
|||
|
|
//初始化车号信息
|
|||
|
|
InitNumParam();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 汇总属性最佳值
|
|||
|
|
* inParam : std::shared_ptr<ProcessData> pProcessData
|
|||
|
|
* outParam: TrainPro &trainPro
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::GetProBest(TrainPro &trainPro, std::shared_ptr<ProcessData> pProcessData)
|
|||
|
|
{
|
|||
|
|
trainPro.iDataSource = iDataSourcePro_;
|
|||
|
|
trainPro.bIsEnd = pProcessData->bIsEnd;
|
|||
|
|
trainPro.strTrainDate = pProcessData->strTrainDate;
|
|||
|
|
trainPro.strTrainName = pProcessData->strTrainName;
|
|||
|
|
trainPro.iDirection = pProcessData->iDirection;
|
|||
|
|
trainPro.iCarXH = pProcessData->iTrainIndex;
|
|||
|
|
|
|||
|
|
//载重
|
|||
|
|
if (mapProInfo_.find(0) != mapProInfo_.end())
|
|||
|
|
{
|
|||
|
|
trainPro.strLoad = GetBest(mapProInfo_.at(0), LOAD_MAXLEN);
|
|||
|
|
}
|
|||
|
|
//自重
|
|||
|
|
if (mapProInfo_.find(1) != mapProInfo_.end())
|
|||
|
|
{
|
|||
|
|
trainPro.strSelf = GetBest(mapProInfo_.at(1), SELF_MAXLEN);
|
|||
|
|
if (trainPro.strSelf.length() == 3)
|
|||
|
|
{
|
|||
|
|
trainPro.strSelf = trainPro.strSelf.substr(0, 2) + "." + trainPro.strSelf.substr(2, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//容积
|
|||
|
|
if (mapProInfo_.find(2) != mapProInfo_.end())
|
|||
|
|
{
|
|||
|
|
trainPro.strVolume = GetBest(mapProInfo_.at(2), VOLUME_MAXLEN);
|
|||
|
|
//棚车容器一般为1开头得三位整数,因此不需要额外补小数点处理。
|
|||
|
|
if (trainPro.strVolume.length() == 3 && trainPro.strVolume.substr(0, 1) != "1")
|
|||
|
|
{
|
|||
|
|
trainPro.strVolume = trainPro.strVolume.substr(0, 2) + "." + trainPro.strVolume.substr(2, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//换长
|
|||
|
|
if (mapProInfo_.find(3) != mapProInfo_.end())
|
|||
|
|
{
|
|||
|
|
trainPro.strChange = GetBest(mapProInfo_.at(3), CHANGE_MAXLEN);
|
|||
|
|
if (trainPro.strChange.length() == 1)
|
|||
|
|
{
|
|||
|
|
if (trainPro.strChange.at(0) != '1')
|
|||
|
|
{
|
|||
|
|
trainPro.strChange = "1." + trainPro.strChange;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (trainPro.strChange.length() == 2)
|
|||
|
|
{
|
|||
|
|
trainPro.strChange = trainPro.strChange.substr(0, 1) + "." + trainPro.strChange.substr(1, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//罐车容量记表
|
|||
|
|
if (mapProInfo_.find(4) != mapProInfo_.end())
|
|||
|
|
{
|
|||
|
|
trainPro.strVolumeSurface = GetBest(mapProInfo_.at(4), VOLUMESURFACE_MAXLEN);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
trainPro.strBestImg = strBestProImg_;
|
|||
|
|
trainPro.fScoreSum = fMaxScoreSumPro_;
|
|||
|
|
trainPro.iCarXH = iProIndex_++;
|
|||
|
|
trainPro.step1Location = step1LocationBestPro_;
|
|||
|
|
trainPro.i64TimeStamp = i64TimeStampPro_;
|
|||
|
|
//初始化属性信息
|
|||
|
|
InitProParam();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 拷贝最优图片到最优路径下
|
|||
|
|
* inParam : N/A
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::CopyBestImgToBestPath(const std::shared_ptr<Train> &pTrain)
|
|||
|
|
{
|
|||
|
|
//拷贝最优图片到最优路径下
|
|||
|
|
if (!pTrain->trainNum.strBestImg.empty())
|
|||
|
|
{
|
|||
|
|
char szCameraNo[6] = {0}; //车号最优图片路径
|
|||
|
|
sprintf(szCameraNo, "/%03d/", pTrain->trainNum.iDataSource + 1);
|
|||
|
|
std::string strDes = strBestPath_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szCameraNo;
|
|||
|
|
if (!MyUtils::getins()->CreateDirPath(strDes))
|
|||
|
|
{
|
|||
|
|
LogError << "engineId:" << engineId_ << " CreateDirPath err strDes:" << strDes;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::string strSrc = strResultPath_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szCameraNo + pTrain->trainNum.strBestImg;
|
|||
|
|
strDes += pTrain->trainNum.strBestImg;
|
|||
|
|
MyUtils::getins()->copyFile(strSrc, strDes);
|
|||
|
|
}
|
|||
|
|
if (!pTrain->trainPro.strBestImg.empty())
|
|||
|
|
{
|
|||
|
|
char szCameraNo[6] = {0}; //车号最优图片路径
|
|||
|
|
sprintf(szCameraNo, "/%03d/", pTrain->trainPro.iDataSource + 1);
|
|||
|
|
std::string strDes = strBestPath_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szCameraNo;
|
|||
|
|
if (!MyUtils::getins()->CreateDirPath(strDes))
|
|||
|
|
{
|
|||
|
|
LogError << "engineId:" << engineId_ << " CreateDirPath err strDes:" << strDes;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
std::string strSrc = strResultPath_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szCameraNo + pTrain->trainPro.strBestImg;
|
|||
|
|
strDes += pTrain->trainPro.strBestImg;
|
|||
|
|
MyUtils::getins()->copyFile(strSrc, strDes);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 汇总车厢最佳值
|
|||
|
|
* inParam : N/A
|
|||
|
|
* outParam: N/A
|
|||
|
|
* return : N/A
|
|||
|
|
*/
|
|||
|
|
void SelectBestEngine::GetTrainBest(std::shared_ptr<ProcessData> pProcessData)
|
|||
|
|
{
|
|||
|
|
std::shared_ptr<Train> pTrain = std::make_shared<Train>();
|
|||
|
|
//1.汇总车号信息
|
|||
|
|
GetNumBest(pTrain->trainNum, pProcessData);
|
|||
|
|
|
|||
|
|
//2.汇总属性信息
|
|||
|
|
GetProBest(pTrain->trainPro, pProcessData);
|
|||
|
|
|
|||
|
|
/*按车型删除误识别的属性
|
|||
|
|
1.非罐车删除容量计表
|
|||
|
|
2.平车删除容积
|
|||
|
|
*/
|
|||
|
|
if (pTrain->trainNum.iTrainTypeId != 5 && pTrain->trainNum.iTrainTypeId != -1)
|
|||
|
|
{
|
|||
|
|
pTrain->trainPro.strVolumeSurface = "";
|
|||
|
|
}
|
|||
|
|
if (pTrain->trainNum.iTrainTypeId == 6)
|
|||
|
|
{
|
|||
|
|
pTrain->trainPro.strVolume = "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pTrain->strTrainDate = pTrain->trainNum.strTrainDate;
|
|||
|
|
pTrain->strTrainName = pTrain->trainNum.strTrainName;
|
|||
|
|
pTrain->iDirection = pTrain->trainNum.iDirection;
|
|||
|
|
pTrain->iCarXH = pTrain->trainNum.iCarXH;
|
|||
|
|
pTrain->iDataSource = pTrain->trainNum.iDataSource >= pTrain->trainPro.iDataSource ? pTrain->trainNum.iDataSource : pTrain->trainPro.iDataSource;
|
|||
|
|
|
|||
|
|
LogInfo << "\n ---汇总结果--- \n"
|
|||
|
|
<< "日期时间: " << pTrain->strTrainDate << " " << pTrain->strTrainName << "\n"
|
|||
|
|
<< "车厢序号: " << pTrain->iCarXH << "\n"
|
|||
|
|
<< "车型Id: " << pTrain->trainNum.iTrainTypeId << "\n"
|
|||
|
|
<< "车型: " << pTrain->trainNum.strTrainType << "\n"
|
|||
|
|
<< "车号: " << pTrain->trainNum.strTrainNum << "\n"
|
|||
|
|
<< "载重: " << pTrain->trainPro.strLoad << "\n"
|
|||
|
|
<< "自重: " << pTrain->trainPro.strSelf << "\n"
|
|||
|
|
<< "容积: " << pTrain->trainPro.strVolume << "\n"
|
|||
|
|
<< "换长: " << pTrain->trainPro.strChange << "\n"
|
|||
|
|
<< "容量记表: " << pTrain->trainPro.strVolumeSurface << "\n"
|
|||
|
|
<< "编号图片: " << pTrain->trainNum.strBestImg << "\n"
|
|||
|
|
<< "属性图片: " << pTrain->trainPro.strBestImg << "\n"
|
|||
|
|
<< "行驶方向: " << pTrain->iDirection << "\n"
|
|||
|
|
<< " ---汇总结果 END--- ";
|
|||
|
|
|
|||
|
|
//拷贝最优图片到最优路径下
|
|||
|
|
CopyBestImgToBestPath(pTrain);
|
|||
|
|
|
|||
|
|
std::shared_ptr<Train> pTrainToCsv = std::make_shared<Train>();
|
|||
|
|
*pTrainToCsv = *pTrain;
|
|||
|
|
PushData(strPort0_, pTrain);
|
|||
|
|
PushData(strPort1_, pTrainToCsv);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
APP_ERROR SelectBestEngine::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 == 0)
|
|||
|
|
{
|
|||
|
|
//车头加入待汇总集合中
|
|||
|
|
HeadAddSelectBestMap(pProcessData, transSubData);
|
|||
|
|
}
|
|||
|
|
//属性
|
|||
|
|
else if (transSubData.iBigClassId == 1)
|
|||
|
|
{
|
|||
|
|
//属性加入待汇总集合中
|
|||
|
|
ProAddSelectBestMap(pProcessData, transSubData);
|
|||
|
|
}
|
|||
|
|
//车号
|
|||
|
|
else if (transSubData.iBigClassId >= 2 && transSubData.iBigClassId <= 6)
|
|||
|
|
{
|
|||
|
|
//车号加入待汇总集合中
|
|||
|
|
NumAddSelectBestMap(pProcessData, transSubData);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//3. 结束帧,需汇总
|
|||
|
|
bool bAllEnd = true;
|
|||
|
|
for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++)
|
|||
|
|
{
|
|||
|
|
bAllEnd = bAllEnd && iter->second;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (bAllEnd)
|
|||
|
|
{
|
|||
|
|
bool bHeadFlag = false;
|
|||
|
|
//第一节或最后一节汇总车头
|
|||
|
|
//(注:针对2个车头的场景,除判断第一节和最后一节外,额外增加车头的次数,当车头大框次数大于3次时,则认为车头。因此后续第一个节和最后一节的条件可以删除)
|
|||
|
|
if (pProcessData->iTrainIndex == 1 || pProcessData->bIsTrainEnd ||
|
|||
|
|
(mapTrainTypeId_.find(0) != mapTrainTypeId_.end() && (mapTrainTypeId_[0] >= 2 || mapTrainTypeId_.size() == 1)))
|
|||
|
|
{
|
|||
|
|
bHeadFlag = GetHeadBest(pProcessData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//汇总车厢 车号和属性
|
|||
|
|
if (!bHeadFlag)
|
|||
|
|
{
|
|||
|
|
GetTrainBest(pProcessData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//初始化参数变量
|
|||
|
|
InitParam();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return APP_ERR_OK;
|
|||
|
|
}
|