2024-01-23 02:46:26 +00:00
|
|
|
|
#include "DataDealTwoEngine.h"
|
|
|
|
|
|
|
|
|
|
|
|
using namespace ai_matrix;
|
|
|
|
|
|
|
|
|
|
|
|
extern bool g_bNoDealStepTwoFlag;
|
|
|
|
|
|
|
|
|
|
|
|
DataDealTwoEngine::DataDealTwoEngine() {}
|
|
|
|
|
|
|
|
|
|
|
|
DataDealTwoEngine::~DataDealTwoEngine() {}
|
|
|
|
|
|
|
|
|
|
|
|
APP_ERROR DataDealTwoEngine::Init()
|
|
|
|
|
|
{
|
|
|
|
|
|
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
|
|
|
|
|
|
strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1";
|
|
|
|
|
|
strPort2_ = engineName_ + "_" + std::to_string(engineId_) + "_2";
|
|
|
|
|
|
strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path");
|
|
|
|
|
|
iIntervalTime_ = 40 *1000;
|
|
|
|
|
|
iSplitSpanPX_ = MyYaml::GetIns()->GetIntValue("gc_split_frame_span_px");
|
|
|
|
|
|
|
|
|
|
|
|
dataSourceConfig_ = MyYaml::GetIns()->GetDataSourceConfigById(engineId_); //获取摄像机参数
|
|
|
|
|
|
mapUseDataSouceCfg_ = MyYaml::GetIns()->GetUseDataSourceConfig();
|
|
|
|
|
|
|
|
|
|
|
|
std::string delimiter(",");
|
|
|
|
|
|
for (auto iter = mapUseDataSouceCfg_.begin(); iter!=mapUseDataSouceCfg_.end(); iter++)
|
|
|
|
|
|
{
|
|
|
|
|
|
int iSourceId = iter->first;
|
|
|
|
|
|
std::vector<std::string> vecSplit = MyUtils::getins()->split(iter->second.strTarget, delimiter);
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> vecPushPorts;
|
|
|
|
|
|
for (auto iter = vecSplit.begin(); iter != vecSplit.end(); iter++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (*iter == "NUM")
|
|
|
|
|
|
{
|
|
|
|
|
|
vecPushPorts.push_back(strPort0_);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (*iter == "CHKDATE")
|
|
|
|
|
|
{
|
|
|
|
|
|
vecPushPorts.push_back(strPort1_);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(*iter == "CONTAINER" || *iter == "CONTAINER_T")
|
|
|
|
|
|
{
|
|
|
|
|
|
vecPushPorts.push_back(strPort2_);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
mapSourcePushPort_[iSourceId] = vecPushPorts;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
InitParam();
|
|
|
|
|
|
LogInfo << "engineId_:" << engineId_ << " DataDealTwoEngine Init ok";
|
|
|
|
|
|
return APP_ERR_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
APP_ERROR DataDealTwoEngine::DeInit()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
LogInfo << "engineId_:" << engineId_ << " DataDealTwoEngine DeInit ok";
|
|
|
|
|
|
return APP_ERR_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 参数初始化(列车结束时需调用)
|
|
|
|
|
|
* inParam : N/A
|
|
|
|
|
|
* outParam: N/A
|
|
|
|
|
|
* return : N/A
|
|
|
|
|
|
*/
|
|
|
|
|
|
void DataDealTwoEngine::InitParam()
|
|
|
|
|
|
{
|
|
|
|
|
|
iTrainIndex_ = 1;
|
|
|
|
|
|
iDirection_ = DIRECTION_UNKNOWN;
|
|
|
|
|
|
iDirectionAndFirst_ = DO_NOT_KNOW_DIRECTION;
|
|
|
|
|
|
iLastSpaceX_ = 0;
|
|
|
|
|
|
iLastSpaceFrameid_ = 0;
|
|
|
|
|
|
iSpaceType_ = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 图片数据解码
|
|
|
|
|
|
* inParam : RawData &rawData :图片数据
|
|
|
|
|
|
* outParam: std::shared_ptr<DecodedData> pDecodedData :解码数据
|
|
|
|
|
|
* return : true(编码成功)/false(编码失败)
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool DataDealTwoEngine::GetJpegdOut(std::shared_ptr<DecodedData> pDecodedData, RawData &rawData)
|
|
|
|
|
|
{
|
|
|
|
|
|
int iRet = APP_ERR_OK;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取大框信息
|
|
|
|
|
|
* inParam : N/A
|
|
|
|
|
|
* outParam: N/A
|
|
|
|
|
|
* return : N/A
|
|
|
|
|
|
*/
|
|
|
|
|
|
void DataDealTwoEngine::GetPostSubDatas(std::vector<PostSubData> &vecPostSubData, Json::Value &jvFrameInfo,
|
|
|
|
|
|
Target tar, Json::Value &jvOneSplit)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::string strKey;
|
|
|
|
|
|
switch (tar)
|
|
|
|
|
|
{
|
|
|
|
|
|
case NUM:
|
|
|
|
|
|
strKey = "step1Num";
|
|
|
|
|
|
break;
|
|
|
|
|
|
case PRO:
|
|
|
|
|
|
strKey = "step1Pro";
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CHKDATE:
|
|
|
|
|
|
strKey = "step1ChkDate";
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CONTAINER:
|
|
|
|
|
|
strKey = "step1Container";
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (strKey.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!jvFrameInfo.isMember(strKey.c_str()))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float fSplitCenterX = jvOneSplit["splitX"].asFloat();
|
|
|
|
|
|
int iValidType = jvOneSplit["validType"].asInt();
|
|
|
|
|
|
|
|
|
|
|
|
Json::Value &jsArray = jvFrameInfo[strKey.c_str()];
|
|
|
|
|
|
for (int i = 0; i < jsArray.size(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
float fCenterX = jsArray[i]["ltx"].asFloat() + (jsArray[i]["rbx"].asFloat() - jsArray[i]["ltx"].asFloat()) / 2;
|
|
|
|
|
|
if (jvOneSplit["useY"].asBool())
|
|
|
|
|
|
{
|
|
|
|
|
|
fCenterX = jsArray[i]["lty"].asFloat() + (jsArray[i]["rby"].asFloat() - jsArray[i]["lty"].asFloat()) / 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool bChkFlag = false;
|
|
|
|
|
|
if(iValidType == VALID_ALL)
|
|
|
|
|
|
{
|
|
|
|
|
|
bChkFlag = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(iValidType == VALID_LEFT && fCenterX < fSplitCenterX)
|
|
|
|
|
|
{
|
|
|
|
|
|
bChkFlag = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(iValidType == VALID_RIGHT && fCenterX > fSplitCenterX)
|
|
|
|
|
|
{
|
|
|
|
|
|
bChkFlag = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (bChkFlag)
|
|
|
|
|
|
{
|
|
|
|
|
|
SingleData sdInfo;
|
|
|
|
|
|
sdInfo.iClassId = jsArray[i]["classid"].asInt();
|
|
|
|
|
|
sdInfo.fScore = jsArray[i]["score"].asFloat();
|
|
|
|
|
|
sdInfo.fLTX = jsArray[i]["ltx"].asFloat();
|
|
|
|
|
|
sdInfo.fLTY = jsArray[i]["lty"].asFloat();
|
|
|
|
|
|
sdInfo.fRBX = jsArray[i]["rbx"].asFloat();
|
|
|
|
|
|
sdInfo.fRBY = jsArray[i]["rby"].asFloat();
|
|
|
|
|
|
sdInfo.fClear = jsArray[i]["clear"].asFloat();
|
|
|
|
|
|
|
|
|
|
|
|
PostSubData postSubData;
|
|
|
|
|
|
postSubData.iBigClassId = sdInfo.iClassId;
|
|
|
|
|
|
postSubData.iTargetType = tar;
|
|
|
|
|
|
if (tar == NUM && postSubData.iBigClassId == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
postSubData.iTargetType = HEAD;
|
|
|
|
|
|
}
|
|
|
|
|
|
postSubData.vecSingleData.emplace_back(sdInfo);
|
|
|
|
|
|
postSubData.step1Location.fLTX = sdInfo.fLTX;
|
|
|
|
|
|
postSubData.step1Location.fLTY = sdInfo.fLTY;
|
|
|
|
|
|
postSubData.step1Location.fRBX = sdInfo.fRBX;
|
|
|
|
|
|
postSubData.step1Location.fRBY = sdInfo.fRBY;
|
|
|
|
|
|
vecPostSubData.emplace_back(postSubData);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取主摄像头车厢间隔坐标信息
|
|
|
|
|
|
* inParam : N/A
|
|
|
|
|
|
* outParam: N/A
|
|
|
|
|
|
* return : N/A
|
|
|
|
|
|
*/
|
|
|
|
|
|
void DataDealTwoEngine::GetMainSplitInfo(Json::Value &jvMainSplit, std::shared_ptr<ProcessData> pProcessData,
|
|
|
|
|
|
Json::Value &jvFrameInfo, std::shared_ptr<TrainRange> pTrainRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pProcessData->iDataSource != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Json::Value jvModelSpace;
|
|
|
|
|
|
if (jvFrameInfo.isMember("step1Space"))
|
|
|
|
|
|
{
|
|
|
|
|
|
jvModelSpace = jvFrameInfo["step1Space"][0];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int iValidType = VALID_ALL; //图像上大框有效类型 {0-全部有效; 1-左边有效; 2-右边有效}
|
|
|
|
|
|
int iSpaceX = 0; //图像上车厢间隔位置
|
|
|
|
|
|
bool bNeedNum = true; //图像上车号框是否有效
|
|
|
|
|
|
bool bNeedPro = true; //图像上属性框是否有效
|
|
|
|
|
|
bool bNeedChkDate = true; //图像定检期框是否有效
|
|
|
|
|
|
bool bNeedContainer = true; //图像集装箱框是否有效
|
|
|
|
|
|
bool bOtherSideNeedNum = true; //另一侧图像上车号框是否有效
|
|
|
|
|
|
bool bOtherSideNeedPro = true; //另一侧图像上属性框是否有效
|
|
|
|
|
|
bool bOtherSideNeedChkDate = true; //另一侧图像上定检期框是否有效
|
|
|
|
|
|
bool bOtherSideNeedContainer = true; //另一侧图像上集装箱框是否有效
|
|
|
|
|
|
|
|
|
|
|
|
if (!jvModelSpace.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
iSpaceX = jvModelSpace["ltx"].asFloat() + (jvModelSpace["rbx"].asFloat() - jvModelSpace["ltx"].asFloat()) / 2;
|
|
|
|
|
|
/*
|
|
|
|
|
|
第一节只有结束间隔;
|
|
|
|
|
|
开始帧间隔为开始间隔;
|
|
|
|
|
|
向左行驶且当前间隔大于上次间隔为结束间隔,向右行驶当前间隔小于上次间隔为结束间隔。
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool bIntervalFlag = ((int)(pProcessData->iFrameId - iLastSpaceFrameid_) > dataSourceConfig_.iSkipInterval * 2);
|
|
|
|
|
|
if (iTrainIndex_ == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
iSpaceType_ = 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (pTrainRange->iStartFrameId == pProcessData->iFrameId)
|
|
|
|
|
|
{
|
|
|
|
|
|
iSpaceType_ = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if ((pProcessData->iDirection == DIRECTION_LEFT && (iLastSpaceX_ < iSpaceX - iSplitSpanPX_) && bIntervalFlag) ||
|
|
|
|
|
|
(pProcessData->iDirection == DIRECTION_RIGHT && (iLastSpaceX_ - iSplitSpanPX_ > iSpaceX) && bIntervalFlag))
|
|
|
|
|
|
{
|
|
|
|
|
|
iSpaceType_ = 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (iSpaceType_ == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
iValidType = pProcessData->iDirection == DIRECTION_LEFT ? VALID_RIGHT : VALID_LEFT;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (iSpaceType_ == 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
iValidType = pProcessData->iDirection == DIRECTION_LEFT ? VALID_LEFT : VALID_RIGHT;
|
|
|
|
|
|
}
|
2024-02-29 08:16:47 +00:00
|
|
|
|
LogDebug << " frameid:" << pProcessData->iFrameId
|
|
|
|
|
|
<< " 车节:" << pProcessData->iTrainIndex << " iSpaceType_:" << iSpaceType_
|
2024-01-23 02:46:26 +00:00
|
|
|
|
<< " iSpaceX:" << iSpaceX << " iLastSpaceX_:" << iLastSpaceX_
|
|
|
|
|
|
<< " iLastSpaceFrameid_:" << iLastSpaceFrameid_ << " bIntervalFlag:" << bIntervalFlag;
|
|
|
|
|
|
iLastSpaceX_ = iSpaceX;
|
|
|
|
|
|
iLastSpaceFrameid_ = pProcessData->iFrameId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
jvMainSplit["validType"] = iValidType;
|
|
|
|
|
|
jvMainSplit["splitX"] = iSpaceX;
|
|
|
|
|
|
jvMainSplit["needNum"] = bNeedNum;
|
|
|
|
|
|
jvMainSplit["needPro"] = bNeedPro;
|
|
|
|
|
|
jvMainSplit["needChkDate"] = bNeedChkDate;
|
|
|
|
|
|
jvMainSplit["needContainer"] = bNeedContainer;
|
|
|
|
|
|
jvMainSplit["otherSideNeedNum"] = bOtherSideNeedNum;
|
|
|
|
|
|
jvMainSplit["otherSideNeedPro"] = bOtherSideNeedPro;
|
|
|
|
|
|
jvMainSplit["otherSideNeedChkDate"] = bOtherSideNeedChkDate;
|
|
|
|
|
|
jvMainSplit["otherSideNeedContainer"] = bOtherSideNeedContainer;
|
|
|
|
|
|
jvMainSplit["mainWidth"] = pProcessData->iWidth;
|
|
|
|
|
|
jvMainSplit["mainHeight"] = pProcessData->iHeight;
|
|
|
|
|
|
|
|
|
|
|
|
if (pProcessData->bIsEnd)
|
|
|
|
|
|
{
|
|
|
|
|
|
iLastSpaceX_ = 0;
|
|
|
|
|
|
iLastSpaceFrameid_ = 0;
|
|
|
|
|
|
iSpaceType_ = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取辅摄像头车厢间隔坐标信息
|
|
|
|
|
|
* inParam : N/A
|
|
|
|
|
|
* outParam: N/A
|
|
|
|
|
|
* return : N/A
|
|
|
|
|
|
*/
|
|
|
|
|
|
void DataDealTwoEngine::GetSubSplitInfoByMain(Json::Value &jvOneSplit, std::shared_ptr<ProcessData> pProcessData, Json::Value &jvFrameInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pProcessData->iDataSource == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pProcessData->iDirection == DIRECTION_RIGHT)
|
|
|
|
|
|
{
|
|
|
|
|
|
//向右行驶时,间隔坐标尽可能小一些,把未完全对其的定检期信息包含进来。
|
|
|
|
|
|
jvOneSplit["splitX"] = jvOneSplit["splitX"].asInt() - 100;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (pProcessData->iDataSource == 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
//顶部集装箱的重设splitX相关逻辑
|
|
|
|
|
|
if (jvOneSplit["rotate"].asInt() == 90)
|
|
|
|
|
|
{
|
|
|
|
|
|
jvOneSplit["useY"] = true;
|
|
|
|
|
|
if (pProcessData->iHeight != jvOneSplit["mainWidth"].asInt())
|
|
|
|
|
|
{
|
|
|
|
|
|
jvOneSplit["splitX"] = jvOneSplit["splitX"].asInt() * pProcessData->iHeight / jvOneSplit["mainWidth"].asInt();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//顶部有间隔时,使用顶部间隔。
|
|
|
|
|
|
if (jvFrameInfo.isMember("step1TopSpace"))
|
|
|
|
|
|
{
|
|
|
|
|
|
Json::Value jvModelSpace = jvFrameInfo["step1TopSpace"][0];
|
|
|
|
|
|
int iSpaceX = jvModelSpace["lty"].asFloat() + (jvModelSpace["rby"].asFloat() - jvModelSpace["lty"].asFloat()) / 2;
|
|
|
|
|
|
LogDebug << "sourceid" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " use TopSpace splitX:"
|
|
|
|
|
|
<< jvOneSplit["splitX"].asInt() << " newsplitX:" << iSpaceX;
|
|
|
|
|
|
jvOneSplit["splitX"] = iSpaceX;
|
|
|
|
|
|
|
|
|
|
|
|
//如果validType为0,则说明主摄像头间隔还未识别到结束间隔,则按顶部摄像头设置validType
|
|
|
|
|
|
if (jvOneSplit["validType"] == VALID_ALL)
|
|
|
|
|
|
{
|
|
|
|
|
|
jvOneSplit["validType"] = pProcessData->iDirection == DIRECTION_LEFT ? VALID_LEFT : VALID_RIGHT;
|
|
|
|
|
|
LogDebug << "sourceid" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId
|
|
|
|
|
|
<< "reset validType:" << jvOneSplit["validType"].asInt();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (pProcessData->iDataSource == 3 || pProcessData->iDataSource == 4)
|
|
|
|
|
|
{
|
|
|
|
|
|
jvOneSplit["splitX"] = (int)(pProcessData->iWidth - jvOneSplit["splitX"].asInt());
|
|
|
|
|
|
int iValidType = jvOneSplit["validType"].asInt();
|
|
|
|
|
|
iValidType = iValidType == VALID_ALL ? iValidType : (iValidType == VALID_LEFT ? VALID_RIGHT : VALID_LEFT);
|
|
|
|
|
|
jvOneSplit["validType"] = iValidType;
|
|
|
|
|
|
jvOneSplit["needNum"] = jvOneSplit["otherSideNeedNum"].asBool();
|
|
|
|
|
|
jvOneSplit["needPro"] = jvOneSplit["otherSideNeedPro"].asBool();
|
|
|
|
|
|
jvOneSplit["needChkDate"] = jvOneSplit["otherSideNeedChkDate"].asBool();
|
|
|
|
|
|
jvOneSplit["needContainer"] = jvOneSplit["otherSideNeedContainer"].asBool();
|
|
|
|
|
|
|
|
|
|
|
|
if (pProcessData->iDataSource == 4 && pProcessData->iDirection == DIRECTION_LEFT)
|
|
|
|
|
|
{
|
|
|
|
|
|
jvOneSplit["splitX"] = jvOneSplit["splitX"].asInt() + 100;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取大框有效方式和车厢间隔坐标
|
|
|
|
|
|
* inParam : N/A
|
|
|
|
|
|
* outParam: N/A
|
|
|
|
|
|
* return : N/A
|
|
|
|
|
|
*/
|
|
|
|
|
|
void DataDealTwoEngine::GetValidTypeAndSplit(Json::Value &jvOneSplit, Json::Value &jvMainSplit,
|
|
|
|
|
|
std::shared_ptr<ProcessData> pProcessData, Json::Value &jvFrameInfo,
|
|
|
|
|
|
std::shared_ptr<TrainRange> pTrainRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pProcessData->iDataSource == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
GetMainSplitInfo(jvMainSplit, pProcessData, jvFrameInfo, pTrainRange);
|
|
|
|
|
|
jvOneSplit = jvMainSplit;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
GetSubSplitInfoByMain(jvOneSplit, pProcessData, jvFrameInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-29 08:16:47 +00:00
|
|
|
|
// LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId
|
|
|
|
|
|
// << " trainIndex:" << pProcessData->iTrainIndex
|
|
|
|
|
|
// << " validType:" << jvOneSplit["validType"].asInt() << " splitX:" << jvOneSplit["splitX"].asInt()
|
|
|
|
|
|
// << " needNum:" << jvOneSplit["needNum"].asBool() << " needPro:" << jvOneSplit["needPro"].asBool()
|
|
|
|
|
|
// << " needChkDate:" << jvOneSplit["needChkDate"].asBool() << " needContainer:" << jvOneSplit["needContainer"].asBool();
|
2024-01-23 02:46:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取大框信息
|
|
|
|
|
|
* inParam : N/A
|
|
|
|
|
|
* outParam: N/A
|
|
|
|
|
|
* return : N/A
|
|
|
|
|
|
*/
|
|
|
|
|
|
int DataDealTwoEngine::GetPostData(std::shared_ptr<ProcessData> pProcessData, Json::Value &jvFrameInfo, Json::Value &jvOneSplit)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::shared_ptr<PostData> pPostData = std::make_shared<PostData>();
|
|
|
|
|
|
pProcessData->pVoidData = std::static_pointer_cast<void>(pPostData);
|
|
|
|
|
|
|
|
|
|
|
|
if (jvOneSplit["needNum"].asBool())
|
|
|
|
|
|
{
|
|
|
|
|
|
GetPostSubDatas(pPostData->vecPostSubData, jvFrameInfo, NUM, jvOneSplit);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (jvOneSplit["needPro"].asBool())
|
|
|
|
|
|
{
|
|
|
|
|
|
GetPostSubDatas(pPostData->vecPostSubData, jvFrameInfo, PRO, jvOneSplit);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (jvOneSplit["needChkDate"].asBool())
|
|
|
|
|
|
{
|
|
|
|
|
|
/*
|
|
|
|
|
|
向右行驶且间隔右边数据有效时,此时画面就1个定检期,画面上的定检期信息全部有效。
|
|
|
|
|
|
向左行驶且间隔左边数据有效时,此时画面就1个定检期,画面上的定检期信息全部有效。
|
|
|
|
|
|
*/
|
|
|
|
|
|
int iValidTypeTemp = jvOneSplit["validType"].asInt();
|
|
|
|
|
|
|
|
|
|
|
|
if ((iValidTypeTemp == VALID_RIGHT && pProcessData->iDataSource == 1 && pProcessData->iDirection == DIRECTION_RIGHT) ||
|
|
|
|
|
|
(iValidTypeTemp == VALID_RIGHT && pProcessData->iDataSource == 4 && pProcessData->iDirection == DIRECTION_LEFT) ||
|
|
|
|
|
|
(iValidTypeTemp == VALID_LEFT && pProcessData->iDataSource == 1 && pProcessData->iDirection == DIRECTION_LEFT) ||
|
|
|
|
|
|
(iValidTypeTemp == VALID_LEFT && pProcessData->iDataSource == 4 && pProcessData->iDirection == DIRECTION_RIGHT))
|
|
|
|
|
|
{
|
|
|
|
|
|
jvOneSplit["validType"] = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
GetPostSubDatas(pPostData->vecPostSubData, jvFrameInfo, CHKDATE, jvOneSplit);
|
|
|
|
|
|
jvOneSplit["validType"] = iValidTypeTemp;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (jvOneSplit["needContainer"].asBool())
|
|
|
|
|
|
{
|
|
|
|
|
|
GetPostSubDatas(pPostData->vecPostSubData, jvFrameInfo, CONTAINER, jvOneSplit);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return pPostData->vecPostSubData.size();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* push数据到队列,队列满时则休眠一段时间再push。
|
|
|
|
|
|
* inParam : const std::string strPort push的端口
|
|
|
|
|
|
: const std::shared_ptr<ProcessData> &pProcessData push的数据
|
|
|
|
|
|
* outParam: N/A
|
|
|
|
|
|
* return : N/A
|
|
|
|
|
|
*/
|
|
|
|
|
|
void DataDealTwoEngine::PushData(const std::string &strPort, const std::shared_ptr<ProcessData> &pProcessData)
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
int iRet = outputQueMap_[strPort]->push(std::static_pointer_cast<void>(pProcessData));
|
|
|
|
|
|
if (iRet != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " push fail iRet:" << iRet;
|
|
|
|
|
|
if (iRet == 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
usleep(10000); // 10ms
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 构造处理数据并push
|
|
|
|
|
|
* inParam : N/A
|
|
|
|
|
|
* outParam: N/A
|
|
|
|
|
|
* return : N/A
|
|
|
|
|
|
*/
|
|
|
|
|
|
void DataDealTwoEngine::MakeProcessData(std::shared_ptr<TrainRange> pTrainRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
int iRet = APP_ERR_OK;
|
|
|
|
|
|
int iDataNO = 1;
|
|
|
|
|
|
|
|
|
|
|
|
std::string strDataDir = strResultPath_ + pTrainRange->strTrainDate + "/" + pTrainRange->strTrainName + "/";
|
|
|
|
|
|
for (int iFrameId = pTrainRange->iStartFrameId; iFrameId <= pTrainRange->iEndFrameId; iFrameId += dataSourceConfig_.iSkipInterval)
|
|
|
|
|
|
{
|
|
|
|
|
|
Json::Value jvMainSplit; //主摄像头车厢间隔坐标信息
|
|
|
|
|
|
int iStatus = TRAINSTATUS_RUN;
|
|
|
|
|
|
int iTagTotalCnt = 0;
|
|
|
|
|
|
for (auto iter = mapUseDataSouceCfg_.begin(); iter != mapUseDataSouceCfg_.end(); iter++)
|
|
|
|
|
|
{
|
|
|
|
|
|
int iSourceId = iter->first;
|
|
|
|
|
|
char szCameraNo[5] = {0};
|
|
|
|
|
|
sprintf(szCameraNo, "%03d/", iSourceId + 1);
|
|
|
|
|
|
bool bIsEndFlag = (pTrainRange->iEndFrameId == iFrameId);
|
|
|
|
|
|
|
2024-02-29 08:16:47 +00:00
|
|
|
|
// LogInfo << "sourceid:" << iSourceId << " StepTwo MakeProcessData trainIndex:" << pTrainRange->iTrainIndex
|
|
|
|
|
|
// << " iFrameId:" << iFrameId << " bIsEndFlag:" << bIsEndFlag;
|
2024-01-23 02:46:26 +00:00
|
|
|
|
std::string strImgName = strDataDir + szCameraNo + std::to_string(iFrameId);
|
|
|
|
|
|
strImgName += (iter->second.iRotate != 0) ? "_rotate.jpg" : ".jpg";
|
|
|
|
|
|
std::string strFileName = strDataDir + szCameraNo + std::to_string(iFrameId) + ".txt";
|
|
|
|
|
|
|
|
|
|
|
|
// 获取大框信息
|
|
|
|
|
|
Json::Value jvFrameInfo;
|
|
|
|
|
|
bool bReadFlag = MyUtils::getins()->ReadJsonInfo(jvFrameInfo, strFileName, 0);
|
|
|
|
|
|
if (!bIsEndFlag && !bReadFlag)
|
|
|
|
|
|
{
|
|
|
|
|
|
//非车厢结束帧且没有txt信息时不处理。
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
iStatus = (iSourceId == 0 ? jvFrameInfo["status"].asInt() : iStatus);
|
|
|
|
|
|
|
|
|
|
|
|
// 构造处理数据信息
|
|
|
|
|
|
std::shared_ptr<ProcessData> pProcessData = std::make_shared<ProcessData>();
|
|
|
|
|
|
pProcessData->iDataSource = iSourceId;
|
|
|
|
|
|
pProcessData->iFrameId = iFrameId;
|
|
|
|
|
|
pProcessData->strTrainDate = pTrainRange->strTrainDate;
|
|
|
|
|
|
pProcessData->strTrainName = pTrainRange->strTrainName;
|
|
|
|
|
|
pProcessData->bIsEnd = bIsEndFlag;
|
|
|
|
|
|
pProcessData->iStatus = iStatus;
|
|
|
|
|
|
pProcessData->iDirection = iDirection_;
|
|
|
|
|
|
pProcessData->iDataNO = iDataNO;
|
|
|
|
|
|
pProcessData->iTrainIndex = pTrainRange->iTrainIndex;
|
|
|
|
|
|
pProcessData->bIsTrainEnd = pTrainRange->bIsEnd;
|
|
|
|
|
|
pProcessData->strPicFilePath = strImgName;
|
|
|
|
|
|
pProcessData->i64TimeStamp = jvFrameInfo["timeStamp"].asUInt64();
|
|
|
|
|
|
pProcessData->iWidth = jvFrameInfo["width"].asInt();
|
|
|
|
|
|
pProcessData->iHeight = jvFrameInfo["height"].asInt();
|
|
|
|
|
|
|
|
|
|
|
|
Json::Value jvOneSplit;
|
|
|
|
|
|
jvOneSplit = jvMainSplit;
|
|
|
|
|
|
jvOneSplit["rotate"] = iter->second.iRotate;
|
|
|
|
|
|
GetValidTypeAndSplit(jvOneSplit, jvMainSplit, pProcessData, jvFrameInfo, pTrainRange);
|
|
|
|
|
|
|
|
|
|
|
|
// 获取有效的大框信息
|
|
|
|
|
|
int iRetCnt = GetPostData(pProcessData, jvFrameInfo, jvOneSplit);
|
|
|
|
|
|
iTagTotalCnt += iRetCnt;
|
|
|
|
|
|
|
|
|
|
|
|
if (iRetCnt > 0 && iStatus == TRAINSTATUS_RUN)
|
|
|
|
|
|
{
|
|
|
|
|
|
cv::Mat cvframe = cv::imread(pProcessData->strPicFilePath);
|
|
|
|
|
|
int iBufferSize = pProcessData->iWidth * pProcessData->iHeight * 3;
|
|
|
|
|
|
void *pBGRBufferobj = nullptr;
|
|
|
|
|
|
pBGRBufferobj = new uint8_t[iBufferSize];
|
|
|
|
|
|
memcpy(pBGRBufferobj, cvframe.data, iBufferSize);
|
|
|
|
|
|
pProcessData->pData.reset(pBGRBufferobj, [](void *data){if(data) {delete[] data; data = nullptr;}});
|
|
|
|
|
|
pProcessData->iSize = iBufferSize;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> vecPushPorts = mapSourcePushPort_[iSourceId];
|
|
|
|
|
|
for (int iPort = 0; iPort < vecPushPorts.size(); iPort++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (iPort == vecPushPorts.size() - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
//iRet = outputQueMap_[vecPushPorts[iPort]]->push(std::static_pointer_cast<void>(pProcessData), true);
|
|
|
|
|
|
PushData(vecPushPorts[iPort], pProcessData);
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
std::shared_ptr<ProcessData> pNewProcessData = std::make_shared<ProcessData>();
|
|
|
|
|
|
*pNewProcessData = *pProcessData;
|
|
|
|
|
|
//iRet = outputQueMap_[vecPushPorts[iPort]]->push(std::static_pointer_cast<void>(pNewProcessData), true);
|
|
|
|
|
|
PushData(vecPushPorts[iPort], pNewProcessData);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
iDataNO++;
|
|
|
|
|
|
//每组处理数据需间隔一定时间 (运行状态且有第一步结果需休眠,否则直接处理后面的数据)
|
|
|
|
|
|
if (iStatus == TRAINSTATUS_RUN && iTagTotalCnt != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
usleep(iIntervalTime_);
|
|
|
|
|
|
}
|
|
|
|
|
|
while (g_bNoDealStepTwoFlag)
|
|
|
|
|
|
{
|
|
|
|
|
|
usleep(iIntervalTime_);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
APP_ERROR DataDealTwoEngine::Process()
|
|
|
|
|
|
{
|
|
|
|
|
|
int iRet = APP_ERR_OK;
|
|
|
|
|
|
while (!isStop_)
|
|
|
|
|
|
{
|
|
|
|
|
|
//获取主摄像头车厢划分结果
|
|
|
|
|
|
std::shared_ptr<void> pVoidData0 = nullptr;
|
|
|
|
|
|
iRet = inputQueMap_[strPort0_]->pop(pVoidData0);
|
|
|
|
|
|
if (nullptr == pVoidData0)
|
|
|
|
|
|
{
|
|
|
|
|
|
usleep(1000); // 1ms
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<TrainRange> pTrainRange = std::static_pointer_cast<TrainRange>(pVoidData0);
|
|
|
|
|
|
LogInfo << "step2 start traindate:" << pTrainRange->strTrainDate << " trainname:" << pTrainRange->strTrainName
|
|
|
|
|
|
<< " trainindex:" << pTrainRange->iTrainIndex << " startframeid:" << pTrainRange->iStartFrameId
|
|
|
|
|
|
<< " endframeid:" << pTrainRange->iEndFrameId << " isEnd:" << pTrainRange->bIsEnd;
|
|
|
|
|
|
|
|
|
|
|
|
if (iDirection_ == DIRECTION_UNKNOWN)
|
|
|
|
|
|
{
|
|
|
|
|
|
/*获取该车辆行驶方向
|
|
|
|
|
|
特殊场景:车头行驶画面一半后停止,再次反方向驶出画面。再次行驶得场景不会有方向.(因没有大框无法计算方向)
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::string strFilePath = strResultPath_ + pTrainRange->strTrainDate + "/" + pTrainRange->strTrainName + "/" + "direction.txt";
|
|
|
|
|
|
int iCnt = 0;
|
|
|
|
|
|
while (!isStop_ && iCnt < 10)
|
|
|
|
|
|
{
|
|
|
|
|
|
Json::Value jvDirectionInfo;
|
|
|
|
|
|
if (MyUtils::getins()->ReadJsonInfo(jvDirectionInfo, strFilePath))
|
|
|
|
|
|
{
|
|
|
|
|
|
iDirection_ = jvDirectionInfo["direction"].asInt();
|
|
|
|
|
|
//按行驶方向获取车号在前还是属性在前
|
|
|
|
|
|
if (iDirectionAndFirst_ == DO_NOT_KNOW_DIRECTION && iDirection_ != DIRECTION_UNKNOWN)
|
|
|
|
|
|
{
|
|
|
|
|
|
iDirectionAndFirst_ = iDirection_ == DIRECTION_LEFT ? dataSourceConfig_.iLeftFirst : dataSourceConfig_.iRightFirst;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
usleep(500 * 1000); // 500ms
|
|
|
|
|
|
iCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*重置开始帧,结束帧
|
|
|
|
|
|
开始帧向上取跳帧的倍数,结束帧向下取跳帧的倍数
|
|
|
|
|
|
例: 车厢开始帧结束帧[50, 125],则推理的开始帧结束帧为[52, 124]
|
|
|
|
|
|
*/
|
|
|
|
|
|
int iSkipInterval = dataSourceConfig_.iSkipInterval;
|
|
|
|
|
|
pTrainRange->iStartFrameId = (pTrainRange->iStartFrameId + iSkipInterval - 1) / iSkipInterval * iSkipInterval;
|
|
|
|
|
|
pTrainRange->iEndFrameId = pTrainRange->iEndFrameId / iSkipInterval * iSkipInterval;
|
|
|
|
|
|
if (pTrainRange->iStartFrameId > pTrainRange->iEndFrameId)
|
|
|
|
|
|
{
|
|
|
|
|
|
pTrainRange->iStartFrameId = pTrainRange->iEndFrameId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//判断第一步是否处理完毕
|
|
|
|
|
|
char szCameraNo[5] = {0};
|
|
|
|
|
|
sprintf(szCameraNo, "%03d/", engineId_ + 1);
|
|
|
|
|
|
std::string strFilePath = strResultPath_ + pTrainRange->strTrainDate + "/" + pTrainRange->strTrainName + "/" +
|
|
|
|
|
|
szCameraNo + std::to_string(pTrainRange->iEndFrameId) + ".txt";
|
|
|
|
|
|
|
|
|
|
|
|
int iReadCnt = 0;
|
|
|
|
|
|
bool bRet = false;
|
|
|
|
|
|
while (!isStop_ && iReadCnt < 30)
|
|
|
|
|
|
{
|
|
|
|
|
|
Json::Value jvFrameInfo;
|
|
|
|
|
|
bRet = MyUtils::getins()->ReadJsonInfo(jvFrameInfo, strFilePath);
|
|
|
|
|
|
if (jvFrameInfo["step1Finish"].asBool())
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
usleep(500 * 1000); // 500ms
|
|
|
|
|
|
iReadCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//处理当车厢的每帧信息
|
|
|
|
|
|
MakeProcessData(pTrainRange);
|
|
|
|
|
|
// push结果汇总
|
|
|
|
|
|
iRet = outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_9"]->push(std::static_pointer_cast<void>(pTrainRange));
|
|
|
|
|
|
|
|
|
|
|
|
iTrainIndex_++;
|
|
|
|
|
|
if (pTrainRange->bIsEnd)
|
|
|
|
|
|
{
|
|
|
|
|
|
InitParam();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return APP_ERR_OK;
|
|
|
|
|
|
}
|