Train_Identify/nvidia_ascend_engine/common_engine/SelectBestEngine/SelectBestContainerEngine_N...

605 lines
23 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 "SelectBestContainerEngine_NEW.h"
#include "myutils.h"
#define CONTAINER_LEN 11
using namespace ai_matrix;
SelectBestContainerEngine_NEW::SelectBestContainerEngine_NEW() {}
SelectBestContainerEngine_NEW::~SelectBestContainerEngine_NEW() {}
APP_ERROR SelectBestContainerEngine_NEW::Init()
{
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1";
//获取几个摄像头识别集装箱
std::map<int, ai_matrix::DataSourceConfig> mapUseDataSouceCfg = MyYaml::GetIns()->GetUseDataSourceConfig();
for (auto iter = mapUseDataSouceCfg.begin(); iter != mapUseDataSouceCfg.end(); iter++)
{
if (iter->second.strTarget.find("CONTAINER") != std::string::npos)
{
LogDebug << "DataSource:" << iter->first << " deal CONTAINER";
mapDataSourceIsEnd_[iter->first] = false;
if (iter->second.strTarget.find("CONTAINER_T") != std::string::npos)
{
setTopContainerSid_.insert(iter->first);
}
}
}
InitParam();
LogInfo << "SelectBestContainerEngine_NEW Init ok";
return APP_ERR_OK;
}
APP_ERROR SelectBestContainerEngine_NEW::DeInit()
{
LogInfo << "SelectBestContainerEngine_NEW DeInit ok";
return APP_ERR_OK;
}
/**
* 初始化参数信息
* inParam : N/A
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine_NEW::InitParam()
{
for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++)
{
iter->second = false;
}
mapSidContainers0_.clear();
mapSidConBest0_.clear();
mapStep1Pre0_.clear();
mapSecondFlag0_.clear();
mapSidContainers1_.clear();
mapSidConBest1_.clear();
mapStep1Pre1_.clear();
mapSecondFlag1_.clear();
}
/**
* 验证集装箱号是否满足规则(前10位依次与2^0 ~2^9相乘/11 所得余数,即是校验位)
* inParam : std::string &strContainerNo 集装箱号信息
* outParam: N/A
* return : true(校验通过)/false(校验失败)
*/
bool SelectBestContainerEngine_NEW::VerifyContainerNo(std::string &strContainerNo)
{
bool bChkFlag = false;
if(strContainerNo.length() != CONTAINER_LEN)
{
return bChkFlag;
}
int iSum = 0;
for (int i = 0; i < strContainerNo.length()-1; ++i)
{
iSum += mapExchange_[strContainerNo.substr(i, 1)] * int(pow(2.0, i));
}
//当校验位等于10时要继续模运算,iSum % 11 % 10,保证最终结果为0~9之间的数
int iChkValue = iSum % 11 % 10;
if (iChkValue == atoi(strContainerNo.substr(strContainerNo.length()-1, 1).c_str()))
{
bChkFlag = true;
}
return bChkFlag;
}
/**
* 构造最优集装箱信息
* inParam : N/A
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine_NEW::MakeBestContainer(Container &containerBest,
TransSubData *pTransSubData,
std::shared_ptr<ProcessData> pProcessData)
{
containerBest.iDataSource = pProcessData->iDataSource;
containerBest.i64TimeStamp = pProcessData->i64TimeStamp;
containerBest.bIsEnd = pProcessData->bIsEnd;
containerBest.strTrainDate = pProcessData->strTrainDate;
containerBest.strTrainName = pProcessData->strTrainName;
containerBest.step1Location = pTransSubData->step1Location;
containerBest.strBestImg = std::to_string(pProcessData->iFrameId) + ".jpg";
containerBest.fScoreSum = pTransSubData->fScoreSum;
containerBest.strContainerNo = pTransSubData->strAllValue;
}
/**
* 识别成功和失败中选取最优结果
* inParam : std::shared_ptr<TrainContainer> pTrainContainer 选优结果
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine_NEW::DealContainer(std::shared_ptr<ProcessData> pProcessData, TransSubData &transSubData,
std::map<int, std::map<int, std::vector<Container>>> &mapSidContainers,
std::map<int, Step1Location> &mapStep1Pre, std::map<int, bool> &mapSecondFlag)
{
/*
mapStep1Pre先保存第1个箱号上一帧识别结果的大框信息。当识别大框信息和保存上一个识别信息间隔大于画面一半时
则说明识别到了第2个箱号此时mapStep1Pre保存第2个箱号的上一帧的大框信息。
mapStep1Pre保存的第1个箱号时
和前帧识别大框间隔小于画面一半时则属于第1个箱号否则属于第2个箱号
mapStep1Pre保存的第2个箱号时
和前帧识别大框间隔小于画面一半时则属于第2个箱号否则属于第1个箱号
*/
if (mapStep1Pre.find(pProcessData->iDataSource) == mapStep1Pre.end())
{
mapStep1Pre[pProcessData->iDataSource] = transSubData.step1Location;
}
if (mapSecondFlag.find(pProcessData->iDataSource) == mapSecondFlag.end())
{
mapSecondFlag[pProcessData->iDataSource] = false;
}
int iCompareValue = 0;
int iPreCenter = 0;
int iCurCenter = 0;
if (setTopContainerSid_.count(pProcessData->iDataSource) != 0)
{
//顶部集装箱使用Y坐标比较
iCompareValue = pProcessData->iHeight / 3;
iPreCenter = mapStep1Pre[pProcessData->iDataSource].fLTY;
iCurCenter = transSubData.step1Location.fLTY;
}
else
{
//侧部集装箱使用X坐标比较
iCompareValue = pProcessData->iWidth / 3;
iPreCenter = mapStep1Pre[pProcessData->iDataSource].fLTX;
iCurCenter = transSubData.step1Location.fLTX;
}
int iIndex = 0;
if (!mapSecondFlag[pProcessData->iDataSource])
{
iIndex = 1;
if (abs(iPreCenter - iCurCenter) > iCompareValue)
{
iIndex = 2;
mapSecondFlag[pProcessData->iDataSource] = true;
}
mapStep1Pre[pProcessData->iDataSource] = transSubData.step1Location;
}
else
{
if (abs(iPreCenter - iCurCenter) > iCompareValue)
{
iIndex = 1;
}
else
{
iIndex = 2;
mapStep1Pre[pProcessData->iDataSource] = transSubData.step1Location;
}
}
//集装箱校验
bool bChkFlag = true;
for (auto iter = transSubData.vecTransInfo.begin(); iter != transSubData.vecTransInfo.end(); ++iter)
{
bChkFlag &= iter->IsChkFlag;
}
if (bChkFlag)
{
bChkFlag = VerifyContainerNo(transSubData.strAllValue);
}
LogDebug << "datasource:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId
<< " iIndex:" << iIndex << " containerNo:" << transSubData.strAllValue << " chkflag:" << bChkFlag;
Container containerBest;
MakeBestContainer(containerBest, &transSubData, pProcessData);
containerBest.bChkFlag = bChkFlag;
mapSidContainers[pProcessData->iDataSource][iIndex].push_back(containerBest);
}
/**
* 识别成功和失败中选取最优结果
* inParam : std::shared_ptr<TrainContainer> pTrainContainer 选优结果
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine_NEW::GetBestContainerBySid(std::map<int, std::map<int, std::vector<Container>>> &mapSidContainers,
std::map<int, std::vector<Container>> &mapSidConBest)
{
for (auto iter = mapSidContainers.begin(); iter != mapSidContainers.end(); iter++)
{
for (auto iterSub = iter->second.begin(); iterSub != iter->second.end(); iterSub++)
{
std::map<std::string, int> mapConCnt;
Container containerSucc;
Container containerFail;
bool bNoSameFlag = false;
for (int i = 0; i < iterSub->second.size(); i++)
{
if (!iterSub->second[i].bChkFlag)
{
// 校验失败的数据,找一个最长的识别即可
if (containerFail.strContainerNo.length() < iterSub->second[i].strContainerNo.length())
{
containerFail = iterSub->second[i];
}
continue;
}
//统计识别校验通过箱号的频次
if (mapConCnt.find(iterSub->second[i].strContainerNo) != mapConCnt.end())
{
mapConCnt[iterSub->second[i].strContainerNo]++;
}
else
{
mapConCnt[iterSub->second[i].strContainerNo] = 1;
}
if (containerSucc.strContainerNo.empty())
{
containerSucc = iterSub->second[i];
continue;
}
if (containerSucc.strContainerNo == iterSub->second[i].strContainerNo)
{
// 校验通过且相同的,选取得分最高的。
if (containerSucc.fScoreSum < iterSub->second[i].fScoreSum)
{
containerSucc = iterSub->second[i];
continue;
}
}
else
{
LogDebug << "sourceid:" << iter->first << " frameid:" << iterSub->second[i].strBestImg
<< " containerNo:" << iterSub->second[i].strContainerNo << " no equal frameid:"
<< containerSucc.strBestImg << " containerNo:" << containerSucc.strContainerNo;
bNoSameFlag = true;
}
}
//有识别不相同时,选取识别次数最多的。
if (bNoSameFlag)
{
int iCnt = 0;
std::string strMaxContainerNO;
for (auto it = mapConCnt.begin(); it != mapConCnt.end(); it++)
{
LogDebug << "sourceid:" << iter->first << " containerNo:" << it->first << " cnt:" << it->second;
if (iCnt < it->second)
{
iCnt = it->second;
strMaxContainerNO = it->first;
}
}
//根据识别次数最多的箱号,获取最优箱号图
float fMaxScoreSum = 0.0;
for (int i = 0; i < iterSub->second.size(); i++)
{
if (iterSub->second[i].strContainerNo == strMaxContainerNO && iterSub->second[i].fScoreSum > fMaxScoreSum)
{
fMaxScoreSum = iterSub->second[i].fScoreSum;
containerSucc = iterSub->second[i];
}
}
}
if (mapSidConBest.find(iter->first) == mapSidConBest.end())
{
mapSidConBest[iter->first] = std::vector<Container>();
}
if (!containerSucc.strContainerNo.empty())
{
mapSidConBest[iter->first].push_back(containerSucc);
LogDebug << "sourceid:" << iter->first << " index:" << iterSub->first << " push frameid:" << containerSucc.strBestImg
<< " containerNo:" << containerSucc.strContainerNo << " chkFlag:" << containerSucc.bChkFlag;
}
else
{
mapSidConBest[iter->first].push_back(containerFail);
LogDebug << "sourceid:" << iter->first << " index:" << iterSub->first << " push frameid:" << containerFail.strBestImg
<< " containerNo:" << containerFail.strContainerNo << " chkFlag:" << containerFail.bChkFlag;
}
}
}
}
/**
* 识别成功和失败中选取最优结果
* inParam : std::shared_ptr<TrainContainer> pTrainContainer 选优结果
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine_NEW::GetBestContainer(TrainContainer &trainContainerSucc,
TrainContainer &trainContainerFail,
std::map<int, std::vector<Container>> &mapSidConBest)
{
int iBestContainerSid = 0; //默认主摄像头
bool bMainCamFlag = false;
for (auto iter = mapSidConBest.begin(); iter != mapSidConBest.end(); iter++)
{
//获取2个箱号都识别的摄像头id
if (iter->second.size() > 1)
{
if (iter->second.at(0).bChkFlag && iter->second.at(1).bChkFlag)
{
iBestContainerSid = iter->first;
break;
}
if (!bMainCamFlag && (iter->second.at(0).bChkFlag || iter->second.at(1).bChkFlag))
{
iBestContainerSid = iter->first;
bMainCamFlag = (iter->first == 0 ? true : false);
}
}
}
LogDebug << "best sourceid:" << iBestContainerSid << " size:" << mapSidConBest[iBestContainerSid].size();
// 按一个摄像头获取2次识别结果
if (mapSidConBest[iBestContainerSid].size() > 0)
{
if (mapSidConBest[iBestContainerSid].at(0).bChkFlag)
{
trainContainerSucc.container1 = mapSidConBest[iBestContainerSid].at(0);
}
else
{
trainContainerFail.container1 = mapSidConBest[iBestContainerSid].at(0);
}
}
if (mapSidConBest[iBestContainerSid].size() > 1)
{
if (mapSidConBest[iBestContainerSid].at(1).bChkFlag)
{
trainContainerSucc.container2 = mapSidConBest[iBestContainerSid].at(1);
}
else
{
trainContainerFail.container2 = mapSidConBest[iBestContainerSid].at(1);
}
}
/*
循环处理所有摄像头识别结果
1.识别正确,按得分比较取最优结果。
*/
for (auto iter = mapSidConBest.begin(); iter != mapSidConBest.end(); iter++)
{
if (iter->first == iBestContainerSid)
{
continue;
}
if (iter->second.size() > 0)
{
if (iter->second.at(0).bChkFlag)
{
//都校验通过,且相等则按得分比较
if (trainContainerSucc.container1.bChkFlag)
{
if (trainContainerSucc.container1.strContainerNo == iter->second.at(0).strContainerNo &&
trainContainerSucc.container1.fScoreSum < iter->second.at(0).fScoreSum)
{
trainContainerSucc.container1 = iter->second.at(0);
}
}
else
{
//一个校验通过则需和箱号2判断是否相等不一致则用校验通过替换如果一致则不替换。(防止一侧摄像头只能识别位置是2的箱号)
if (trainContainerSucc.container2.strContainerNo != iter->second.at(0).strContainerNo)
{
trainContainerSucc.container1 = iter->second.at(0);
}
}
}
else
{
if (trainContainerFail.container1.strContainerNo.length() < iter->second.at(0).strContainerNo.length())
{
trainContainerFail.container1 = iter->second.at(0);
}
}
}
if (iter->second.size() > 1)
{
if (iter->second.at(1).bChkFlag)
{
//都校验通过,且相等则按得分比较
if (trainContainerSucc.container2.bChkFlag)
{
if (trainContainerSucc.container2.strContainerNo == iter->second.at(1).strContainerNo &&
trainContainerSucc.container2.fScoreSum < iter->second.at(1).fScoreSum)
{
trainContainerSucc.container2 = iter->second.at(1);
}
}
else
{
//一个校验通过则需和箱号1判断是否相等防止箱号1和2一致
if (trainContainerSucc.container1.strContainerNo != iter->second.at(1).strContainerNo)
{
trainContainerSucc.container2 = iter->second.at(1);
}
}
}
else
{
if (trainContainerFail.container2.strContainerNo.length() < iter->second.at(1).strContainerNo.length())
{
trainContainerFail.container2 = iter->second.at(1);
}
}
}
}
}
/**
* 识别成功和失败中选取最优结果
* inParam : std::shared_ptr<TrainContainer> pTrainContainer 选优结果
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine_NEW::SelectBestTrainContainer(std::shared_ptr<TrainContainer> pTrainContainer)
{
//1.获取正向校验通过数据
GetBestContainerBySid(mapSidContainers0_, mapSidConBest0_);
TrainContainer trainContainerSucc0;
TrainContainer trainContainerFail0;
GetBestContainer(trainContainerSucc0, trainContainerFail0, mapSidConBest0_);
*pTrainContainer = trainContainerSucc0;
if (!trainContainerSucc0.container1.strContainerNo.empty() && !trainContainerSucc0.container2.strContainerNo.empty())
{
//正向全部识别成功直接返回。
return;
}
//2. 正向没全部识别成功,获取反向校验通过数据
LogDebug << "select best reverse info";
GetBestContainerBySid(mapSidContainers1_, mapSidConBest1_);
TrainContainer trainContainerSucc1;
TrainContainer trainContainerFail1;
GetBestContainer(trainContainerSucc1, trainContainerFail1, mapSidConBest1_);
// 反向识别且和正向不相等则,按时间顺序设置。
if (!trainContainerSucc1.container1.strContainerNo.empty() && trainContainerSucc1.container1.strContainerNo != pTrainContainer->container1.strContainerNo)
{
// 正向没识别第一个时,反向识别,则反向作为第一个。
if (pTrainContainer->container1.strContainerNo.empty())
{
pTrainContainer->container1 = trainContainerSucc1.container1;
}
else
{
// 正向识别第一个,则肯定没识别到第二个,因此按时间处理下。如果反向也只识别到第一个,则作为第二个集装箱号。
Container container1Temp = pTrainContainer->container1;
if (container1Temp.i64TimeStamp >= trainContainerSucc1.container1.i64TimeStamp)
{
pTrainContainer->container2 = container1Temp;
pTrainContainer->container1 = trainContainerSucc1.container1;
}
else if (trainContainerSucc1.container2.strContainerNo.empty()) //如果反向没识别第二个则反向第一个做为第2个。
{
pTrainContainer->container2 = trainContainerSucc1.container1;
}
}
}
if (!trainContainerSucc1.container2.strContainerNo.empty() && trainContainerSucc1.container2.strContainerNo != pTrainContainer->container2.strContainerNo)
{
if (pTrainContainer->container2.strContainerNo.empty() )
{
pTrainContainer->container2 = trainContainerSucc1.container2;
}
}
if (!pTrainContainer->container1.strContainerNo.empty() && !pTrainContainer->container2.strContainerNo.empty())
{
return;
}
//3. 获取正向未校验通过数据
if (pTrainContainer->container1.strContainerNo.empty())
{
pTrainContainer->container1 = trainContainerFail0.container1;
}
if (pTrainContainer->container2.strContainerNo.empty())
{
pTrainContainer->container2 = trainContainerFail0.container2;
}
//4.获取反向未通过校验数据 (正向有内容不再取反向内容)
if (pTrainContainer->container1.strContainerNo.empty() || pTrainContainer->container2.strContainerNo.empty())
{
if (pTrainContainer->container1.strContainerNo.empty())
{
pTrainContainer->container1 = trainContainerFail1.container1;
}
if (pTrainContainer->container2.strContainerNo.empty())
{
pTrainContainer->container2 = trainContainerFail1.container2;
}
}
}
APP_ERROR SelectBestContainerEngine_NEW::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)
{
DealContainer(pProcessData, transSubData, mapSidContainers0_, mapStep1Pre0_, mapSecondFlag0_);
}
//反方向信息
else if (transSubData.iBigClassId == 1)
{
LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " reverse info";
DealContainer(pProcessData, transSubData, mapSidContainers1_, mapStep1Pre1_, mapSecondFlag1_);
}
}
bool bAllEnd = true;
for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++)
{
bAllEnd = bAllEnd && iter->second;
}
//4. 结束帧时,全部处理掉
if (bAllEnd)
{
std::shared_ptr<TrainContainer> pTrainContainer = std::make_shared<TrainContainer>();
SelectBestTrainContainer(pTrainContainer);
if (pTrainContainer->container1.iDataSource == pTrainContainer->container2.iDataSource &&
pTrainContainer->container1.bChkFlag && pTrainContainer->container2.bChkFlag)
{
if (pTrainContainer->container1.i64TimeStamp > pTrainContainer->container2.i64TimeStamp)
{
LogWarn << "bestcontainer swap container1:" << pTrainContainer->container1.strBestImg << " " << pTrainContainer->container1.strContainerNo
<< " contianer2:" << pTrainContainer->container2.strBestImg << " " << pTrainContainer->container2.strContainerNo;
Container containerTemp = pTrainContainer->container1;
pTrainContainer->container1 = pTrainContainer->container2;
pTrainContainer->container2 = containerTemp;
}
}
outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pTrainContainer));
//push端口1记录csv
outputQueMap_[strPort1_]->push(std::static_pointer_cast<void>(pTrainContainer));
//初始化参数变量
InitParam();
}
}
return APP_ERR_OK;
}