VTrain_BothSides/engine/CharacterConversionEngine/TrainCharacterConversionEng...

833 lines
28 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 "TrainCharacterConversionEngine.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);
}
//自定义比较规则
bool CmpVec(const pair<string, uint32_t> &P1, const pair<string, uint32_t> &P2)
{
return P1.second < P2.second;
}
}
TrainCharacterConversionEngine::TrainCharacterConversionEngine() {}
TrainCharacterConversionEngine::~TrainCharacterConversionEngine() {}
APP_ERROR TrainCharacterConversionEngine::Init()
{
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1";
strPort2_ = engineName_ + "_" + std::to_string(engineId_) + "_2";
this->modelConfig_ = Config::getins()->getModelByTrainStep2Config();
this->baseConfig_ = Config::getins()->getBaseConfig();
InitParam();
LogInfo << "TrainCharacterConversionEngine Init ok";
return APP_ERR_OK;
}
APP_ERROR TrainCharacterConversionEngine::DeInit()
{
LogInfo << "TrainCharacterConversionEngine DeInit ok";
return APP_ERR_OK;
}
/**
* 初始化参数信息
*/
void TrainCharacterConversionEngine::InitParam()
{
mapNumInfo_.clear();
iPreFrameId_ = 0;
}
/**
* 校验车型是否符合验证
* inParam : int classId 大框类别id
* : const std::string &trainNum 车型字符信息
* outParam: N/A
* return : true:符合; false:不符合
*/
bool TrainCharacterConversionEngine::authTransNum(int classId, const std::string &trainNum)
{
switch (classId)
{
case TRAIN_HEAD: // 车头上的编号
break;
case K_TRAIN_NUM: // 编号 矿车、煤炭漏斗车(兖矿自备、枣矿自备)
{
if (trainNum == "K13" || trainNum == "KM100AH")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 4:
reg = "^K[1FMZ]{1}[36789]{1}[018ABKNT]{1}";
break;
case 5:
reg = "^K[1M]{1}[368]{1}[1ABDN]{1}[AGKNT]{1}";
break;
case 6:
reg = "^K[MF]{1}[69]{1}[80]{1}A[KH]{1}";
break;
default:
// LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case C_TRAIN_NUM: // 敞车 特殊车型 C5D CF CFK
{
if (trainNum == "CF" || trainNum == "C62A(N)")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 3:
reg = "^C[15678F]{1}[0123456DK]{1}";
break;
case 4:
reg = "^C[1678]{1}[012346]{1}[0ABCEFHKMTY]{1}";
break;
case 5:
reg = "^C[1678]{1}[01246]{1}[0ABCEY]{1}[KAFHNT]{1}";
break;
case 6:
reg = "^C[17]{1}0[0E]{1}[A-]{1}[AH]{1}";
break;
default:
// LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case P_TRAIN_NUM: // 编号 棚车
{
if (trainNum == "P70(H)" || trainNum == "P62(N)")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 3:
reg = "^P[1678]{1}[012345]{1}";
break;
case 4:
reg = "^P[678]{1}[023456]{1}[ABHKNST]{1}";
break;
case 5:
reg = "^P6[24]{1}[ANG]{1}[KT]{1}";
break;
default:
// LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case G_TRAIN_NUM: // 编号 罐车
{
if (trainNum == "GY100SK")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 2:
reg = "^G[HLS]{1}";
break;
case 3:
reg = "^[GL]{1}[1567HL]{1}[01246789K]{1}";
break;
case 4:
reg = "^[GU]{1}[167FJLNQSWY]{1}[170689]{1}[KSABDGTM075W]{1}";
break;
case 5:
reg = "^[GU]{1}[17FHNQY6]{1}[1706A89]{1}[SBDAM057W]{1}[KEHTB0ZAS]{1}";
break;
case 6:
reg = "^[UG]{1}[6YH]{1}[1489A]{1}[057W]{1}[Z0LSA]{1}[KSAT]{1}";
break;
default:
// LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case NX_TRAIN_NUM: // 编号 平车
{
if (trainNum == "N6")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 3:
reg = "^[NQX]{1}[1234678T]{1}[0124567HK]{1}";
break;
case 4:
reg = "^[BNX]{1}[16X]{1}[17BC]{1}[07AGKT]{1}";
break;
case 5:
reg = "^[NX]{1}[16NX]{1}[17C]{1}[07AGT]{1}[KTABH]{1}";
break;
case 6:
reg = "^NX[170]{2}[AB-]{1}[KTHF]{1}";
break;
case 7:
reg = "^NX70[AB]{1}[-]{1}[KTHF]{1}";
break;
default:
// LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case J_TRAIN_NUM: // 编号 牲畜车 特种车
{
if (trainNum == "TP64GK")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 2:
reg = "^[DT]{1}[2678]{1}";
break;
case 3:
reg = "^[DST]{1}[12346789LQ]{1}[012578ADFGP]{1}";
break;
case 4:
reg = "^[DJNT]{1}[12356AFKQS]{1}[012345678DFQS]{1}[A12345679GHKQ]{1}";
break;
case 5:
reg = "^[DJQT]{1}[2KNSH1P]{1}[613XQ2]{1}[A761234B]{1}[KA70G]{1}";
break;
default:
// LogWarn << "Unknow train classId: " << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
default:
LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return true;
}
/**
* 过滤第二步字段代号的误识别
* inParam : std::vector<SingleData> &vecObjs
* : TargetMaxLen iMaxLen
* outParam: N/A
* return : N/A
*/
void TrainCharacterConversionEngine::filterSingleData(std::vector<SingleData> &vecObjs, TargetMaxLen iMaxLen)
{
/*误识别场景
例: 车厢容积属性只有2位时但因误识别导致自重的某个字符字段代号错误划归到容积中这样实际只有2位的容积变为3位。导致选优时错误。
只处理1个字段代号的误识别若有多个字段代号同时错误无法区分哪些字符字段代号是正确的。(字段代号误识别较多时,则增强模型训练)
排除一个最大和最小值后计算平局坐标值,每个框左上角和平局值左上角高度差大于平局值的高度则剔除.
*/
if (vecObjs.size() != iMaxLen || vecObjs.size() <= 2)
{
return;
}
std::deque<SingleData> dqObjs(vecObjs.begin(), vecObjs.end());
std::sort(dqObjs.begin(), dqObjs.end(), [](SingleData &a, SingleData &b)
{
return a.fLTY < b.fLTY;
});
dqObjs.pop_front();
dqObjs.pop_back();
SingleData singleDataAvg;
for (auto & dqObj : dqObjs)
{
singleDataAvg.fLTX += dqObj.fLTX;
singleDataAvg.fLTY += dqObj.fLTY;
singleDataAvg.fRBX += dqObj.fRBX;
singleDataAvg.fRBY += dqObj.fRBY;
}
singleDataAvg.fLTX = singleDataAvg.fLTX / dqObjs.size();
singleDataAvg.fLTY = singleDataAvg.fLTY / dqObjs.size();
singleDataAvg.fRBX = singleDataAvg.fRBX / dqObjs.size();
singleDataAvg.fRBY = singleDataAvg.fRBY / dqObjs.size();
float fAvgHeight = singleDataAvg.fRBY - singleDataAvg.fLTY;
//剔除位置错误的字符信息
for (auto iter = vecObjs.begin(); iter != vecObjs.end(); iter++)
{
float fTemp = fabs(iter->fLTY - singleDataAvg.fLTY);
if (fTemp > (fAvgHeight - 5))
{
std::string strOne = this->modelConfig_.vecClass.at(iter->iClassId);
LogWarn << "engineId:" << engineId_ << " " << strOne << " Line wrong ";
vecObjs.erase(iter);
break;
}
}
}
/**
* 属性框内容转换
* inParam : std::map<int, std::vector<SingleData>> &mapLine
* outParam: TransSubData &transSubData
* return : N/A
*/
void TrainCharacterConversionEngine::transPro(Step2ResultData &step2ResultData, std::map<int, std::vector<SingleData>> &mapLine)
{
//载重
if (mapLine.find(0) != mapLine.end())
{
TransInfo loadInfo;
loadInfo.iLine = 0;
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] < '0' || strOne[0] > '9')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in load";
continue;
}
strTemp += strOne;
loadInfo.vecValue.emplace_back(strOne);
loadInfo.vecScore.emplace_back(mapLine.at(0).at(j).fScore);
step2ResultData.fSubScoreSum += mapLine.at(0).at(j).fScore;
}
//匹配正则表达式
//std::regex reg("^[0-9]{2}");
std::regex reg("^([4,5,6,7,8,9]{1}[0-9]{1}|[1]{1}[0-3]{1}[0-9]{1})$"); //(第1位棚车:4 5; K自备车:1 5 7 8 9; 平车:7; 罐车:6 7; 敞车:6 7 8)
if (std::regex_match(strTemp, reg))
{
loadInfo.IsChkFlag = true;
}
loadInfo.strTmpResult = strTemp;
step2ResultData.vecTransInfo.emplace_back(loadInfo);
}
//自重
if (mapLine.find(1) != mapLine.end())
{
this->filterSingleData(mapLine.at(1), SELF_MAXLEN);
TransInfo selfInfo;
selfInfo.iLine = 1;
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')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in self";
continue;
}
strTemp += strOne;
selfInfo.vecValue.emplace_back(strOne);
selfInfo.vecScore.emplace_back(mapLine.at(1).at(j).fScore);
step2ResultData.fSubScoreSum += mapLine.at(1).at(j).fScore;
}
//匹配正则表达式
std::regex reg("^[1,2,3]{1}[0-9]{1,2}$");
if (std::regex_match(strTemp, reg))
{
selfInfo.IsChkFlag = true;
}
selfInfo.strTmpResult = strTemp;
step2ResultData.vecTransInfo.emplace_back(selfInfo);
}
//容积
if (mapLine.find(2) != mapLine.end())
{
this->filterSingleData(mapLine.at(2), VOLUME_MAXLEN);
TransInfo volumeInfo;
volumeInfo.iLine = 2;
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')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in volume";
continue;
}
strTemp += strOne;
volumeInfo.vecValue.emplace_back(strOne);
volumeInfo.vecScore.emplace_back(mapLine.at(2).at(j).fScore);
step2ResultData.fSubScoreSum += mapLine.at(2).at(j).fScore;
}
//匹配正则表达式
//std::regex reg("^[0-9]{2,3}$");
std::regex reg("^[1,6,7,8,9]{1}[0-9]{1,2}$"); //(第1位棚车:1; K自备车:1或9; 罐车:6或7; 敞车:7或8)
if (std::regex_match(strTemp, reg))
{
volumeInfo.IsChkFlag = true;
}
volumeInfo.strTmpResult = strTemp;
step2ResultData.vecTransInfo.emplace_back(volumeInfo);
}
//换长
if (mapLine.find(3) != mapLine.end())
{
TransInfo changeInfo;
changeInfo.iLine = 3;
std::string strTemp;
for (auto j = 0; j < mapLine.at(3).size(); j++)
{
//过滤非数字
std::string strOne = this->modelConfig_.vecClass.at(mapLine.at(3).at(j).iClassId);
if (strOne[0] < '0' || strOne[0] > '9')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in change";
continue;
}
strTemp += strOne;
changeInfo.vecValue.emplace_back(strOne);
changeInfo.vecScore.emplace_back(mapLine.at(3).at(j).fScore);
step2ResultData.fSubScoreSum += mapLine.at(3).at(j).fScore;
}
//匹配正则表达式
//std::regex reg("^[0-9]{2}$");
std::regex reg("^[1]{1}[0-9]{1}$");
if (std::regex_match(strTemp, reg))
{
changeInfo.IsChkFlag = true;
}
changeInfo.strTmpResult = strTemp;
step2ResultData.vecTransInfo.emplace_back(changeInfo);
}
//罐车容量计表
if (mapLine.find(4) != mapLine.end())
{
TransInfo volumeSurfaceInfo;
volumeSurfaceInfo.iLine = 4;
std::string strTemp;
for (auto j = 0; j < mapLine.at(4).size(); j++)
{
strTemp += this->modelConfig_.vecClass.at(mapLine.at(4).at(j).iClassId);
volumeSurfaceInfo.vecValue.emplace_back(this->modelConfig_.vecClass.at(mapLine.at(4).at(j).iClassId));
volumeSurfaceInfo.vecScore.emplace_back(mapLine.at(4).at(j).fScore);
step2ResultData.fSubScoreSum += mapLine.at(4).at(j).fScore;
}
volumeSurfaceInfo.IsChkFlag = true; //暂不校验
step2ResultData.vecTransInfo.emplace_back(volumeSurfaceInfo);
}
}
/**
* 车号框内容转换
* inParam : std::map<int, std::vector<SingleData>> &mapLine
* outParam: TransSubData &transSubData
* return : N/A
*/
void TrainCharacterConversionEngine::transNum(Step2ResultData &step2ResultData, std::map<int, std::vector<SingleData>> &mapLine)
{
//车型
if (mapLine.find(0) != mapLine.end())
{
TransInfo typeInfo;
typeInfo.iLine = 0;
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);
strTemp += strOne;
typeInfo.vecValue.emplace_back(strOne);
typeInfo.vecScore.emplace_back(mapLine.at(0).at(j).fScore);
step2ResultData.fSubScoreSum += mapLine.at(0).at(j).fScore;
}
//校验车型是否符合验证
typeInfo.IsChkFlag = this->authTransNum(step2ResultData.iClassId, strTemp);
LogDebug << "--->>> 符合正则吗?" << typeInfo.IsChkFlag << " --- " << strTemp;
typeInfo.strTmpResult = strTemp;
step2ResultData.vecTransInfo.emplace_back(typeInfo);
}
// 编号
if (mapLine.find(1) != mapLine.end())
{
TransInfo numInfo;
numInfo.iLine = 1;
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')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in num";
continue;
}
strTemp += strOne;
numInfo.vecValue.emplace_back(strOne);
numInfo.vecScore.emplace_back(mapLine.at(1).at(j).fScore);
step2ResultData.fSubScoreSum += mapLine.at(1).at(j).fScore;
}
//匹配正则表达式
std::regex reg("^[0-9]{5,7}$"); //车厢编号固定7位
if (std::regex_match(strTemp, reg))
{
numInfo.IsChkFlag = true;
}
numInfo.strTmpResult = strTemp;
// LogDebug << "--->>> 符合正则吗?" << numInfo.IsChkFlag << " --- " << strTemp;
step2ResultData.vecTransInfo.emplace_back(numInfo);
}
}
/**
* 车头框内容转换
* inParam : std::map<int, std::vector<SingleData>> &mapLine
* outParam: TransSubData &transSubData
* return : N/A
*/
void TrainCharacterConversionEngine::transHead(Step2ResultData &step2ResultData, std::map<int, std::vector<SingleData>> &mapLine)
{
//车头型号
if (mapLine.find(0) != mapLine.end())
{
TransInfo typeInfo;
typeInfo.iLine = 0;
std::string strTemp;
for (auto j = 0; j < mapLine.at(0).size(); j++)
{
strTemp += this->modelConfig_.vecClass.at(mapLine.at(0).at(j).iClassId);
typeInfo.vecValue.emplace_back(this->modelConfig_.vecClass.at(mapLine.at(0).at(j).iClassId));
typeInfo.vecScore.emplace_back(mapLine.at(0).at(j).fScore);
step2ResultData.fSubScoreSum += mapLine.at(0).at(j).fScore;
}
//不做结果校验IsChkFlag默认为true
typeInfo.IsChkFlag = true;
step2ResultData.vecTransInfo.emplace_back(typeInfo);
}
//车头编号
if (mapLine.find(1) != mapLine.end())
{
TransInfo numInfo;
numInfo.iLine = 1;
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')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in headnum";
continue;
}
strTemp += strOne;
numInfo.vecValue.emplace_back(strOne);
numInfo.vecScore.emplace_back(mapLine.at(1).at(j).fScore);
step2ResultData.fSubScoreSum += mapLine.at(1).at(j).fScore;
}
//不做结果校验IsChkFlag默认为true
numInfo.IsChkFlag = true;
step2ResultData.vecTransInfo.emplace_back(numInfo);
}
}
/**
* 验证集装箱号是否满足规则(前10位依次与2^0 ~2^9相乘/11 所得余数,即是校验位)
* inParam : std::string &strContainerNo 集装箱号信息
* outParam: N/A
* return : true(校验通过)/false(校验失败)
*/
bool TrainCharacterConversionEngine::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 TrainCharacterConversionEngine::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;
}
// LogDebug << " -- " << info.strTmpResult;
if (this->verifyContainerNo(info.strTmpResult))
{
info.IsChkFlag = true;
}
step2ResultData.vecTransInfo.emplace_back(info);
}
/**
* 记录在画面中间位置识别的车号
* inParam : const TransSubData &transSubData 车号信息
: const std::shared_ptr<ProcessData> &pProcessData 帧数据
* outParam: N/A
* return : N/A
*/
void TrainCharacterConversionEngine::recordNum(const Step2ResultData &step2ResultData, const int iFrameId)
{
float iCenterX = step2ResultData.fLTX + (step2ResultData.fRBX - step2ResultData.fLTX) / 2;
float iImgL = IMAGE_WIDTH / 3;
float iImgR = IMAGE_WIDTH / 3 * 2;
if (iCenterX <= iImgL || iCenterX >= iImgR)
{
return;
}
std::string strValue;
for (const auto& transInfo : step2ResultData.vecTransInfo)
{
if (transInfo.iLine != 1)
{
continue;
}
for (const auto & j : transInfo.vecValue)
{
strValue += j;
}
}
bool bIntervalFlag = ((int)(iFrameId - iPreFrameId_) > iSkipInterval_ * 2);
if (mapNumInfo_.find(strValue) == mapNumInfo_.end())
{
// LogDebug << " frameid:" << iFrameId << " NUM:" << strValue
// << " bIntervalFlag:" << bIntervalFlag;
if (bIntervalFlag)
{
mapNumInfo_[strValue] = iFrameId;
}
}
iPreFrameId_ = iFrameId;
}
APP_ERROR TrainCharacterConversionEngine::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 (auto & i : pVStep2OutputData->vecStep2ResultData)
{
std::vector<SingleData> vecSingleData = i.vecSingleData;
std::map<int, std::vector<SingleData>> mapLine;
for (auto & j : vecSingleData)
{
mapLine[j.iLine].push_back(j);
}
float iWidth = i.fRBX - i.fLTX;
float iHeight = i.fRBY - i.fLTY;
bool bSortByX = iHeight < (iWidth * 1.5); // 竖排集装箱按y坐标排序
//每一行按x坐标排序
for (auto & it : mapLine)
{
if (it.second.size() > 2)
{
std::set<float> setX;
std::set<float> setY;
for (auto & j : it.second)
{
setX.insert(j.fLTX);
setY.insert(j.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 & j : it.second)
{
strTemp += this->modelConfig_.vecClass.at(j.iClassId);
}
}
switch (i.iClassId)
{
case TRAIN_HEAD:
this->transHead(i, mapLine);
// this->recordNum(pVStep2OutputData->vecStep2ResultData[i], pVStep2OutputData->iFrameId);
break;
case TRAIN_PRO:
this->transPro(i, mapLine);
break;
case K_TRAIN_NUM ... NX_TRAIN_NUM:
this->transNum(i, mapLine);
// this->recordNum(pVStep2OutputData->vecStep2ResultData[i], pVStep2OutputData->iFrameId);
break;
case CONTAINERNUM:
this->transContainerNum(i, mapLine);
break;
default:
break;
}
}
if (pVStep2OutputData->iDataSource == 0)
{
outputQueMap_[this->strPort0_]->push(std::static_pointer_cast<void>(pVStep2OutputData), true);
}
else
{
outputQueMap_[this->strPort2_]->push(std::static_pointer_cast<void>(pVStep2OutputData), true);
}
outputQueMap_[strPort1_]->push(std::static_pointer_cast<void>(pVStep2OutputData), true);
if (pVStep2OutputData->bIsEnd)
{
//初始化参数变量
InitParam();
}
}
return APP_ERR_OK;
}