#include "TrainParationMgr.h" using namespace ai_matrix; TrainParationMgr::TrainParationMgr() {} TrainParationMgr::~TrainParationMgr() {} APP_ERROR TrainParationMgr::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path"); //获取主摄像头信息 mainCfg_ = MyYaml::GetIns()->GetDataSourceConfigById(0); nFrameRate = 25; InitParam(); nTailPixOffset = getTailPixOffset(); LogInfo << "TrainParationMgr Init ok"; return APP_ERR_OK; } APP_ERROR TrainParationMgr::DeInit() { LogInfo << "TrainParationMgr DeInit ok"; return APP_ERR_OK; } int TrainParationMgr::getTailPixOffset() { LogInfo << "TrainParationMgr getTailPixOffset start"; // 单位计算 // 帧宽像素/米 float fframewidth_meter = ((METHOD_BASE_WIDTH * 1.0) / (TRAIN_IN_CAMERA_WIDTH)); // 车尾车钩像素位置 float fOffsetPosistion = TRAIN_WIDTH * fframewidth_meter; int nretOffset = (int)fOffsetPosistion; return nretOffset; } /** * 参数初始化(列车结束时需调用) * inParam : N/A * outParam: N/A * return : N/A */ void TrainParationMgr::InitParam() { } /** * 计算车钩移动的像素值 * inParam : 行车速度(单位:米/秒) * inParam : 宽度 * inParam : 相机帧率(单位:帧/秒) * outParam: N/A * return : 间隔帧 */ int TrainParationMgr::getCouplerOffsetPosition(float fspeed, int nframeindex) { LogInfo << "TrainAnaEngine getCouplerOffsetPosition start"; //单位换算 // 米/秒 -> 米/帧 // 米/帧 = 米/秒 * 秒/帧(即:1/帧率) float fmeter_frame = fspeed / nFrameRate; // 米/帧 -> 像素/帧 // 像素/帧 = 米/帧 * 像素/米 float fpix_frame = fmeter_frame * (METHOD_BASE_WIDTH / TRAIN_IN_CAMERA_WIDTH); int nretPixOffet = (int)fpix_frame; nretPixOffet = nretPixOffet * nframeindex; LogInfo << "TrainAnaEngine getCouplerOffsetPosition nretPixOffet:" << nretPixOffet; LogInfo << "TrainAnaEngine getCouplerOffsetPosition end"; return nretPixOffet; } /** * 计算车钩移动的像素值 * inParam : 行车速度(单位:米/秒) * inParam : 宽度 * inParam : 相机帧率(单位:帧/秒) * outParam: N/A * return : 间隔帧 */ int TrainParationMgr::getCouplerOffsetPix(float fspeed, int noffsetPix) { LogInfo << "TrainAnaEngine getCouplerOffsetPix start"; LogInfo << "TrainAnaEngine getCouplerOffsetPix fspeed:" << fspeed; // LogInfo << "TrainAnaEngine getCouplerOffsetPix start:" << nframeindex; //单位换算 // 米/秒 -> 米/帧 // 米/帧 = 米/秒 * 秒/帧(即:1/帧率) float fmeter_frame = fspeed / nFrameRate; LogInfo << "TrainAnaEngine getCouplerOffsetPix fmeter_frame:" << fmeter_frame; // 米/帧 -> 像素/帧 // 像素/帧 = 米/帧 * 像素/米 float fpix_frame = fmeter_frame * (METHOD_BASE_WIDTH / TRAIN_IN_CAMERA_WIDTH); LogInfo << "TrainAnaEngine getCouplerOffsetPix fpix_frame:" << fpix_frame; int nretPixOffet = (int)fpix_frame; nretPixOffet = (noffsetPix - (METHOD_BASE_WIDTH / 2)) / nretPixOffet; LogInfo << "TrainAnaEngine getCouplerOffsetPix nretPixOffet:" << nretPixOffet; LogInfo << "TrainAnaEngine getCouplerOffsetPix end"; return nretPixOffet; } /** * 计算车钩从中间到边缘的间隔帧 * inParam : 行车速度(单位:米/秒) * inParam : 宽度 * inParam : 相机帧率(单位:帧/秒) * outParam: N/A * return : 间隔帧 */ int TrainParationMgr::getOffsetFrame(float fspeed, int width, int nFrameRate) { LogInfo << "TrainAnaEngine getOffsetFrame start"; LogInfo << "TrainAnaEngine getOffsetFrame fspeed:" << fspeed; LogInfo << "TrainAnaEngine getOffsetFrame width:" << width; LogInfo << "TrainAnaEngine getOffsetFrame nFrameRate:" << nFrameRate; //LogInfo << "TrainAnaEngine getOffsetFrame nLatestFrame:" << nLatestFrame; //偏移值 = (中间到边缘的宽度(米) / 速度(米/秒)->时间(秒))* 帧率(帧/秒) float ftmp = width * (float) nFrameRate; LogInfo << "TrainAnaEngine getOffsetFrame start end:" << ftmp; ftmp = ftmp / fspeed; LogInfo << "TrainAnaEngine getOffsetFrame start end:" << ftmp; int nRet = (int) ftmp; LogInfo << "TrainAnaEngine getOffsetFrame start end:" << nRet; return nRet; } APP_ERROR TrainParationMgr::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 pPartionInfo = std::static_pointer_cast(pVoidData0); int nSize = lstPartInfo.size(); int nPartionIndex = nSize - 1; //当然车厢通过的数量 if (nSize == 0) { PartionInfo stTempInfo; stTempInfo.endframe = pPartionInfo->modelSpaceFrame; stTempInfo.i64EndTimeStamp = pPartionInfo->i64EndTimeStamp; stTempInfo.nindex = 1; //第一节车厢开始帧为跳帧数,开始帧时间设置为来车时间 stTempInfo.startframe = mainCfg_.iSkipInterval; std::string strTemp = pPartionInfo->strTrainDate + " " + pPartionInfo->strTrainName; stTempInfo.i64StartTimeStamp = MyUtils::getins()->GetParamTimeMilliSeconds(strTemp); stTempInfo.fspeed = TRAIN_DEFAULT_SPEED; stTempInfo.fLTX = (abs(pPartionInfo->fLTX - pPartionInfo->fRBX) / 2) + pPartionInfo->fLTX; lstPartInfo.push_back(stTempInfo); //lstPartInfo.push_back(stTempInfo); nPartionIndex++; } lstPartInfo[nPartionIndex].i64EndTimeStamp = pPartionInfo->i64EndTimeStamp; lstPartInfo[nPartionIndex].endframe = pPartionInfo->modelSpaceFrame; // 根据开始帧时间戳和结束帧时间错 计算当节车厢的行车速度 // 根据时间戳计算时间差 float nTimePassed = (abs(lstPartInfo[nPartionIndex].i64EndTimeStamp - lstPartInfo[nPartionIndex].i64StartTimeStamp)) * 1.0; //防止停车导致速度过小 if(pPartionInfo->nStatus != TRAIN_PAUSE && nTimePassed <= 50000) { lstPartInfo[nPartionIndex].fspeed = (TRAIN_WIDTH * 1000.0) /nTimePassed; } else { if (nPartionIndex >= 1){ lstPartInfo[nPartionIndex].fspeed = lstPartInfo[nPartionIndex - 1].fspeed / 3; } else { lstPartInfo[nPartionIndex].fspeed = TRAIN_DEFAULT_SPEED / 10; } } // //nSamePartionIgnoreCount = (nTimePassed / (3 * 5000)) * nFrameRate; // 结束帧为当前帧再往后 (除以2的原因:中间为车钩,车钩后的车体宽度为整个镜头的宽度除以2) lstPartInfo[nPartionIndex].bmodelconfirmed = true; /// write json info to file //先读取文本内容,追加新的信息后再写入 //划分信息 JSON格式 Json::Value jvPartionInfo; //JSON保存路径 std::string strFilePath; //检测到车厢划分信息 strFilePath = strResultPath_ + pPartionInfo->strTrainDate + "/" + pPartionInfo->strTrainName + "/" + std::to_string(nPartionIndex + 1) + ".txt"; LogInfo << "TrainAnaEngine Process lstPartInfo[nPartionIndex].startframe:" << lstPartInfo[nPartionIndex].startframe ; LogInfo << "TrainAnaEngine Process lstPartInfo[nPartionIndex].endframe:" << lstPartInfo[nPartionIndex].endframe; PartionInfo stTempInfo; // 开始记录新的一节车厢信息(从索引变成序号+1 ,新增一节车厢信息+1) stTempInfo.nindex = nPartionIndex + 2; // 上一节车厢的结束帧 - (偏移帧 = (镜头内的车体宽度/ (速度) -> 通过时间) * 帧/秒 ) 作为下一节车厢的开始帧 int ntempOffsetFrame = lstPartInfo[nPartionIndex].endframe; stTempInfo.startframe = ntempOffsetFrame; stTempInfo.i64StartTimeStamp = pPartionInfo->i64EndTimeStamp; // 初始化下一节的结束帧 //stTempInfo.endframe = 0; lstPartInfo.push_back(stTempInfo); // 记录过车日期 jvPartionInfo["trainDate"] = pPartionInfo->strTrainDate; // 记录过车时间 jvPartionInfo["trainName"] = pPartionInfo->strTrainName; // 记录车厢节数 (索引从0开始 所以这里+1) jvPartionInfo["trainNo"] = nPartionIndex + 1; // 记录行车开始帧 jvPartionInfo["startFrameId"] = lstPartInfo[nPartionIndex].startframe; jvPartionInfo["startTimeStamp"] = lstPartInfo[nPartionIndex].i64StartTimeStamp; // 记录行车结束帧 jvPartionInfo["endFrameId"] = lstPartInfo[nPartionIndex].endframe; jvPartionInfo["endTimeStamp"] = lstPartInfo[nPartionIndex].i64EndTimeStamp; // 记录车厢是否完全通过 jvPartionInfo["isEnd"] = pPartionInfo->bIsEnd; //是否是间隔模型切分的车厢 jvPartionInfo["modelconfirmed"] = pPartionInfo->bmodelconfirmed; // 记录当前车厢的信息到JSON文件 MyUtils::getins()->WriteJsonInfo(jvPartionInfo, strFilePath); std::shared_ptr pTrainRange = std::make_shared(); pTrainRange->strTrainDate = jvPartionInfo["trainDate"].asString(); pTrainRange->strTrainName = jvPartionInfo["trainName"].asString(); pTrainRange->iTrainIndex = jvPartionInfo["trainNo"].asInt(); pTrainRange->iStartFrameId = jvPartionInfo["startFrameId"].asInt(); pTrainRange->i64StartTimeStamp = jvPartionInfo["startTimeStamp"].asInt64(); pTrainRange->iEndFrameId = jvPartionInfo["endFrameId"].asInt(); pTrainRange->i64EndTimeStamp = jvPartionInfo["endTimeStamp"].asInt64(); pTrainRange->bIsEnd = jvPartionInfo["isEnd"].asBool(); pTrainRange->bmodelconfirmed = jvPartionInfo["modelconfirmed"].asBool(); iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast(pTrainRange), true); if (pPartionInfo->bIsEnd) { lstPartInfo.clear(); } } return APP_ERR_OK; }