Train_Identify_arm/nvidia_ascend_engine/common_engine/SelectBestEngine/SelectBestEngine.cpp

1 line
25 KiB
C++
Raw 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 "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)
{
LogInfo << "<<< --- 没数据 --- >>>";
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 {
// LogInfo << "--->>> 没有符合正则的??";
// 此处因车厢太脏。识别效果很差难以与RFID识别结果融合所以增加eles
return strValue;
}
//获取最优长度
int iBestLen = GetBestLength(vecAllTransInfo, iMaxLen);
// LogInfo << "--->>> 最优长度:" << iBestLen;
//初始化最优结果
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];
// LogInfo << "待选优 >>> " << transInfo.vecValue[0];
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);
// LogInfo << "-->>> " << trainNum.strTrainType;
}
//编号
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;
}