1 line
10 KiB
C++
1 line
10 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";
|
||
strPort3_ = engineName_ + "_" + std::to_string(engineId_) + "_3";
|
||
this->modelConfig_ = Config::getins()->getModelByContainerStep2Config();
|
||
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;
|
||
}
|
||
|
||
void ContainerCharacterConversionEngine::transContainerType(Step2ResultData &step2ResultData, std::map<int, std::vector<SingleData>> &mapLine)
|
||
{
|
||
TransInfo info;
|
||
info.iLine = 1;
|
||
//集装箱型号(4位 字母或数字)
|
||
if (mapLine.find(3) != mapLine.end())
|
||
{
|
||
std::string strTemp;
|
||
for (auto j = 0; j < mapLine.at(3).size(); j++)
|
||
{
|
||
strTemp += vecClassNames_.at(mapLine.at(3).at(j).iClassId);
|
||
}
|
||
int nTypesize = strTemp.length();
|
||
nTypesize = nTypesize > 4 ? 4 : nTypesize;
|
||
info.strTmpResult = strTemp.substr(0, nTypesize);
|
||
}
|
||
if (info.strTmpResult.length() != 4)
|
||
{
|
||
info.bIsChkFlag = false;
|
||
}
|
||
// step2ResultData.transInfo = info;
|
||
}
|
||
|
||
/**
|
||
* 集装箱框内容转换
|
||
* 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 = this->modelConfig_.vecClass.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.bIsChkFlag = true;
|
||
}
|
||
else
|
||
{
|
||
info.strTmpResult = "invalid-" + info.strTmpResult;
|
||
}
|
||
|
||
step2ResultData.transInfo = 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);
|
||
|
||
std::shared_ptr<SaveDebugImgData> pSaveDebugImgData = std::make_shared<SaveDebugImgData>();
|
||
pSaveDebugImgData->iFrameId = pVStep2OutputData->iFrameId;
|
||
pSaveDebugImgData->iDataSource = pVStep2OutputData->iDataSource;
|
||
pSaveDebugImgData->strDetectDate = pVStep2OutputData->strDetectDate;
|
||
pSaveDebugImgData->strDetectTime = pVStep2OutputData->strDetectTime;
|
||
pSaveDebugImgData->cvImage = pVStep2OutputData->cvImage.clone();
|
||
pSaveDebugImgData->step2ResultData = pVStep2OutputData->step2ResultData;
|
||
pSaveDebugImgData->vecCornerResultData = pVStep2OutputData->vecCornerResultData;
|
||
|
||
if (pVStep2OutputData->bIsEnd)
|
||
{
|
||
// LogInfo << " --->>> 结束信号 : " << pVStep2OutputData->iDataSource;
|
||
outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_" + std::to_string(pVStep2OutputData->iDataSource)]->push(std::static_pointer_cast<void>(pVStep2OutputData), true);
|
||
// outputQueMap_[strPort3_]->push(std::static_pointer_cast<void>(pSaveDebugImgData), true);
|
||
continue;
|
||
}
|
||
|
||
std::vector<SingleData> vecSingleData = pVStep2OutputData->step2ResultData.vecSingleData;
|
||
|
||
if (pVStep2OutputData->step2ResultData.fScore == 0.0f)
|
||
{
|
||
outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_" + std::to_string(pVStep2OutputData->iDataSource)]->push(std::static_pointer_cast<void>(pVStep2OutputData), true);
|
||
// outputQueMap_[strPort3_]->push(std::static_pointer_cast<void>(pSaveDebugImgData), true);
|
||
continue;
|
||
}
|
||
|
||
std::map<int, std::vector<SingleData>> mapLine;
|
||
for (auto & it_singleData : vecSingleData)
|
||
{
|
||
mapLine[it_singleData.iLine].push_back(it_singleData);
|
||
}
|
||
|
||
bool bSortByX =
|
||
(pVStep2OutputData->step2ResultData.fRBY - pVStep2OutputData->step2ResultData.fLTY) <
|
||
((pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX) *
|
||
1.5);
|
||
|
||
//每一行按x坐标排序
|
||
for (auto & it : mapLine)
|
||
{
|
||
if (it.second.size() > 2)
|
||
{
|
||
std::set<float> setX;
|
||
std::set<float> setY;
|
||
for (auto & it_singleData : it.second)
|
||
{
|
||
setX.insert(it_singleData.fLTX);
|
||
setY.insert(it_singleData.fLTY);
|
||
}
|
||
float X = *setX.rbegin() - *setX.begin();
|
||
float Y = *setY.rbegin() - *setY.begin();
|
||
bSortByX = (X > Y);
|
||
}
|
||
|
||
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 & it_singleData : it.second)
|
||
// {
|
||
// strTemp += this->modelConfig_.vecClass.at(it_singleData.iClassId);
|
||
// }
|
||
}
|
||
|
||
switch (pVStep2OutputData->step2ResultData.iClassId)
|
||
{
|
||
case 0:
|
||
this->transContainerNum(pVStep2OutputData->step2ResultData, mapLine);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
// 模型识别不稳定时才用。
|
||
// if (bSortByX && pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag)
|
||
// {
|
||
// if (mapLine.find(0) != mapLine.end() && mapLine.find(1) != mapLine.end())
|
||
// {
|
||
// if (mapLine.at(1).at(0).fLTX < mapLine.at(0).at(0).fLTX)
|
||
// {
|
||
// pVStep2OutputData->step2ResultData.transInfo.strTmpResult = "invalid-" + pVStep2OutputData->step2ResultData.transInfo.strTmpResult;
|
||
// pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag = false;
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
pSaveDebugImgData->step2ResultData = pVStep2OutputData->step2ResultData;
|
||
outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_" + std::to_string(pVStep2OutputData->iDataSource)]->push(std::static_pointer_cast<void>(pVStep2OutputData), true);
|
||
// outputQueMap_[strPort3_]->push(std::static_pointer_cast<void>(pSaveDebugImgData), true);
|
||
}
|
||
|
||
return APP_ERR_OK;
|
||
}
|