Train_Identify/nvidia_ascend_engine/common_engine/SelectBestEngine/SelectBestContainerEngine.cpp

513 lines
19 KiB
C++
Raw Normal View History

2024-01-23 02:46:26 +00:00
#include "SelectBestContainerEngine.h"
#include "myutils.h"
#define CONTAINER_LEN 11
using namespace ai_matrix;
SelectBestContainerEngine::SelectBestContainerEngine() {}
SelectBestContainerEngine::~SelectBestContainerEngine() {}
APP_ERROR SelectBestContainerEngine::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 Init ok";
return APP_ERR_OK;
}
APP_ERROR SelectBestContainerEngine::DeInit()
{
LogInfo << "SelectBestContainerEngine DeInit ok";
return APP_ERR_OK;
}
/**
*
* inParam : N/A
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine::InitParam()
{
for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++)
{
iter->second = false;
}
mapTCFail0_.clear();
mapTCSucc0_.clear();
mapStep1Pre0_.clear();
mapSecondFlag0_.clear();
mapTCFail1_.clear();
mapTCSucc1_.clear();
mapStep1Pre1_.clear();
mapSecondFlag1_.clear();
}
/**
* (102^0 ~2^9/11 )
* inParam : std::string &strContainerNo
* outParam: N/A
* return : true()/false()
*/
bool SelectBestContainerEngine::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::MakeBestContainer(Container &containerBest,
TransSubData *pTransSubData,
std::shared_ptr<ProcessData> pProcessData)
{
// std::string strContainerInfo;
// for (size_t i = 0; i < pTransSubData->vecTransInfo.size(); i++)
// {
// TransInfo transInfo = pTransSubData->vecTransInfo[i];
// for (size_t j = 0; j < transInfo.vecValue.size(); j++)
// {
// strContainerInfo += transInfo.vecValue[j];
// }
// }
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 : TransSubData &transSubData
: std::shared_ptr<ProcessData> pProcessData
: int iIndex
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine::DealFailContianer(TransSubData &transSubData, std::shared_ptr<ProcessData> pProcessData,
int iIndex, std::map<int, TrainContainer> &mapTCFail)
{
if (mapTCFail.find(pProcessData->iDataSource) == mapTCFail.end())
{
mapTCFail[pProcessData->iDataSource] = TrainContainer();
}
Container containerTemp;
if (iIndex == 1)
{
containerTemp = mapTCFail[pProcessData->iDataSource].container1;
}
else if (iIndex == 2)
{
containerTemp = mapTCFail[pProcessData->iDataSource].container2;
}
if (transSubData.strAllValue.length() > containerTemp.strContainerNo.length())
{
Container containerBest;
MakeBestContainer(containerBest, &transSubData, pProcessData);
if (iIndex == 1)
{
mapTCFail[pProcessData->iDataSource].container1 = containerBest;
}
else if (iIndex == 2)
{
mapTCFail[pProcessData->iDataSource].container2 = containerBest;
}
}
}
/**
*
* inParam : TransSubData &transSubData
: std::shared_ptr<ProcessData> pProcessData
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine::DealSuccContianer(TransSubData &transSubData, std::shared_ptr<ProcessData> pProcessData,
int iIndex, std::map<int, TrainContainer> &mapTCSucc)
{
if (mapTCSucc.find(pProcessData->iDataSource) == mapTCSucc.end())
{
mapTCSucc[pProcessData->iDataSource] = TrainContainer();
}
//iIndex == 1表示第一个集装箱只有第一个时才设置到第一个集装箱中。防止第一个未校验通过第二个校验通过的设置为1.
if (iIndex == 1)
{
Container containerTemp1 = mapTCSucc[pProcessData->iDataSource].container1;
if (containerTemp1.strContainerNo.empty() || transSubData.strAllValue == containerTemp1.strContainerNo)
{
if (transSubData.fScoreSum > containerTemp1.fScoreSum)
{
Container containerBest;
MakeBestContainer(containerBest, &transSubData, pProcessData);
mapTCSucc[pProcessData->iDataSource].container1 = containerBest;
}
return;
}
}
Container containerTemp2 = mapTCSucc[pProcessData->iDataSource].container2;
if (containerTemp2.strContainerNo.empty() || transSubData.strAllValue == containerTemp2.strContainerNo)
{
if (transSubData.fScoreSum > containerTemp2.fScoreSum)
{
Container containerBest;
MakeBestContainer(containerBest, &transSubData, pProcessData);
mapTCSucc[pProcessData->iDataSource].container2 = containerBest;
}
}
}
/**
*
* inParam : std::shared_ptr<TrainContainer> pTrainContainer
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine::SelectBestTrainContainer(std::shared_ptr<TrainContainer> pTrainContainer)
{
Container container1;
Container container2;
/*
*/
//1.获取正向校验通过数据
for (auto iterSucee = mapTCSucc0_.begin(); iterSucee != mapTCSucc0_.end(); iterSucee++)
{
LogDebug << "sourceid:" << iterSucee->first << " frameid:" << iterSucee->second.container1.strBestImg
<< " containerNo1:" << iterSucee->second.container1.strContainerNo << " frameid:" << iterSucee->second.container2.strBestImg
<< " containerNo2:" << iterSucee->second.container2.strContainerNo;
if (!iterSucee->second.container1.strContainerNo.empty() && iterSucee->second.container1.fScoreSum > container1.fScoreSum)
{
container1 = iterSucee->second.container1;
}
if (!iterSucee->second.container2.strContainerNo.empty() && iterSucee->second.container2.fScoreSum > container2.fScoreSum)
{
if (iterSucee->second.container2.strContainerNo == container1.strContainerNo)
{
LogError << "sourceid:" << iterSucee->first << " frameid:" << iterSucee->second.container2.strBestImg
<< " containerNo2:" << iterSucee->second.container2.strContainerNo << " equal containerNo1";
continue;
}
container2 = iterSucee->second.container2;
}
}
pTrainContainer->container1 = container1;
pTrainContainer->container2 = container2;
if (!pTrainContainer->container1.strContainerNo.empty() && !pTrainContainer->container2.strContainerNo.empty())
{
//正向全部识别成功直接返回。
return;
}
//2. 正向没全部识别成功,获取反向校验通过数据
Container containerRev1;
Container containerRev2;
for (auto iterSucee = mapTCSucc1_.begin(); iterSucee != mapTCSucc1_.end(); iterSucee++)
{
LogDebug << "reverse sourceid:" << iterSucee->first << " frameid:"<< iterSucee->second.container1.strBestImg
<< " containerNo1:" << iterSucee->second.container1.strContainerNo << " frameid:"<< iterSucee->second.container2.strBestImg
<< " containerNo2:" << iterSucee->second.container2.strContainerNo;
if (!iterSucee->second.container1.strContainerNo.empty() && iterSucee->second.container1.fScoreSum > containerRev1.fScoreSum)
{
containerRev1 = iterSucee->second.container1;
}
if (!iterSucee->second.container2.strContainerNo.empty() && iterSucee->second.container2.fScoreSum > containerRev2.fScoreSum)
{
containerRev2 = iterSucee->second.container2;
}
}
//反向识别且和正向不相等则,按时间顺序设置。
if (!containerRev1.strContainerNo.empty() && containerRev1.strContainerNo != pTrainContainer->container1.strContainerNo)
{
//正向没识别第一个时,反向识别,则反向作为第一个。
if (pTrainContainer->container1.strContainerNo.empty())
{
pTrainContainer->container1 = containerRev1;
}
else
{
//正向识别第一个,则肯定没识别到第二个,因此按时间处理下。如果反向也只识别到第一个,则作为第二个集装箱号。
Container container1Temp = pTrainContainer->container1;
if(container1Temp.i64TimeStamp >= containerRev1.i64TimeStamp)
{
pTrainContainer->container2 = container1Temp;
pTrainContainer->container1 = containerRev1;
}
else if (containerRev2.strContainerNo.empty())
{
pTrainContainer->container2 = containerRev1;
}
}
}
if (!containerRev2.strContainerNo.empty() && containerRev2.strContainerNo != pTrainContainer->container2.strContainerNo)
{
if (pTrainContainer->container2.strContainerNo.empty() )
{
pTrainContainer->container2 = containerRev2;
}
}
if (!pTrainContainer->container1.strContainerNo.empty() && !pTrainContainer->container2.strContainerNo.empty())
{
return;
}
//3. 获取正向未校验通过数据
for (auto iterFail = mapTCFail0_.begin(); iterFail != mapTCFail0_.end(); iterFail++)
{
LogDebug << "sourceid:" << iterFail->first << " frameid:"<< iterFail->second.container1.strBestImg
<< " containerNo1:" << iterFail->second.container1.strContainerNo << " frameid:"<< iterFail->second.container2.strBestImg
<< " containerNo2:" << iterFail->second.container2.strContainerNo;
if (pTrainContainer->container1.strContainerNo.empty())
{
if (iterFail->second.container1.strContainerNo.length() > pTrainContainer->container1.strContainerNo.length())
{
pTrainContainer->container1 = iterFail->second.container1;
}
}
if (pTrainContainer->container2.strContainerNo.empty())
{
if (iterFail->second.container2.strContainerNo.length() > pTrainContainer->container2.strContainerNo.length())
{
pTrainContainer->container2 = iterFail->second.container2;
}
}
}
//4.获取反向未通过校验数据 (正向有内容不再取反向内容)
if (pTrainContainer->container1.strContainerNo.empty() || pTrainContainer->container2.strContainerNo.empty())
{
for (auto iterFail = mapTCFail1_.begin(); iterFail != mapTCFail1_.end(); iterFail++)
{
LogDebug << "reverse sourceid:" << iterFail->first << " frameid:" << iterFail->second.container1.strBestImg
<< " containerNo1:" << iterFail->second.container1.strContainerNo << " frameid:" << iterFail->second.container2.strBestImg
<< " containerNo2:" << iterFail->second.container2.strContainerNo;
if (pTrainContainer->container1.strContainerNo.empty())
{
if (iterFail->second.container1.strContainerNo.length() > pTrainContainer->container1.strContainerNo.length())
{
pTrainContainer->container1 = iterFail->second.container1;
}
}
if (pTrainContainer->container2.strContainerNo.empty())
{
if (iterFail->second.container2.strContainerNo.length() > pTrainContainer->container2.strContainerNo.length())
{
pTrainContainer->container2 = iterFail->second.container2;
}
}
}
}
}
/**
*
* inParam : std::shared_ptr<TrainContainer> pTrainContainer
* outParam: N/A
* return : N/A
*/
void SelectBestContainerEngine::DealContainer(std::shared_ptr<ProcessData> pProcessData, TransSubData &transSubData,
std::map<int, TrainContainer> &mapTCSucc, std::map<int, TrainContainer> &mapTCFail,
std::map<int, Step1Location> &mapStep1Pre, std::map<int, bool> &mapSecondFlag)
{
/*
mapStep1Pre先保存第1个箱号上一帧识别结果的大框信息
2mapStep1Pre保存第2个箱号的上一帧的大框信息
mapStep1Pre保存的第1个箱号时
12
mapStep1Pre保存的第2个箱号时
21
*/
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 / 2;
iPreCenter = mapStep1Pre[pProcessData->iDataSource].fLTY;
iCurCenter = transSubData.step1Location.fLTY;
}
else
{
//侧部集装箱使用X坐标比较
iCompareValue = pProcessData->iWidth / 2;
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;
if (!bChkFlag)
{
DealFailContianer(transSubData, pProcessData, iIndex, mapTCFail);
}
else
{
DealSuccContianer(transSubData, pProcessData, iIndex, mapTCSucc);
}
}
APP_ERROR SelectBestContainerEngine::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, mapTCSucc0_, mapTCFail0_, mapStep1Pre0_, mapSecondFlag0_);
}
//反方向信息
else if (transSubData.iBigClassId == 1)
{
LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " reverse info";
DealContainer(pProcessData, transSubData, mapTCSucc1_, mapTCFail1_, 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);
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;
}