#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 pInferenceResultDataBack = std::static_pointer_cast(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 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 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 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(std::make_shared(message))); } /** * 根据当前帧数据,处理上一帧数据 * inParam : std::shared_ptr pProcessData :当前帧数据 * outParam: N/A * return : N/A */ void TrainStep1FilterEngine::dealProcessDataPre(std::shared_ptr 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::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(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 pVoidData0 = nullptr; inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr == pVoidData0) { usleep(1000); //1ms continue; } std::shared_ptr pInferenceResultData = std::static_pointer_cast(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(pInferenceResultData), true); this->initParam(); } } return APP_ERR_OK; }