generated from zhangwei/Matrixai
214 lines
7.0 KiB
C++
214 lines
7.0 KiB
C++
#include "ContainerCharacterConversionEngine.h"
|
||
|
||
|
||
using namespace ai_matrix;
|
||
|
||
namespace
|
||
{
|
||
//按照x坐标排列
|
||
bool CompareX(const SingleData &v1, const SingleData &v2)
|
||
{
|
||
return (v1.fLTX < v2.fLTX);
|
||
}
|
||
//按照y坐标排列
|
||
bool CompareY(const SingleData &v1, const SingleData &v2)
|
||
{
|
||
return (v1.fLTY < v2.fLTY);
|
||
}
|
||
}
|
||
|
||
ContainerCharacterConversionEngine::ContainerCharacterConversionEngine() {}
|
||
|
||
ContainerCharacterConversionEngine::~ContainerCharacterConversionEngine() {}
|
||
|
||
APP_ERROR ContainerCharacterConversionEngine::Init()
|
||
{
|
||
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
|
||
strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1";
|
||
this->modelConfig_ = Config::getins()->getModelByTrainStep2Config();
|
||
this->baseConfig_ = Config::getins()->getBaseConfig();
|
||
|
||
LogInfo << "ContainerCharacterConversionEngine Init ok";
|
||
return APP_ERR_OK;
|
||
}
|
||
|
||
APP_ERROR ContainerCharacterConversionEngine::DeInit()
|
||
{
|
||
LogInfo << "ContainerCharacterConversionEngine DeInit ok";
|
||
return APP_ERR_OK;
|
||
}
|
||
|
||
/**
|
||
* 验证集装箱号是否满足规则(前10位依次与2^0 ~2^9相乘)/11 所得余数,即是校验位)
|
||
* inParam : std::string &strContainerNo 集装箱号信息
|
||
* outParam: N/A
|
||
* return : true(校验通过)/false(校验失败)
|
||
*/
|
||
bool ContainerCharacterConversionEngine::verifyContainerNo(std::string &strContainerNo)
|
||
{
|
||
bool bChkFlag = false;
|
||
|
||
if(strContainerNo.length() != 11)
|
||
{
|
||
return bChkFlag;
|
||
}
|
||
|
||
int iSum = 0;
|
||
for (int i = 0; i < strContainerNo.length()-1; ++i)
|
||
{
|
||
iSum += this->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 : std::map<int, std::vector<SingleData>> &mapLine
|
||
* outParam: TransSubData &transSubData
|
||
* return : N/A
|
||
*/
|
||
void ContainerCharacterConversionEngine::transContainerNum(Step2ResultData &step2ResultData, std::map<int, std::vector<SingleData>> &mapLine)
|
||
{
|
||
TransInfo info;
|
||
info.iLine = 0;
|
||
// 箱主代码+设备识别码(4位英文字母)
|
||
if (mapLine.find(0) != mapLine.end())
|
||
{
|
||
std::string strTemp = "";
|
||
for (auto j = 0; j < mapLine.at(0).size(); j++)
|
||
{
|
||
std::string strOne = this->modelConfig_.vecClass.at(mapLine.at(0).at(j).iClassId);
|
||
// 过滤非字母
|
||
if (strOne[0] < 'A' || strOne[0] > 'Z')
|
||
{
|
||
// LogDebug << strOne << " not A-Z in container";
|
||
continue;
|
||
}
|
||
strTemp += strOne;
|
||
info.vecValue.emplace_back(strOne);
|
||
info.vecScore.emplace_back(mapLine.at(0).at(j).fScore);
|
||
step2ResultData.fSubScoreSum += mapLine.at(0).at(j).fScore;
|
||
}
|
||
info.strTmpResult += strTemp;
|
||
}
|
||
|
||
// 箱号(6位数字)
|
||
if (mapLine.find(1) != mapLine.end())
|
||
{
|
||
std::string strTemp = "";
|
||
for (auto j = 0; j < mapLine.at(1).size(); j++)
|
||
{
|
||
std::string strOne = this->modelConfig_.vecClass.at(mapLine.at(1).at(j).iClassId);
|
||
// 过滤非数字
|
||
if (strOne[0] < '0' || strOne[0] > '9')
|
||
{
|
||
// LogDebug << "engineId:" << engineId_ << " " << strOne << " not digit in num";
|
||
continue;
|
||
}
|
||
strTemp += strOne;
|
||
info.vecValue.emplace_back(strOne);
|
||
info.vecScore.emplace_back(mapLine.at(1).at(j).fScore);
|
||
step2ResultData.fSubScoreSum += mapLine.at(1).at(j).fScore;
|
||
}
|
||
info.strTmpResult += strTemp;
|
||
}
|
||
|
||
//校验码(1位数字)
|
||
if (mapLine.find(2) != mapLine.end())
|
||
{
|
||
std::string strTemp = "";
|
||
for (auto j = 0; j < mapLine.at(2).size(); j++)
|
||
{
|
||
//过滤非数字
|
||
std::string strOne = vecClassNames_.at(mapLine.at(2).at(j).iClassId);
|
||
if (strOne[0] < '0' || strOne[0] > '9')
|
||
{
|
||
// LogDebug << "engineId:" << engineId_ << " " << strOne << " not digit in container_2";
|
||
continue;
|
||
}
|
||
strTemp += strOne;
|
||
info.vecValue.emplace_back(strOne);
|
||
info.vecScore.emplace_back(mapLine.at(2).at(j).fScore);
|
||
step2ResultData.fSubScoreSum += mapLine.at(2).at(j).fScore;
|
||
}
|
||
info.strTmpResult += strTemp;
|
||
}
|
||
|
||
if (this->verifyContainerNo(info.strTmpResult))
|
||
{
|
||
info.IsChkFlag = true;
|
||
}
|
||
step2ResultData.vecTransInfo.emplace_back(info);
|
||
}
|
||
|
||
APP_ERROR ContainerCharacterConversionEngine::Process()
|
||
{
|
||
int iRet = APP_ERR_OK;
|
||
while (!isStop_)
|
||
{
|
||
std::shared_ptr<void> pVoidData0 = nullptr;
|
||
inputQueMap_[strPort0_]->pop(pVoidData0);
|
||
if (nullptr == pVoidData0)
|
||
{
|
||
usleep(1000); //1ms
|
||
continue;
|
||
}
|
||
|
||
std::shared_ptr<VStep2OutputData> pVStep2OutputData = std::static_pointer_cast<VStep2OutputData>(pVoidData0);
|
||
|
||
for (int i = 0; i < pVStep2OutputData->vecStep2ResultData.size(); i++)
|
||
{
|
||
std::vector<SingleData> vecSingleData = pVStep2OutputData->vecStep2ResultData[i].vecSingleData;
|
||
|
||
std::map<int, std::vector<SingleData>> mapLine;
|
||
for (int j = 0; j < vecSingleData.size(); j++)
|
||
{
|
||
mapLine[vecSingleData[j].iLine].push_back(vecSingleData[j]);
|
||
}
|
||
|
||
//每一行按x或y坐标排序
|
||
uint32_t iWidth = pVStep2OutputData->vecStep2ResultData[i].fRBX - pVStep2OutputData->vecStep2ResultData[i].fLTX;
|
||
uint32_t iHeight = pVStep2OutputData->vecStep2ResultData[i].fRBY - pVStep2OutputData->vecStep2ResultData[i].fLTY;
|
||
bool bSortByX = iHeight >= (iWidth * 1.5) ? false : true; //竖排集装箱按y坐标排序
|
||
|
||
//每一行按x坐标排序
|
||
for (auto it = mapLine.begin(); it != mapLine.end(); it++)
|
||
{
|
||
if (bSortByX)
|
||
{
|
||
std::sort(it->second.begin(), it->second.end(), CompareX);
|
||
}
|
||
else
|
||
{
|
||
std::sort(it->second.begin(), it->second.end(), CompareY);
|
||
}
|
||
|
||
std::string strTemp = "";
|
||
for (auto j = 0; j < it->second.size(); j++)
|
||
{
|
||
strTemp += this->modelConfig_.vecClass.at(it->second.at(j).iClassId);
|
||
}
|
||
}
|
||
|
||
switch (pVStep2OutputData->vecStep2ResultData[i].iClassId)
|
||
{
|
||
case T_CONTAINER:
|
||
this->transContainerNum(pVStep2OutputData->vecStep2ResultData[i], mapLine);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pVStep2OutputData), true);
|
||
}
|
||
return APP_ERR_OK;
|
||
}
|