VTrain/engine/Step1FilterInferenceEngine/TrainStep1FilterEngine.cpp

1 line
32 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 "TrainStep1FilterEngine.h"
using namespace ai_matrix;
//namespace
//{
// //按照x坐标排列
// bool CompareX(const SingleData &a, const SingleData &b)
// {
// return a.fLTX < b.fLTX;
// }
//}
TrainStep1FilterEngine::TrainStep1FilterEngine() {}
TrainStep1FilterEngine::~TrainStep1FilterEngine() {}
APP_ERROR TrainStep1FilterEngine::Init()
{
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
this->baseConfig_ = Config::getins()->getBaseConfig();
this->dataSourceConfig_ = Config::getins()->getDataSourceConfig();
this->identifyConfig_ = Config::getins()->getIdentifyConfig();
this->mapTargetStr_.insert(std::make_pair(NUM, "NUM"));
this->mapTargetStr_.insert(std::make_pair(PRO, "PRO"));
this->mapTargetStr_.insert(std::make_pair(HEAD, "HEAD"));
this->mapTargetStr_.insert(std::make_pair(SPACE, "SPACE"));//SPACE
this->mapTargetStr_.insert(std::make_pair(TRAINSPACE, "SPACE"));//SPACE
this->mapTargetStr_.insert(std::make_pair(CONTAINER, "CONTAINER"));//CONTAINER
this->initParam();
LogInfo << "TrainStep1FilterEngine Init ok";
return APP_ERR_OK;
}
APP_ERROR TrainStep1FilterEngine::DeInit()
{
LogInfo << "TrainStep1FilterEngine DeInit ok";
return APP_ERR_OK;
}
/**
* 参数初始化(列车结束时需调用)
*/
void TrainStep1FilterEngine::initParam()
{
this->pInferenceResultDataPre_ = nullptr;
this->iNotChgCount_ = 0;
while (!this->stackBackInfo_.empty())
{
this->stackBackInfo_.pop();
}
while (!this->queInferenceResultData_.empty())
{
this->queInferenceResultData_.pop();
}
iTrainStatus_ = TRAINSTATUS_RUN;
g_come_direction = DIRECTION_UNKNOWN;
mapCalDirection_.clear();
}
void TrainStep1FilterEngine::addBackInfo()
{
std::string strAllClassType;
for (size_t i = 0; i < this->pInferenceResultDataPre_->vecSingleData.size(); i++)
{
if (strAllClassType.find(this->mapTargetStr_[this->pInferenceResultDataPre_->vecSingleData[i].iTargetType]) != std::string::npos)
{
continue;
}
strAllClassType += this->mapTargetStr_[this->pInferenceResultDataPre_->vecSingleData[i].iTargetType];
}
if (strAllClassType.empty())
{
return;
}
TrainBackInfo trainBackInfo;
trainBackInfo.pInferenceResultData = this->pInferenceResultDataPre_;
trainBackInfo.strAllClassType = strAllClassType;
if (this->stackBackInfo_.empty())
{
this->stackBackInfo_.push(trainBackInfo);
LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " 新增倒车信息:" << strAllClassType
<< " 当前数量:" << this->stackBackInfo_.size();
}
else
{
TrainBackInfo trainBackInfoTop = stackBackInfo_.top();
if (trainBackInfoTop.strAllClassType != trainBackInfo.strAllClassType)
{
if (((g_come_direction == DIRECTION_RIGHT &&
this->dataSourceConfig_.iRightFirst == RIGHT_RUN_AND_PRO_FIRST) ||
(g_come_direction == DIRECTION_LEFT &&
this->dataSourceConfig_.iLeftFirst == LEFT_RUN_AND_PRO_FIRST)) &&
((trainBackInfo.strAllClassType == "SPACE" &&
(trainBackInfoTop.strAllClassType == "PROSPACE" ||
trainBackInfoTop.strAllClassType == "SPACEPRO")) ||
(trainBackInfo.strAllClassType == "NUM" &&
(trainBackInfoTop.strAllClassType == "NUMSPACE" ||
trainBackInfoTop.strAllClassType == "SPACENUM")) ||
((trainBackInfo.strAllClassType == "PROSPACE" ||
trainBackInfo.strAllClassType == "SPACEPRO")
&& trainBackInfoTop.strAllClassType == "PRO")))
{
return;
}
if (((g_come_direction == DIRECTION_RIGHT &&
this->dataSourceConfig_.iRightFirst == RIGHT_RUN_AND_NUM_FIRST) ||
(g_come_direction == DIRECTION_LEFT &&
this->dataSourceConfig_.iRightFirst == LEFT_RUN_AND_NUM_FIRST)) &&
((trainBackInfo.strAllClassType == "SPACE" &&
(trainBackInfoTop.strAllClassType == "NUMSPACE" ||
trainBackInfoTop.strAllClassType == "SPACENUM")) ||
(trainBackInfo.strAllClassType == "PRO" &&
(trainBackInfoTop.strAllClassType == "PROSPACE" ||
trainBackInfoTop.strAllClassType == "SPACEPRO")) ||
((trainBackInfo.strAllClassType == "NUMSPACE" ||
trainBackInfo.strAllClassType == "SPACENUM") &&
trainBackInfoTop.strAllClassType == "NUM")))
{
return;
}
this->stackBackInfo_.push(trainBackInfo);
LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " 新增倒车信息:" << strAllClassType
<< " 当前数量:" << this->stackBackInfo_.size();
}
}
}
bool TrainStep1FilterEngine::isEndDealBackInfo()
{
if (this->stackBackInfo_.empty())
{
return true;
}
bool bPopFlag = false;
if (this->pInferenceResultDataPre_->vecSingleData.size() == 0) return false;
/*
处理倒车数据时数据需设置为倒车主要是保证这样的数据后面Engine不处理防止切分车厢出错。
类型不相等时就pop当pop后还剩一个数据时则表示已经回到了刚开始倒车的地方。只剩一个数据的逻辑在上方
处理最后一个时,不能只判断下类型相同就弹出。需要控制下位置。(要么类型相同位置合适,要么类型不相同)
正向为向左行驶,则当前数据的位置尽量小于等于栈中最后一个元素的位置。
正向为向右行驶,则当前数据的位置尽量大于等于栈中最后一个元素的位置。
*/
// std::sort(this->pInferenceResultDataPre_->vecSingleData.begin(), this->pInferenceResultDataPre_->vecSingleData.end(), CompareX);
std::string strAllClassType;
for (size_t i = 0; i < this->pInferenceResultDataPre_->vecSingleData.size(); i++)
{
if (strAllClassType.find(mapTargetStr_[this->pInferenceResultDataPre_->vecSingleData[i].iTargetType]) != std::string::npos)
{
continue;
}
strAllClassType += mapTargetStr_[this->pInferenceResultDataPre_->vecSingleData[i].iTargetType];
}
if (strAllClassType.empty())
{
return false;
}
if (stackBackInfo_.size() == 1)
{
TrainBackInfo trainBackInfoLast = stackBackInfo_.top();
std::shared_ptr<InferenceResultData> pInferenceResultDataBack = std::static_pointer_cast<InferenceResultData>(trainBackInfoLast.pInferenceResultData);
// std::sort(pInferenceResultDataBack->vecSingleData.begin(), pInferenceResultDataBack->vecSingleData.end(), CompareX);
for (size_t i = 0; i < pInferenceResultDataBack->vecSingleData.size(); i++)
{
int bFlag = -1;
for (size_t j = 0; j < pInferenceResultDataPre_->vecSingleData.size(); j++)
{
if (pInferenceResultDataBack->vecSingleData[i].iClassId == pInferenceResultDataPre_->vecSingleData[j].iClassId)
{
if (pInferenceResultDataPre_->vecSingleData[j].fLTX < 1 || pInferenceResultDataBack->vecSingleData[i].fLTX < 1)
{
LogDebug << "大框X坐标小于1判定为异常大框。过滤";
break;
}
bFlag = (pInferenceResultDataBack->vecSingleData[i].fLTX <= pInferenceResultDataPre_->vecSingleData[j].fLTX) ? 1 : 0;
LogDebug << "帧:" << pInferenceResultDataPre_->iFrameId
<< " 倒车前帧:" << pInferenceResultDataBack->iFrameId
<< " 恢复到原位:" << bFlag
<< " 当前框位置:" << pInferenceResultDataPre_->vecSingleData[i].fLTX
<< " 倒车前位置:" << pInferenceResultDataBack->vecSingleData[i].fLTX
<< "方向:" << g_come_direction;
}
}
if ((g_come_direction == DIRECTION_LEFT && bFlag == 0) ||
(g_come_direction == DIRECTION_RIGHT && bFlag == 1))
{
bPopFlag = true;
break;
}
}
if (bPopFlag)
{
LogDebug << "frameId:" << pInferenceResultDataPre_->iFrameId << " 恢复倒车前的位置:" << bPopFlag;
stackBackInfo_.pop();
}
}
else
{
TrainBackInfo trainBackInfoTop_bak = stackBackInfo_.top();
stackBackInfo_.pop();
TrainBackInfo trainBackInfoTop = stackBackInfo_.top();
if (trainBackInfoTop.strAllClassType != strAllClassType)
{
stackBackInfo_.push(trainBackInfoTop_bak);
LogDebug << "帧:" << pInferenceResultDataPre_->iFrameId << " 倒车信息:" << stackBackInfo_.size()
<< " 顶部倒车信息:" << trainBackInfoTop.strAllClassType << " 本次识别信息:" << strAllClassType;
}
else
{
LogDebug << "帧:" << pInferenceResultDataPre_->iFrameId
<< " 倒车信息:" << stackBackInfo_.size()
<< " 顶部倒车信息:" << trainBackInfoTop.strAllClassType
<< " 本次识别信息:" << strAllClassType
<< " 删除倒车信息:" << trainBackInfoTop_bak.strAllClassType;
}
}
return stackBackInfo_.empty() ? true : false;
}
/**
* 校验火车是否停止
* return : true:停止; false:非停止 1(正常行驶) 2(停车) 3(倒车)
*/
int TrainStep1FilterEngine::getTrainStatus()
{
if (g_come_direction == DIRECTION_UNKNOWN)
{
LogDebug << " frameId:" << this->pInferenceResultDataPre_->iFrameId << " 未判断出行车方向,暂定认为火车正常行驶中";
return TRAINSTATUS_RUN;
}
// 无框时,返回之前的列车状态
if (this->pInferenceResultDataPre_->vecSingleData.size() == 0)
{
return iTrainStatus_;
}
queInferenceResultData_.push(this->pInferenceResultDataPre_);
if (queInferenceResultData_.size() < 3)
{
return TRAINSTATUS_RUN;
}
std::shared_ptr<InferenceResultData> pInferenceResultDataFront = queInferenceResultData_.front();
// iNotChgCount_大于0表示有可能停车此时pop队列数据要多留存几个。用最开始的数据来判断是否真正停车如果每次只用上上帧判断当列车超级慢时可能判断为停车。
int iSizeTemp = iNotChgCount_ > 0 ? 10 : 2;
while (queInferenceResultData_.size() > iSizeTemp)
{
queInferenceResultData_.pop();
}
// LogDebug << "frameId:" << pProcessData->iFrameId << " 判断运动状态队列 第一帧:" << postDataFront.iFrameId << " 队列size:" << quePostData_.size() << " iSizeTemp:" << iSizeTemp;
bool bSameFlag = false;
for (size_t i = 0; i < this->pInferenceResultDataPre_->vecSingleData.size(); i++)
{
SingleData singleDataBack = this->pInferenceResultDataPre_->vecSingleData[i];
for (size_t j = 0; j < pInferenceResultDataFront->vecSingleData.size(); j++)
{
SingleData singleDataFront = pInferenceResultDataFront->vecSingleData[j];
/*
使用iBigClassId可能出现平车只有间隔大框且间隔大框可以一会是平车间隔一会是通用间隔。导致类别不一样
使用iTargetType可能出现平车只有间隔大框且间隔大框可以一会是平车间隔一会是通用间隔。导致像素差判断不准。
*/
if (singleDataFront.iTargetType != singleDataBack.iTargetType)
{
LogDebug << "判断前后帧识别的是否一致 上一个:" << singleDataFront.iTargetType << " 当前:" << singleDataBack.iTargetType;
continue;
}
if (singleDataFront.iTargetType == CONTAINER) continue;
bSameFlag = true;
int iCenterBack = singleDataBack.fLTX + (singleDataBack.fRBX - singleDataBack.fLTX) / 2;
int iCenterFront = singleDataFront.fLTX + (singleDataFront.fRBX - singleDataFront.fLTX) / 2;
if (abs(iCenterBack - iCenterFront) > this->identifyConfig_.iChkstopPx)
{
iNotChgCount_ = 0;
/*
iCenterBack > iCenterFront 表示向右行驶,且原方向为向左行驶
iCenterBack < iCenterFront 表示向左行驶,且原方向为向右行驶
以上2种表示倒车。
*/
if ((iCenterBack > iCenterFront && g_come_direction == DIRECTION_LEFT) ||
(iCenterBack < iCenterFront && g_come_direction == DIRECTION_RIGHT))
{
if (this->identifyConfig_.iPartitionFrameSpan < (this->pInferenceResultDataPre_->iFrameId - pInferenceResultDataFront->iFrameId)
&& this->identifyConfig_.iSplitFrameSpanPx < abs(iCenterBack - iCenterFront))
{
return TRAINSTATUS_RUN;
}
// LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " 检测到火车倒车";
return TRAINSTATUS_BACK;
}
else
{
// LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " 正常行驶";
return TRAINSTATUS_RUN;
}
}
/*
小于10个像素表示可能停车累计未变化次数。
累计变化次数超过10次返回停车
累计变化次数未超过10次返回之前行驶状态
*/
else
{
iNotChgCount_++;
LogDebug << " frameId:" << this->pInferenceResultDataPre_->iFrameId
<< " 大框移动范围小("
<< abs(iCenterBack - iCenterFront)
<< ") 判断停车计数:" << iNotChgCount_ << "/" << this->identifyConfig_.iChkstopCount;
if (iNotChgCount_ > this->identifyConfig_.iChkstopCount)
{
LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " 检测到火车停车";
return TRAINSTATUS_STOP;
}
else
{
// LogDebug << "frameId:" << pProcessData->iFrameId << " iTrainStatus_:" << iTrainStatus_;
return iTrainStatus_;
}
}
}
}
/*
未找到相同的框,说明是老框消失掉了,新框出现了。
按新框出现的位置判断是向左行驶,还是向右行驶。
*/
LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " bSameFlag:" << bSameFlag;
if (!bSameFlag)
{
// std::sort(this->pInferenceResultDataPre_->vecSingleData.begin(), this->pInferenceResultDataPre_->vecSingleData.end(), CompareX);
SingleData singleData = this->pInferenceResultDataPre_->vecSingleData.front();
if (g_come_direction == DIRECTION_LEFT)
{
singleData = this->pInferenceResultDataPre_->vecSingleData.back();
}
LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " fLTX:" << singleData.fLTX << " fRBX:" << singleData.fRBX;
iNotChgCount_ = 0;
int iCenter = singleData.fLTX + (singleData.fRBX - singleData.fLTX) / 2;
int iValue = IMAGE_WIDTH / 2;
if ((iCenter > iValue && g_come_direction == DIRECTION_RIGHT) ||
(iCenter < iValue && g_come_direction == DIRECTION_LEFT))
{
/*
针对有效帧较少时,和上上帧比较没有同类型大框,且当前帧已行驶到画面中心导致误判的情况,
增加和上帧同类型大框的比较处理。
*/
std::shared_ptr<InferenceResultData> pInferenceResultDataMiddle = queInferenceResultData_.front();
for (size_t i = 0; i < pInferenceResultDataPre_->vecSingleData.size(); i++)
{
SingleData singleDataBack = pInferenceResultDataPre_->vecSingleData[i];
for (size_t j = 0; j < pInferenceResultDataMiddle->vecSingleData.size(); j++)
{
SingleData singleDataMiddle = pInferenceResultDataMiddle->vecSingleData[j];
if (singleDataMiddle.iTargetType != singleDataBack.iTargetType)
{
continue;
}
int iCenterBack = singleDataBack.fLTX + (singleDataBack.fRBX - singleDataBack.fLTX) / 2;
int iCenterMiddle = singleDataMiddle.fLTX + (singleDataMiddle.fRBX - singleDataMiddle.fLTX) / 2;
// 位置比较大于10个像素则表示有移动。再判断时正向移动还是倒车
LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " " << iCenterBack << "-" << iCenterMiddle
<< "=" << abs(iCenterBack - iCenterMiddle) << " 目标差值:" << this->identifyConfig_.iChkstopPx;
if (abs(iCenterBack - iCenterMiddle) > this->identifyConfig_.iChkstopPx)
{
if ((iCenterBack > iCenterMiddle && g_come_direction == DIRECTION_LEFT) ||
(iCenterBack < iCenterMiddle && g_come_direction == DIRECTION_RIGHT))
{
LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " 检测到火车倒车";
return TRAINSTATUS_BACK;
}
else
{
LogDebug << "frameId:" << this->pInferenceResultDataPre_->iFrameId << " 正常行驶";
return TRAINSTATUS_RUN;
}
}
}
}
// LogDebug << "frameId:" << pProcessData->iFrameId << " back2";
return iTrainStatus_;
}
}
// LogDebug << "frameId:" << pProcessData->iFrameId << " iNotChgCount_:" << iNotChgCount_ << " run run";
return TRAINSTATUS_RUN;
}
/**
* 计算行车方向新
*/
void TrainStep1FilterEngine::calculateDirection()
{
/*
连续3帧同目标识别框信息
判断位置差异是否超过10px(判停车参数),且两两之间都是线性。如果符合则计算方向。
上述条件不符合则剔除第一个元素再次累计连续3帧处理。
*/
for (auto iter = this->pInferenceResultDataPre_->vecSingleData.begin();
iter != this->pInferenceResultDataPre_->vecSingleData.end(); iter++)
{
// 火车车头和集装箱号 暂不参与方向判断
if (iter->iClassId == CONTAINERNUM
|| iter->iClassId == TRAIN_HEAD) continue;
CalculateInfo calInfo;
calInfo.iFrameId = this->pInferenceResultDataPre_->iFrameId;
calInfo.iBigClassId = iter->iClassId;
calInfo.fCenterX = iter->fLTX + (iter->fRBX - iter->fLTX) / 2;
calInfo.fTargetWidth = iter->fRBX - iter->fLTX;
auto iterSubMap = this->mapCalDirection_.find(iter->iClassId);
if (iterSubMap == this->mapCalDirection_.end())
{
std::vector<CalculateInfo> vecTemp;
this->mapCalDirection_.insert(std::make_pair(iter->iClassId, vecTemp));
iterSubMap = this->mapCalDirection_.find(iter->iClassId);
}
iterSubMap->second.emplace_back(calInfo);
if (iterSubMap->second.size() > 2)
{
LogDebug << " frameid:" << this->pInferenceResultDataPre_->iFrameId
<< " last:" << iterSubMap->second.at(2).iFrameId << " " << iterSubMap->second.at(2).fCenterX
<< " mid:" << iterSubMap->second.at(1).iFrameId << " " << iterSubMap->second.at(1).fCenterX
<< " pre:" << iterSubMap->second.at(0).iFrameId << " " << iterSubMap->second.at(0).fCenterX;
//如果帧号连续且移动位置大于15px则计算方向
if (iterSubMap->second.at(2).iFrameId - iterSubMap->second.at(1).iFrameId != 1 ||
iterSubMap->second.at(1).iFrameId - iterSubMap->second.at(0).iFrameId != 1)
{
iterSubMap->second.erase(iterSubMap->second.begin());
continue;
}
if (abs(iterSubMap->second.at(0).fTargetWidth -
iterSubMap->second.at(2).fTargetWidth) >= 1.5*this->identifyConfig_.iChkstopPx) {
iterSubMap->second.erase(iterSubMap->second.begin());
continue;
}
int iLast = iterSubMap->second.at(2).fCenterX;
int iMid = iterSubMap->second.at(1).fCenterX;
int iPre = iterSubMap->second.at(0).fCenterX;
if (abs(iPre - iLast) <= this->identifyConfig_.iChkstopPx)
{
iterSubMap->second.erase(iterSubMap->second.begin());
continue;
}
if (iPre <= iMid && iMid <= iLast)
{
g_come_direction = DIRECTION_RIGHT;
}
else if (iPre >= iMid && iMid >= iLast)
{
g_come_direction = DIRECTION_LEFT;
}
else
{
iterSubMap->second.erase(iterSubMap->second.begin());
continue;
}
// LogDebug << " frameid:" << pInferenceResultDataPre_->iFrameId << " iDirection_:" << g_come_direction;
}
}
}
void TrainStep1FilterEngine::sendComeTrain(const std::string strTrainDate, const std::string strTrainName, const int iDirection) {
std::string message = "{\"cometime\":\"" + strTrainDate + " " + strTrainName + "\",\"type\":\"1\",\"direction\":" + std::to_string(iDirection == this->dataSourceConfig_.iDirection ? 1:-1) + "}";
LogWarn << message;
outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_1"]->push(std::static_pointer_cast<void>(std::make_shared<std::string>(message)));
}
/**
* 根据当前帧数据,处理上一帧数据
* inParam : std::shared_ptr<ProcessData> pProcessData :当前帧数据
* outParam: N/A
* return : N/A
*/
void TrainStep1FilterEngine::dealProcessDataPre(std::shared_ptr<InferenceResultData> pInferenceResultData)
{
/*
目标框是否是连续识别,只识别到一帧的目标框认为误识别,过滤掉。
判断上一帧,当前帧 是否有框
上一帧有框,当前帧有框,说明连续识别,正常处理。
上一帧有框,当前帧无框,则非连续识别,过滤大框
上一帧无框,当前帧有框,则连续识别个数置零。
上一帧无框,当前帧无框,则连续识别个数置零。
*/
if (!this->pInferenceResultDataPre_) return;
int iHeadContinueCnt = 0;
int iProContinueCnt = 0;
int iNumContinueCnt = 0;
int iSpaceContinueCnt = 0;
int iTrainSpaceContinueCnt = 0;
int iContainerContinueCnt = 0;
for (int i = 0; i < pInferenceResultData->vecSingleData.size(); i++)
{
if (pInferenceResultData->vecSingleData[i].iTargetType == HEAD)
{
iHeadContinueCnt++;
}
else if (pInferenceResultData->vecSingleData[i].iTargetType == PRO)
{
iProContinueCnt++;
}
else if (pInferenceResultData->vecSingleData[i].iTargetType == NUM)
{
iNumContinueCnt++;
}
else if (pInferenceResultData->vecSingleData[i].iTargetType == SPACE)
{
iSpaceContinueCnt++;
}
else if (pInferenceResultData->vecSingleData[i].iTargetType == TRAINSPACE)
{
iTrainSpaceContinueCnt++;
}
else if (pInferenceResultData->vecSingleData[i].iTargetType == CONTAINER)
{
iContainerContinueCnt++;
}
}
for (int i = 0; i < this->pInferenceResultDataPre_->vecSingleData.size(); i++)
{
if (this->pInferenceResultDataPre_->vecSingleData[i].iTargetType == HEAD)
{
iHeadContinueCnt++;
}
else if (this->pInferenceResultDataPre_->vecSingleData[i].iTargetType == PRO)
{
iProContinueCnt++;
}
else if (this->pInferenceResultDataPre_->vecSingleData[i].iTargetType == NUM)
{
iNumContinueCnt++;
}
else if (this->pInferenceResultDataPre_->vecSingleData[i].iTargetType == SPACE)
{
iSpaceContinueCnt++;
}
else if (this->pInferenceResultDataPre_->vecSingleData[i].iTargetType == TRAINSPACE)
{
iTrainSpaceContinueCnt++;
}
else if (this->pInferenceResultDataPre_->vecSingleData[i].iTargetType == CONTAINER)
{
iContainerContinueCnt++;
}
}
//非连续识别的情况,认为误识别,剔除误识别的大框信息
for (std::vector<SingleData>::iterator it = pInferenceResultDataPre_->vecSingleData.begin(); it != pInferenceResultDataPre_->vecSingleData.end();)
{
if (iHeadContinueCnt < 2 && it->iTargetType == HEAD)
{
LogDebug << " frameId:" << pInferenceResultDataPre_->iFrameId << " Head 框因非连续识别而过滤";
it = pInferenceResultDataPre_->vecSingleData.erase(it);
continue;
}
if (iProContinueCnt < 2 && it->iTargetType == PRO)
{
LogDebug << " frameId:" << pInferenceResultDataPre_->iFrameId << " PRO 框因非连续识别而过滤";
it = pInferenceResultDataPre_->vecSingleData.erase(it);
continue;
}
if (iNumContinueCnt < 2 && it->iTargetType == NUM)
{
LogDebug << " frameId:" << pInferenceResultDataPre_->iFrameId << " NUM 框因非连续识别而过滤";
it = pInferenceResultDataPre_->vecSingleData.erase(it);
continue;
}
if (iSpaceContinueCnt < 2 && it->iTargetType == SPACE)
{
LogDebug << " frameId:" << pInferenceResultDataPre_->iFrameId << " SPACE 框因非连续识别而过滤";
it = pInferenceResultDataPre_->vecSingleData.erase(it);
continue;
}
if (iTrainSpaceContinueCnt < 2 && it->iTargetType == TRAINSPACE)
{
LogDebug << " frameId:" << pInferenceResultDataPre_->iFrameId << " TRAINSPACE 框因非连续识别而过滤";
it = pInferenceResultDataPre_->vecSingleData.erase(it);
continue;
}
// if (iTrainSpaceContinueCnt < 2 && it->iTargetType == CONTAINER)
// {
// LogDebug << " frameId:" << pInferenceResultDataPre_->iFrameId << " CONTAINER 框因非连续识别而过滤";
// it = pInferenceResultDataPre_->vecSingleData.erase(it);
// continue;
// }
it++;
}
//判定行驶方向, 记录Direction文件信息
if (g_come_direction == DIRECTION_UNKNOWN)
{
LogInfo << "暂未判断出来车方向";
this->calculateDirection();
// if (g_come_direction != DIRECTION_UNKNOWN) this->sendComeTrain(pProcessData->strTrainDate, pProcessData->strTrainName, iDirection_);
}
if (g_come_direction != DIRECTION_UNKNOWN)
{
std::string strFilePath = this->baseConfig_.strDebugResultPath + "/"
+ pInferenceResultDataPre_->strTrainDate + "/"
+ StringUtil::getins()->replace_all_distinct(pInferenceResultDataPre_->strTrainTime, ":", "-") + "/"
+ "jpg/"
+ std::to_string(pInferenceResultDataPre_->iFrameId) + ".json";
Json::Value jvJsonInfo;
if (!this->readJson(strFilePath, jvJsonInfo, 10))
{
LogError << "读取JSON失败需检查是否占用";
}
jvJsonInfo["direction"] = g_come_direction.load();
if (!FileUtil::getins()->writeJsonInfo(jvJsonInfo, strFilePath))
{
LogError << "来车方向存储失败:" << strFilePath;
}
else
{
LogDebug << "来车方向为(1左2右)" << g_come_direction;
}
}
//主摄像头校验是否停车
int iTrainStatusTemp = iTrainStatus_;
iTrainStatus_ = this->getTrainStatus();
iTrainStatusTemp = iTrainStatus_;
if (iTrainStatus_ == TRAINSTATUS_STOP)
{
//停车
}
else if (iTrainStatus_ == TRAINSTATUS_BACK)
{
//倒车
addBackInfo();
iTrainStatusTemp = TRAINSTATUS_STOP;
}
else if(iTrainStatus_ == TRAINSTATUS_RUN)
{
/*
正向行驶需先把倒车产生的倒车数据处理完毕,即使车辆回到原倒车点,再开始识别行驶数据
*/
if(!this->isEndDealBackInfo())
{
iTrainStatusTemp = TRAINSTATUS_STOP;
}
}
LogDebug << " 帧:" << this->pInferenceResultDataPre_->iFrameId
<< " 火车实时运行状态:" << iTrainStatus_ << "(0无车1运行2停车3倒车) 转换后运行状态:" << iTrainStatusTemp;
this->pInferenceResultDataPre_->iTrainStatus = iTrainStatusTemp;
// this->sendComeTrain(pProcessData->strTrainDate, pProcessData->strTrainName, iDirection_);
//上一帧push端口0
outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pInferenceResultDataPre_));
}
bool TrainStep1FilterEngine::readJson(std::string &strFilePath, Json::Value &jvInfo, int i)
{
i--;
if (access(strFilePath.c_str(), F_OK) != 0)
{
LogWarn << "文件:" << strFilePath << " 不存在";
return i > 0 ? this->readJson(strFilePath, jvInfo, i) : false;
}
if (!FileUtil::getins()->readJsonInfo(jvInfo, strFilePath))
{
LogError << "读取json文件失败:" << strFilePath;
return i > 0 ? this->readJson(strFilePath, jvInfo, i) : false;
}
return true;
}
APP_ERROR TrainStep1FilterEngine::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<InferenceResultData> pInferenceResultData = std::static_pointer_cast<InferenceResultData>(pVoidData0);
// 不识别集装箱的情况下1帧最多识别4个大框。[(车头、车厢间隔、间隔、车号); (车号、车厢间隔、间隔、属性)]
if (pInferenceResultData->vecSingleData.size() > 5 && !this->identifyConfig_.bContainerDetect)
{
LogWarn << " frameId:" << pInferenceResultData->iFrameId
<< " 识别到的目标个数超出预期 size:" << pInferenceResultData->vecSingleData.size();
pInferenceResultData->vecSingleData.clear();
continue;
}
// 识别集装箱的情况下1帧最多识别5个大框。[(车头、车厢间隔、间隔、车号、集装箱); (车号、车厢间隔、间隔、属性、集装箱)]
if (pInferenceResultData->vecSingleData.size() > 5 && this->identifyConfig_.bContainerDetect)
{
LogWarn << " frameId:" << pInferenceResultData->iFrameId
<< " 识别到的目标个数超出预期 size:" << pInferenceResultData->vecSingleData.size();
pInferenceResultData->vecSingleData.clear();
continue;
}
// 根据当前帧数据,处理上一帧数据
this->dealProcessDataPre(pInferenceResultData);
this->pInferenceResultDataPre_ = pInferenceResultData;
if (pInferenceResultData->bIsEnd)
{
// 结束帧push端口0
LogDebug << " frameid:" << pInferenceResultData->iFrameId << " isEnd:" << pInferenceResultData->bIsEnd;
outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pInferenceResultData), true);
this->initParam();
}
}
return APP_ERR_OK;
}