#include "MoveEngine.h" #include #include "myqueue.h" using namespace ai_matrix; MoveEngine::MoveEngine() {} MoveEngine::~MoveEngine() {} APP_ERROR MoveEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; this->modelConfig_ = Config::getins()->getModelByMoveConfig(); this->identifyConfig_ = Config::getins()->getIdentifyConfig(); this->baseConfig_ = Config::getins()->getBaseConfig(); this->dataSourceConfig_ = Config::getins()->getDataSourceConfig(); if (identifyConfig_.bNeedMoveDetectFlag) { // 读取模型信息 APP_ERROR ret = ReadModelInfo(); if (ret != APP_ERR_OK) { LogError << "Failed to read model info, ret = " << ret; return ret; } ret = InitModel(); if (ret != APP_ERR_OK) { LogError << "Failed to read model info, ret = " << ret; return ret; } } InitParam(); LogInfo << "MoveEngine Init ok"; return APP_ERR_OK; } APP_ERROR MoveEngine::InitModel() { modelinfo.modelCommonInfo.uiModelWidth = model_width; modelinfo.modelCommonInfo.uiModelHeight = model_height; modelinfo.modelCommonInfo.uiInputSize = input_size; modelinfo.modelCommonInfo.uiOutputSize = output_size; modelinfo.modelCommonInfo.uiChannel = INPUT_CHANNEL; modelinfo.modelCommonInfo.uiBatchSize = batch_size; modelinfo.modelCommonInfo.strInputBlobName = INPUT_BLOB_NAME; modelinfo.modelCommonInfo.strOutputBlobName = OUTPUT_BLOB_NAME; string strModelName = ""; int nRet = yolov8model.YoloV8InferenceInit(&modelinfo, strModelName, modelConfig_.strModelPath); if (nRet != 0) { LogInfo << "YoloV5ClassifyInferenceInit nRet:" << nRet; return APP_ERR_COMM_READ_FAIL; } return APP_ERR_OK; } APP_ERROR MoveEngine::ReadModelInfo() { int iFolderExist = access(modelConfig_.strModelPath.c_str(), R_OK); if (iFolderExist == -1) { LogError << "ModelPath " << modelConfig_.strModelPath << " doesn't exist or read failed!"; return APP_ERR_COMM_NO_EXIST; } return APP_ERR_OK; } APP_ERROR MoveEngine::DeInit() { if (identifyConfig_.bNeedMoveDetectFlag) { yolov8model.YoloV8InferenceDeinit(); } LogInfo << "MoveEngine DeInit ok"; return APP_ERR_OK; } /** * 参数初始化(列车结束时需调用) * inParam : N/A * outParam: N/A * return : N/A */ void MoveEngine::InitParam() { this->iStepInter_ = 0; for (auto & map_it : this->mapMoveDataNO_) { map_it.second = 1; } this->strTrainTime_ = ""; this->strTrainName_ = ""; this->strTrainDate_ = ""; for (bool & value : this->bHaveTrain_) { value = false; } } bool MoveEngine::getIsHaveTrain() { for (const bool & type : this->bHaveTrain_) { if (type) return true; } // for (int i = 0; i < 2; ++i) // { // if (g_bHaveTrain[i].load()) return true; // } return false; } bool MoveEngine::isNewTrain() { bool bIsNew = true; for (auto & map_it : this->mapMoveDataNO_) { if (map_it.second != 1) bIsNew = false; } return bIsNew; } /** * 使用单device处理 * inParam : std::shared_ptr pProcessData * outParam: N/A * return : N/A */ void MoveEngine::SingleDeviceProcess(std::shared_ptr pProcessData, int iType) { if(this->isNewTrain() || strTrainDate_.empty()) { this->strTrainDate_ = TimeUtil::getins()->getDate(); this->strTrainTime_ = TimeUtil::getins()->getTime(); this->strTrainName_ = StringUtil::getins()->replace_all_distinct(strTrainTime_, ":", "-"); //创建该该列车的数据存储目录(防止后续多线程创建报错) std::string strTrainPath = baseConfig_.strDebugResultPath + "/" + strTrainDate_ + "/" + this->strTrainName_ + "/jpg_0"; FileUtil::getins()->createDirPath(strTrainPath); //创建该该列车的数据存储目录(防止后续多线程创建报错) std::string strTrainPath2 = baseConfig_.strDebugResultPath + "/" + strTrainDate_ + "/" + this->strTrainName_ + "/jpg_1"; FileUtil::getins()->createDirPath(strTrainPath2); std::string strBestImgPath = baseConfig_.strResultPath + "/" + strTrainDate_ + "/" + this->strTrainName_; FileUtil::getins()->createDirPath(strBestImgPath); } // if (g_come_direction != 0 && (g_come_direction != this->dataSourceConfig_.iDirection && this->dataSourceConfig_.iDirection)) // { // pProcessData->bIsTrainEnd = true; // } // if (pProcessData->bIsTrainEnd && this->isNewTrain()) // { // return; // } std::string strFilePath = baseConfig_.strDebugResultPath + "/" + strTrainDate_ + "/" + strTrainName_ + "/jpg_" + std::to_string(pProcessData->iDataSource); // 通知存储来车检测结果 std::shared_ptr pVMoveInfo = std::make_shared(); pVMoveInfo->iDataSource = pProcessData->iDataSource; pVMoveInfo->strFilePath = strFilePath; pVMoveInfo->strFileName = std::to_string(this->mapMoveDataNO_[pProcessData->iDataSource]) + ".json"; pVMoveInfo->iFrameId = this->mapMoveDataNO_[pProcessData->iDataSource]; //当前帧号 pVMoveInfo->i64TimeStamp = pProcessData->sourceFrameData.i64TimeStamp; pVMoveInfo->bIsEnd = pProcessData->bIsTrainEnd; pVMoveInfo->strTrainDate = strTrainDate_; pVMoveInfo->strTrainTime = strTrainTime_; pVMoveInfo->strTrainName = strTrainName_; pVMoveInfo->iTrainStage = iType; outputQueMap_[strPort1_]->push(std::static_pointer_cast(pVMoveInfo), true); // push端口,存图 std::shared_ptr pSaveImgData = std::make_shared(); pSaveImgData->iDataSource = pProcessData->iDataSource; pSaveImgData->strFilePath = strFilePath; pSaveImgData->strFileName = std::to_string(this->mapMoveDataNO_[pProcessData->iDataSource]) + ".jpg"; pSaveImgData->strTrainStage = this->intTrainStage_2_str(iType); pSaveImgData->frameData.pData = pProcessData->sourceFrameData.pData; pSaveImgData->frameData.iSize = pProcessData->sourceFrameData.iSize; pSaveImgData->frameData.iWidth = pProcessData->dataSourceInfo.iWidth; pSaveImgData->frameData.iHeight = pProcessData->dataSourceInfo.iHeight; pSaveImgData->frameData.i64TimeStamp = pProcessData->sourceFrameData.i64TimeStamp; pSaveImgData->bIsEnd = pProcessData->bIsTrainEnd; outputQueMap_[strPort0_]->push(std::static_pointer_cast(pSaveImgData), true); if (pProcessData->bIsTrainEnd) { std::shared_ptr pSaveImgData2 = std::make_shared(); pSaveImgData2->iDataSource = pProcessData->iDataSource == 0 ? 1: 0; pSaveImgData2->strFileName = std::to_string(this->mapMoveDataNO_[pSaveImgData2->iDataSource]-1) + ".jpg"; pSaveImgData2->strFilePath = baseConfig_.strDebugResultPath + "/" + strTrainDate_ + "/" + strTrainName_ + "/jpg_" + std::to_string(pSaveImgData2->iDataSource); pSaveImgData2->bIsEnd = pProcessData->bIsTrainEnd; outputQueMap_[strPort0_]->push(std::static_pointer_cast(pSaveImgData2), true); LogInfo << "---> 火车结束信号 数据源:" << pSaveImgData2->iDataSource << " 帧:" << this->mapMoveDataNO_[pSaveImgData2->iDataSource]; LogInfo << "---> 火车结束信号 数据源:" << pProcessData->iDataSource << " 帧:" << this->mapMoveDataNO_[pProcessData->iDataSource]; this->InitParam(); } } std::string MoveEngine::intTrainStage_2_str(int iTrainStage) { switch (iTrainStage) { case MONITOR_MODEL_TRAIN_HEAD: return "train_head"; case MONITOR_MODEL_HEAD_FIRST: return "head_and_carriage"; case MONITOR_MODEL_NO_TRAIN: return "no_train"; case MONITOR_MODEL_TRAIN_TAIL: return "train_tail"; case MONITOR_MODEL_TRAIN_BODY: return "carriage"; default: return ""; } } APP_ERROR MoveEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { //pop端口0 std::shared_ptr pVoidData0 = nullptr; inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr == pVoidData0) { usleep(1000); //1ms continue; } std::shared_ptr pProcessData = std::static_pointer_cast(pVoidData0); // int iType = MONITOR_MODEL_INIT_STATE; //1. 无需动态检测 if (!this->identifyConfig_.bNeedMoveDetectFlag) { SingleDeviceProcess(pProcessData, MONITOR_MODEL_INIT_STATE); this->mapMoveDataNO_[pProcessData->iDataSource]++; if (pProcessData->bIsTrainEnd) { InitParam(); } continue; } // 进行推理 if (!pProcessData->sourceFrameData.pData || !pProcessData->sourceFrameData.iSize) { continue; } if (this->getIsHaveTrain() && !this->mapMoveDataNO_[pProcessData->iDataSource] % 2) { SingleDeviceProcess(pProcessData, iType[pProcessData->iDataSource]); this->mapMoveDataNO_[pProcessData->iDataSource]++; continue; } cv::Mat img; // BGR cv::Mat img_gray(pProcessData->dataSourceInfo.iHeight, pProcessData->dataSourceInfo.iWidth, CV_8UC1); cvtColor(cv::Mat(pProcessData->dataSourceInfo.iHeight, pProcessData->dataSourceInfo.iWidth, CV_8UC3, static_cast(pProcessData->sourceFrameData.pData.get())), img_gray, COLOR_BGR2GRAY); cvtColor(img_gray, img, COLOR_GRAY2BGR); auto start = std::chrono::system_clock::now(); // 计时开始 float fReturnVal[STEP0_OUTPUT_ARRAY]; memset(fReturnVal, 0x00, sizeof(fReturnVal)); yolov8model.YoloV8InferenceModelGetType(img, fReturnVal, STEP0_OUTPUT_ARRAY * sizeof(float)); // exit(0); float fScore = 0.0f; for(int n = 0; n < STEP0_OUTPUT_ARRAY; n++){ if(fReturnVal[n] > fScore){ fScore = fReturnVal[n]; iType[pProcessData->iDataSource] = n; } } // LogDebug <<"模型得分 车头:"<< fReturnVal[0]<<" 无车:"<< fReturnVal[1]<<" 车尾:"<< fReturnVal[2]<<" 有车:"<< fReturnVal[3]; // LogInfo<<"来车当前状态:"<< (nType == 0 ? "有车头" : (nType == 1 ? "无车")); switch (iType[pProcessData->iDataSource]) { case MONITOR_MODEL_INIT_STATE: LogDebug << "数据源:" << pProcessData->iDataSource << " 来车检测初始状态"; break; case MONITOR_MODEL_TRAIN_HEAD: LogDebug << "数据源:" << pProcessData->iDataSource << " 来车状态:有车头"; break; case MONITOR_MODEL_HEAD_FIRST: LogDebug << "数据源:" << pProcessData->iDataSource << " 来车状态:车头与车身之间"; case MONITOR_MODEL_NO_TRAIN: // LogDebug << "来车状态:无车"; break; case MONITOR_MODEL_TRAIN_TAIL: LogDebug << "数据源:" << pProcessData->iDataSource << " 来车状态:车尾"; break; case MONITOR_MODEL_TRAIN_BODY: LogDebug << "数据源:" << pProcessData->iDataSource << " 来车状态:车身"; break; default: LogWarn << "数据源:" << pProcessData->iDataSource << " 来车状态:未定义状态"; break; } if (this->identifyConfig_.bTrainHeardDetect) { this->bHaveTrain_[pProcessData->iDataSource] = (iType[pProcessData->iDataSource] == MONITOR_MODEL_TRAIN_BODY || iType[pProcessData->iDataSource] == MONITOR_MODEL_TRAIN_HEAD || iType[pProcessData->iDataSource] == MONITOR_MODEL_HEAD_FIRST || iType[pProcessData->iDataSource] == MONITOR_MODEL_TRAIN_TAIL); // g_bHaveTrain[pProcessData->iDataSource].store(iType == MONITOR_MODEL_TRAIN_BODY // || iType == MONITOR_MODEL_TRAIN_HEAD // || iType == MONITOR_MODEL_HEAD_FIRST // || iType == MONITOR_MODEL_TRAIN_TAIL); } else { this->bHaveTrain_[pProcessData->iDataSource] = (iType[pProcessData->iDataSource] == MONITOR_MODEL_TRAIN_BODY || iType[pProcessData->iDataSource] == MONITOR_MODEL_TRAIN_TAIL || iType[pProcessData->iDataSource] == MONITOR_MODEL_HEAD_FIRST); // g_bHaveTrain[pProcessData->iDataSource].store(iType == MONITOR_MODEL_TRAIN_BODY // || iType == MONITOR_MODEL_TRAIN_TAIL // || iType == MONITOR_MODEL_HEAD_FIRST); } auto end = std::chrono::system_clock::now(); uint64_t i64Time = std::chrono::duration_cast(end - start).count(); if (getIsHaveTrain()) { iHasTrainNum_ = iHasTrainNum_ > 20 ? iHasTrainNum_ : iHasTrainNum_ + 1; // if (iHasTrainNum_ > 0) LogInfo << "数据源:" << pProcessData->iDataSource << "当前有车, 计数:" << iHasTrainNum_; } else { iHasTrainNum_ = iHasTrainNum_ == 0 ? iHasTrainNum_ : iHasTrainNum_ - 1; if (iHasTrainNum_ == 0) LogInfo << "数据源:" << pProcessData->iDataSource << " ----- 当前无车 -----"; } if (iHasTrainNum_ > 0) //有车开始识别 { iStepInter_ = 1; } else //无车停止识别 { if (iStepInter_ == 1) { iStepInter_ = 2; } } //有车识别处理 if (iStepInter_ != 0) { pProcessData->bIsTrainEnd = (iStepInter_ == 2); //动态检测无车,设置列车结束标识 SingleDeviceProcess(pProcessData, iType[pProcessData->iDataSource]); this->mapMoveDataNO_[pProcessData->iDataSource]++; if (iStepInter_ == 2) { InitParam(); } } } return APP_ERR_OK; }