From bcc5f6bcd4ddea445b65b390f89d127a55b3b763 Mon Sep 17 00:00:00 2001 From: "Mr.V" Date: Wed, 18 Dec 2024 15:33:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=83=8F=E7=B4=A0=E5=88=87?= =?UTF-8?q?=E5=88=86=E4=B8=AD=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ai_matrix/Config/Config.cpp | 2 + ai_matrix/Config/Config.h | 4 + app/config/config.yaml | 78 ++++++++++++------- app/config/matrix.yaml | 70 ++++++++++------- app/config/model_config.yaml | 12 ++- common/CommonStruct.h | 18 +++++ config/config.yaml | 4 + config/matrix.yaml | 2 +- .../ContainerCharacterConversionEngine.cpp | 2 +- engine/ControlEngine/ControlEngine.cpp | 14 ++-- engine/DataUploadEngine/ToMinioSrvEngine.cpp | 2 +- .../ContainerDivideEngine.cpp | 2 +- engine/MergeEngine/Step1MergeEngine.cpp | 2 +- .../SaveDebugImageEngine.cpp | 19 ++--- .../SaveDebugImageEngine.h | 2 +- engine/SelectBestEngine/SelectBestEngine.cpp | 57 +++++++++++--- .../ContainerStep1InferenceEngine.cpp | 5 +- .../ContainerStep2InferenceEngine.cpp | 2 +- 18 files changed, 203 insertions(+), 94 deletions(-) diff --git a/ai_matrix/Config/Config.cpp b/ai_matrix/Config/Config.cpp index e78d867..ae4e5b7 100644 --- a/ai_matrix/Config/Config.cpp +++ b/ai_matrix/Config/Config.cpp @@ -70,6 +70,8 @@ namespace ai_matrix this->identifyConfig_.iTargetMinWidth = config_["identify"]["target_min_width"].as(); this->identifyConfig_.iTargetMinY = config_["identify"]["target_min_y"].as(); this->identifyConfig_.iMaxIdentifyFrame = config_["identify"]["max_identify_frame"].as(); + this->identifyConfig_.iMaxContainerSpaceX = config_["identify"]["max_container_space_x"].as(); + this->identifyConfig_.iMaxContainerSpaceY = config_["identify"]["max_container_space_y"].as(); // websocket server 服务端参数 this->wSocketConfig_.bIsUse = config_["wsocket_server"]["is_use"].as(); diff --git a/ai_matrix/Config/Config.h b/ai_matrix/Config/Config.h index 0f6858c..c662e15 100644 --- a/ai_matrix/Config/Config.h +++ b/ai_matrix/Config/Config.h @@ -88,6 +88,10 @@ namespace ai_matrix int iTargetMinY; // 单次识别最大帧数 int iMaxIdentifyFrame; + // 两个箱子的箱角最大差值X + int iMaxContainerSpaceX; + // 两个箱子的箱角最大差值Y + int iMaxContainerSpaceY; }; // websocket_server 的服务端参数 diff --git a/app/config/config.yaml b/app/config/config.yaml index 5473391..b779733 100644 --- a/app/config/config.yaml +++ b/app/config/config.yaml @@ -1,7 +1,7 @@ # 基础控制参数 base: # 股道名称 - track_name: "1" + track_name: "1门" # 测试模式 test_model: false # Api 监听端口 @@ -24,43 +24,63 @@ log: # 数据源参数 data_source: - url: "./vedio/buertai2.mp4" - # 跳帧数 - skip_interval: 3 - # 行驶方向 0-自动识别 1-向左 2-向右 (与“首位信息”成对存在,形成例如向左就编号在前,向右就属性在前的对应) - direction: 0 - # 0-向左编号在前 1-向左属性在前 (向右行驶的情况:2-向右编号在前 3-向右属性在前) - left_first: 0 - # (向左行驶的情况:0-向左编号在前 1-向左属性在前) 2-向右编号在前 3-向右属性在前 - right_first: 3 - # 识别区域 - identify_areas: [120, 0, 1800, 1080] + - # 顶部摄像头(必须顶部摄像头) + url: "./videos/buertai2.mp4" + # 跳帧数 + skip_interval: 3 + # 识别区域 + identify_areas: [120, 0, 1800, 1080] + # 切箱方式 + divide_mode: "corner" #[corner, pixel] + # 汽车行进方向 + run_direction: "down" #[up, down, left, right] + - # 侧部摄像头 + url: "./videos/buertai2.mp4" + # 跳帧数 + skip_interval: 3 + # 识别区域 + identify_areas: [ 120, 0, 1800, 1080 ] + # 切箱方式 + divide_mode: "pixel" #[corner, pixel] + # 汽车行进方向 + run_direction: "right" #[up, down, left, right] + - # 侧边摄像头 + url: "./videos/buertai2.mp4" + # 跳帧数 + skip_interval: 3 + # 识别区域 + identify_areas: [ 120, 0, 1800, 1080 ] + # 切箱方式 + divide_mode: "pixel" #[corner, pixel] + # 汽车行进方向 + run_direction: "left" #[up, down, left, right] # 识别参数 identify: - # 运行方式 - run_mode: "always" #[always; command] - # 是否开启动态检测 - need_move_detect_flag: true - # 识别方向 [LEFT,RIGHT,ALL] - identify_direction: "LEFT" + # 切箱方式 + divide_mode: "corner" #[corner, pixel] # 大框帧跨度(比一个大框从出现到消失的跨度稍大一点, 跟跳帧有关系) - partition_frame_span: 20 - # 大框帧跨度的位置像素差异 - split_frame_span_px: 200 + partition_frame_span: 0 + # 顶部Y轴大框帧跨度的位置像素差异 + top_y_split_span_px: 200 + # 侧边X轴大框帧跨度的位置像素差异 + side_x_split_span_px: 600 # 每帧大框位置差异最小值 (持续小于此值,则可能停车) chkstop_px: 15 # 持续X次续位置差异小于gc_chkstop_px,则判断为停车。 chkstop_count: 10 # 过滤最小大框高度(不需要的话就写个很小的值) - num_frame_height: 150 - pro_frame_height: 120 - # 过滤最大框宽度(不需要的话就写个很大的值) - space_frame_width: 500 - # 是否识别车头 - train_heard_detect: false - # 是否识别集装箱 - container_detect: false + target_min_height: 95 + # 过滤最小大框宽度(不需要的话就写个很小的值) + target_min_width: 50 + # 过滤低于指定Y轴的大框 + target_min_y: 550 + # 单次识别最大帧数 + max_identify_frame: 600 + # 两个箱子的箱角最大差值X + max_container_space_x: 600 + # 两个箱子的箱角最大差值Y + max_container_space_y: 500 # websocket_server 的服务端参数 wsocket_server: diff --git a/app/config/matrix.yaml b/app/config/matrix.yaml index 3943746..65d8c2f 100644 --- a/app/config/matrix.yaml +++ b/app/config/matrix.yaml @@ -1,44 +1,56 @@ -#use_deviceid: -# #engineid: deviceid -# 0: 0 - #engine实例 engines: ApiEngine: 0 + DeleteExpiredFolderEngine: 0 + WSServerEngine: 0 VideoEngine: 0 + VideoEngine: 1 + VideoEngine: 2 VideoDecodeEngine: 0 - MoveEngine: 0 - SaveMoveImageEngine: 0 + VideoDecodeEngine: 1 + VideoDecodeEngine: 2 + ControlEngine: 0 +# SaveMoveImageEngine: 0 SaveMoveInfoEngine: 0 - TrainStep1DataReadEngine: 0 - TrainStep1InferenceEngine: 0 - TrainStep1FilterEngine: 0 - TrainDivideEngine: 0 - TrainStep2DataReadEngine: 0 - TrainStep2InferenceEngine: 0 - TrainCharacterConversionEngine: 0 + ContainerStep1InferenceEngine: 0 + CornerInferenceEngine: 0 + Step1MergeEngine: 0 + ContainerStep2InferenceEngine: 0 + ContainerCharacterConversionEngine: 0 + ContainerDivideEngine: 0 + ContainerDivideEngine: 1 + ContainerDivideEngine: 2 SelectBestEngine: 0 SaveResultCSVEngine: 0 - ToHttpSrvEngine: 0 ToMinioSrvEngine: 0 SaveDebugImageEngine: 0 #engine连接 connects: + WSServerEngine_0_0: "ControlEngine_0_0 1024" VideoEngine_0_0: "VideoDecodeEngine_0_0 1024" - VideoDecodeEngine_0_0: "MoveEngine_0_0 1024" - MoveEngine_0_0: "SaveMoveImageEngine_0_0 1024" - MoveEngine_0_1: "SaveMoveInfoEngine_0_0 1024" - SaveMoveImageEngine_0_0: "TrainStep1DataReadEngine_0_0 1024" - TrainStep1DataReadEngine_0_0: "TrainStep1InferenceEngine_0_0 1024" - TrainStep1InferenceEngine_0_0: "TrainStep1FilterEngine_0_0 1024" - TrainStep1FilterEngine_0_0: "TrainDivideEngine_0_0 1024" - TrainDivideEngine_0_0: "TrainStep2DataReadEngine_0_0 1024" - TrainStep2DataReadEngine_0_0: "TrainStep2InferenceEngine_0_0 1024" - TrainStep2InferenceEngine_0_0: "TrainCharacterConversionEngine_0_0 1024" - TrainCharacterConversionEngine_0_0: "SelectBestEngine_0_0 1024" - TrainCharacterConversionEngine_0_1: "SaveDebugImageEngine_0_0 1024" - SelectBestEngine_0_0: "SaveResultCSVEngine_0_0 1024" - SaveResultCSVEngine_0_0: "ToHttpSrvEngine_0_0 1024" - SaveResultCSVEngine_0_1: "ToMinioSrvEngine_0_0 1024" + VideoEngine_1_0: "VideoDecodeEngine_1_0 1024" + VideoEngine_2_0: "VideoDecodeEngine_2_0 1024" + VideoDecodeEngine_0_0: "ControlEngine_0_1 1024" + VideoDecodeEngine_1_0: "ControlEngine_0_1 1024" + VideoDecodeEngine_2_0: "ControlEngine_0_1 1024" + ControlEngine_0_0: "WSServerEngine_0_0 1024" + ControlEngine_0_1: "ContainerStep1InferenceEngine_0_0 1024" + ControlEngine_0_2: "CornerInferenceEngine_0_0 1024" + ControlEngine_0_3: "SaveMoveInfoEngine_0_0 1024" + ControlEngine_0_4: "SaveMoveImageEngine_0_0 1024" + ContainerStep1InferenceEngine_0_0: "Step1MergeEngine_0_0 1024" + CornerInferenceEngine_0_0: "Step1MergeEngine_0_1 1024" + Step1MergeEngine_0_0: "ContainerStep2InferenceEngine_0_0 1024" + ContainerStep2InferenceEngine_0_0: "ContainerCharacterConversionEngine_0_0 1024" + ContainerCharacterConversionEngine_0_0: "ContainerDivideEngine_0_0 1024" + ContainerCharacterConversionEngine_0_1: "ContainerDivideEngine_1_0 1024" + ContainerCharacterConversionEngine_0_2: "ContainerDivideEngine_2_0 1024" + ContainerCharacterConversionEngine_0_3: "SaveDebugImageEngine_0_0 1024" + ContainerDivideEngine_0_0: "SelectBestEngine_0_0 1024" + ContainerDivideEngine_1_0: "SelectBestEngine_0_0 1024" + ContainerDivideEngine_2_0: "SelectBestEngine_0_0 1024" + SelectBestEngine_0_0: "WSServerEngine_0_0 1024" + SelectBestEngine_0_1: "ToMinioSrvEngine_0_0 1024" + SelectBestEngine_0_2: "SaveResultCSVEngine_0_0 1024" diff --git a/app/config/model_config.yaml b/app/config/model_config.yaml index 030d784..4736eaa 100644 --- a/app/config/model_config.yaml +++ b/app/config/model_config.yaml @@ -39,9 +39,17 @@ train_step2_model: container_step1_model: model_path: "./model/container_step1/con1.engine" score_threshold: 0.6 - class: [] + class: ["CONTAINERNUM","CONTAINERNUM_REVERSE"] # ,"SPACE_T","SPACENX_T","SPACEG_T","SPACEP_T","SPACEP_T" # 集装箱字符识别 container_step2_model: model_path: "./model/container_step2/con2.engine" score_threshold: 0.7 - class: [] \ No newline at end of file + class: ["0","1","2","3","4","5","6","7","8","9", + "A","B","C","D","E","F","G","H","I","J","K","L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V","W", "X", "Y", "Z", + "change", "load", "m", "self", "t", "volume", "meter",")", "(", "?", "-" + ] +# 集装箱箱角识别 +corner_model: + model_path: "./model/corner/corner.engine" + score_threshold: 0.7 + class: ["CNTR_CORNER","CNTR_CORNER_TOP"] \ No newline at end of file diff --git a/common/CommonStruct.h b/common/CommonStruct.h index dbf747d..70a9219 100644 --- a/common/CommonStruct.h +++ b/common/CommonStruct.h @@ -380,4 +380,22 @@ typedef struct } DetectResultData; + +// 存图数据 +typedef struct +{ + // 数据来源标识 + int iDataSource; + std::string strDetectDate; + std::string strDetectTime; + // 帧序号 + int iFrameId; + // 箱号大框以及对应小框的集合 + Step2ResultData step2ResultData; + // 箱角大框 + std::vector vecCornerResultData; + // 图片 + cv::Mat cvImage; +} SaveDebugImgData; + #endif //TRAIN_COMMONSTRUCT_H diff --git a/config/config.yaml b/config/config.yaml index d0b5b93..b779733 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -77,6 +77,10 @@ identify: target_min_y: 550 # 单次识别最大帧数 max_identify_frame: 600 + # 两个箱子的箱角最大差值X + max_container_space_x: 600 + # 两个箱子的箱角最大差值Y + max_container_space_y: 500 # websocket_server 的服务端参数 wsocket_server: diff --git a/config/matrix.yaml b/config/matrix.yaml index 4218bd5..8a47258 100644 --- a/config/matrix.yaml +++ b/config/matrix.yaml @@ -10,7 +10,7 @@ engines: VideoDecodeEngine: 1 VideoDecodeEngine: 2 ControlEngine: 0 - SaveMoveImageEngine: 0 +# SaveMoveImageEngine: 0 SaveMoveInfoEngine: 0 ContainerStep1InferenceEngine: 0 CornerInferenceEngine: 0 diff --git a/engine/CharacterConversionEngine/ContainerCharacterConversionEngine.cpp b/engine/CharacterConversionEngine/ContainerCharacterConversionEngine.cpp index 98be92a..436362f 100644 --- a/engine/CharacterConversionEngine/ContainerCharacterConversionEngine.cpp +++ b/engine/CharacterConversionEngine/ContainerCharacterConversionEngine.cpp @@ -1 +1 @@ -#include "ContainerCharacterConversionEngine.h" using namespace ai_matrix; namespace { //按照x坐标排列 bool CompareX(const SingleData &v1, const SingleData &v2) { return (v1.fLTX < v2.fLTX); } //按照y坐标排列 bool CompareY(const SingleData &v1, const SingleData &v2) { return (v1.fLTY < v2.fLTY); } } ContainerCharacterConversionEngine::ContainerCharacterConversionEngine() {} ContainerCharacterConversionEngine::~ContainerCharacterConversionEngine() {} APP_ERROR ContainerCharacterConversionEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort3_ = engineName_ + "_" + std::to_string(engineId_) + "_3"; this->modelConfig_ = Config::getins()->getModelByContainerStep2Config(); this->baseConfig_ = Config::getins()->getBaseConfig(); LogInfo << "ContainerCharacterConversionEngine Init ok"; return APP_ERR_OK; } APP_ERROR ContainerCharacterConversionEngine::DeInit() { LogInfo << "ContainerCharacterConversionEngine DeInit ok"; return APP_ERR_OK; } /** * 验证集装箱号是否满足规则(前10位依次与2^0 ~2^9相乘)/11 所得余数,即是校验位) * inParam : std::string &strContainerNo 集装箱号信息 * outParam: N/A * return : true(校验通过)/false(校验失败) */ bool ContainerCharacterConversionEngine::verifyContainerNo(std::string &strContainerNo) { bool bChkFlag = false; if(strContainerNo.length() != 11) { return bChkFlag; } int iSum = 0; for (int i = 0; i < strContainerNo.length()-1; ++i) { iSum += this->mapExchange_[strContainerNo.substr(i, 1)] * int(pow(2.0, i)); } //当校验位等于10时要继续模运算,iSum % 11 % 10,保证最终结果为0~9之间的数 int iChkValue = iSum % 11 % 10; if (iChkValue == atoi(strContainerNo.substr(strContainerNo.length()-1, 1).c_str())) { bChkFlag = true; } return bChkFlag; } void ContainerCharacterConversionEngine::transContainerType(Step2ResultData &step2ResultData, std::map> &mapLine) { TransInfo info; info.iLine = 1; //集装箱型号(4位 字母或数字) if (mapLine.find(3) != mapLine.end()) { std::string strTemp; for (auto j = 0; j < mapLine.at(3).size(); j++) { strTemp += vecClassNames_.at(mapLine.at(3).at(j).iClassId); } int nTypesize = strTemp.length(); nTypesize = nTypesize > 4 ? 4 : nTypesize; info.strTmpResult = strTemp.substr(0, nTypesize); } if (info.strTmpResult.length() != 4) { info.bIsChkFlag = false; } // step2ResultData.transInfo = info; } /** * 集装箱框内容转换 * inParam : std::map> &mapLine * outParam: TransSubData &transSubData * return : N/A */ void ContainerCharacterConversionEngine::transContainerNum(Step2ResultData &step2ResultData, std::map> &mapLine) { TransInfo info; info.iLine = 0; // 箱主代码+设备识别码(4位英文字母) if (mapLine.find(0) != mapLine.end()) { std::string strTemp; for (auto j = 0; j < mapLine.at(0).size(); j++) { std::string strOne = this->modelConfig_.vecClass.at(mapLine.at(0).at(j).iClassId); // 过滤非字母 if (strOne[0] < 'A' || strOne[0] > 'Z') { // LogDebug << strOne << " not A-Z in container"; continue; } strTemp += strOne; info.vecValue.emplace_back(strOne); info.vecScore.emplace_back(mapLine.at(0).at(j).fScore); step2ResultData.fSubScoreSum += mapLine.at(0).at(j).fScore; } info.strTmpResult += strTemp; } // 箱号(6位数字) if (mapLine.find(1) != mapLine.end()) { std::string strTemp; for (auto j = 0; j < mapLine.at(1).size(); j++) { std::string strOne = this->modelConfig_.vecClass.at(mapLine.at(1).at(j).iClassId); // 过滤非数字 if (strOne[0] < '0' || strOne[0] > '9') { // LogDebug << "engineId:" << engineId_ << " " << strOne << " not digit in num"; continue; } strTemp += strOne; info.vecValue.emplace_back(strOne); info.vecScore.emplace_back(mapLine.at(1).at(j).fScore); step2ResultData.fSubScoreSum += mapLine.at(1).at(j).fScore; } info.strTmpResult += strTemp; } //校验码(1位数字) if (mapLine.find(2) != mapLine.end()) { std::string strTemp; for (auto j = 0; j < mapLine.at(2).size(); j++) { //过滤非数字 std::string strOne = this->modelConfig_.vecClass.at(mapLine.at(2).at(j).iClassId); if (strOne[0] < '0' || strOne[0] > '9') { // LogDebug << "engineId:" << engineId_ << " " << strOne << " not digit in container_2"; continue; } strTemp += strOne; info.vecValue.emplace_back(strOne); info.vecScore.emplace_back(mapLine.at(2).at(j).fScore); step2ResultData.fSubScoreSum += mapLine.at(2).at(j).fScore; } info.strTmpResult += strTemp; } if (this->verifyContainerNo(info.strTmpResult)) { info.bIsChkFlag = true; } else { info.strTmpResult = "invalid-" + info.strTmpResult; } step2ResultData.transInfo = info; } APP_ERROR ContainerCharacterConversionEngine::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 pVStep2OutputData = std::static_pointer_cast(pVoidData0); if (pVStep2OutputData->bIsEnd) { outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_" + std::to_string(pVStep2OutputData->iDataSource)]->push(std::static_pointer_cast(pVStep2OutputData), true); outputQueMap_[strPort3_]->push(std::static_pointer_cast(pVStep2OutputData), true); } std::vector vecSingleData = pVStep2OutputData->step2ResultData.vecSingleData; if (pVStep2OutputData->step2ResultData.fScore == 0.0f) continue; std::map> mapLine; for (auto & it_singleData : vecSingleData) { mapLine[it_singleData.iLine].push_back(it_singleData); } bool bSortByX = (pVStep2OutputData->step2ResultData.fRBY - pVStep2OutputData->step2ResultData.fLTY) < ((pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX) * 1.5); //每一行按x坐标排序 for (auto & it : mapLine) { if (it.second.size() > 2) { std::set setX; std::set setY; for (auto & it_singleData : it.second) { setX.insert(it_singleData.fLTX); setY.insert(it_singleData.fLTY); } float X = *setX.rbegin() - *setX.begin(); float Y = *setY.rbegin() - *setY.begin(); bSortByX = (X > Y); } if (bSortByX) { std::sort(it.second.begin(), it.second.end(), CompareX); } else { std::sort(it.second.begin(), it.second.end(), CompareY); } // std::string strTemp; // for (auto & it_singleData : it.second) // { // strTemp += this->modelConfig_.vecClass.at(it_singleData.iClassId); // } } switch (pVStep2OutputData->step2ResultData.iClassId) { case 0: this->transContainerNum(pVStep2OutputData->step2ResultData, mapLine); break; default: break; } // 模型识别不稳定时才用。 // if (bSortByX && pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag) // { // if (mapLine.find(0) != mapLine.end() && mapLine.find(1) != mapLine.end()) // { // if (mapLine.at(1).at(0).fLTX < mapLine.at(0).at(0).fLTX) // { // pVStep2OutputData->step2ResultData.transInfo.strTmpResult = "invalid-" + pVStep2OutputData->step2ResultData.transInfo.strTmpResult; // pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag = false; // } // } // } outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_" + std::to_string(pVStep2OutputData->iDataSource)]->push(std::static_pointer_cast(pVStep2OutputData), true); outputQueMap_[strPort3_]->push(std::static_pointer_cast(pVStep2OutputData), true); } return APP_ERR_OK; } \ No newline at end of file +#include "ContainerCharacterConversionEngine.h" using namespace ai_matrix; namespace { //按照x坐标排列 bool CompareX(const SingleData &v1, const SingleData &v2) { return (v1.fLTX < v2.fLTX); } //按照y坐标排列 bool CompareY(const SingleData &v1, const SingleData &v2) { return (v1.fLTY < v2.fLTY); } } ContainerCharacterConversionEngine::ContainerCharacterConversionEngine() {} ContainerCharacterConversionEngine::~ContainerCharacterConversionEngine() {} APP_ERROR ContainerCharacterConversionEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort3_ = engineName_ + "_" + std::to_string(engineId_) + "_3"; this->modelConfig_ = Config::getins()->getModelByContainerStep2Config(); this->baseConfig_ = Config::getins()->getBaseConfig(); LogInfo << "ContainerCharacterConversionEngine Init ok"; return APP_ERR_OK; } APP_ERROR ContainerCharacterConversionEngine::DeInit() { LogInfo << "ContainerCharacterConversionEngine DeInit ok"; return APP_ERR_OK; } /** * 验证集装箱号是否满足规则(前10位依次与2^0 ~2^9相乘)/11 所得余数,即是校验位) * inParam : std::string &strContainerNo 集装箱号信息 * outParam: N/A * return : true(校验通过)/false(校验失败) */ bool ContainerCharacterConversionEngine::verifyContainerNo(std::string &strContainerNo) { bool bChkFlag = false; if(strContainerNo.length() != 11) { return bChkFlag; } int iSum = 0; for (int i = 0; i < strContainerNo.length()-1; ++i) { iSum += this->mapExchange_[strContainerNo.substr(i, 1)] * int(pow(2.0, i)); } //当校验位等于10时要继续模运算,iSum % 11 % 10,保证最终结果为0~9之间的数 int iChkValue = iSum % 11 % 10; if (iChkValue == atoi(strContainerNo.substr(strContainerNo.length()-1, 1).c_str())) { bChkFlag = true; } return bChkFlag; } void ContainerCharacterConversionEngine::transContainerType(Step2ResultData &step2ResultData, std::map> &mapLine) { TransInfo info; info.iLine = 1; //集装箱型号(4位 字母或数字) if (mapLine.find(3) != mapLine.end()) { std::string strTemp; for (auto j = 0; j < mapLine.at(3).size(); j++) { strTemp += vecClassNames_.at(mapLine.at(3).at(j).iClassId); } int nTypesize = strTemp.length(); nTypesize = nTypesize > 4 ? 4 : nTypesize; info.strTmpResult = strTemp.substr(0, nTypesize); } if (info.strTmpResult.length() != 4) { info.bIsChkFlag = false; } // step2ResultData.transInfo = info; } /** * 集装箱框内容转换 * inParam : std::map> &mapLine * outParam: TransSubData &transSubData * return : N/A */ void ContainerCharacterConversionEngine::transContainerNum(Step2ResultData &step2ResultData, std::map> &mapLine) { TransInfo info; info.iLine = 0; // 箱主代码+设备识别码(4位英文字母) if (mapLine.find(0) != mapLine.end()) { std::string strTemp; for (auto j = 0; j < mapLine.at(0).size(); j++) { std::string strOne = this->modelConfig_.vecClass.at(mapLine.at(0).at(j).iClassId); // 过滤非字母 if (strOne[0] < 'A' || strOne[0] > 'Z') { // LogDebug << strOne << " not A-Z in container"; continue; } strTemp += strOne; info.vecValue.emplace_back(strOne); info.vecScore.emplace_back(mapLine.at(0).at(j).fScore); step2ResultData.fSubScoreSum += mapLine.at(0).at(j).fScore; } info.strTmpResult += strTemp; } // 箱号(6位数字) if (mapLine.find(1) != mapLine.end()) { std::string strTemp; for (auto j = 0; j < mapLine.at(1).size(); j++) { std::string strOne = this->modelConfig_.vecClass.at(mapLine.at(1).at(j).iClassId); // 过滤非数字 if (strOne[0] < '0' || strOne[0] > '9') { // LogDebug << "engineId:" << engineId_ << " " << strOne << " not digit in num"; continue; } strTemp += strOne; info.vecValue.emplace_back(strOne); info.vecScore.emplace_back(mapLine.at(1).at(j).fScore); step2ResultData.fSubScoreSum += mapLine.at(1).at(j).fScore; } info.strTmpResult += strTemp; } //校验码(1位数字) if (mapLine.find(2) != mapLine.end()) { std::string strTemp; for (auto j = 0; j < mapLine.at(2).size(); j++) { //过滤非数字 std::string strOne = this->modelConfig_.vecClass.at(mapLine.at(2).at(j).iClassId); if (strOne[0] < '0' || strOne[0] > '9') { // LogDebug << "engineId:" << engineId_ << " " << strOne << " not digit in container_2"; continue; } strTemp += strOne; info.vecValue.emplace_back(strOne); info.vecScore.emplace_back(mapLine.at(2).at(j).fScore); step2ResultData.fSubScoreSum += mapLine.at(2).at(j).fScore; } info.strTmpResult += strTemp; } if (this->verifyContainerNo(info.strTmpResult)) { info.bIsChkFlag = true; } else { info.strTmpResult = "invalid-" + info.strTmpResult; } step2ResultData.transInfo = info; } APP_ERROR ContainerCharacterConversionEngine::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 pVStep2OutputData = std::static_pointer_cast(pVoidData0); std::shared_ptr pSaveDebugImgData = std::make_shared(); pSaveDebugImgData->iFrameId = pVStep2OutputData->iFrameId; pSaveDebugImgData->iDataSource = pVStep2OutputData->iDataSource; pSaveDebugImgData->strDetectDate = pVStep2OutputData->strDetectDate; pSaveDebugImgData->strDetectTime = pVStep2OutputData->strDetectTime; pSaveDebugImgData->cvImage = pVStep2OutputData->cvImage.clone(); pSaveDebugImgData->step2ResultData = pVStep2OutputData->step2ResultData; pSaveDebugImgData->vecCornerResultData = pVStep2OutputData->vecCornerResultData; if (pVStep2OutputData->bIsEnd) { outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_" + std::to_string(pVStep2OutputData->iDataSource)]->push(std::static_pointer_cast(pVStep2OutputData), true); // outputQueMap_[strPort3_]->push(std::static_pointer_cast(pSaveDebugImgData), true); continue; } std::vector vecSingleData = pVStep2OutputData->step2ResultData.vecSingleData; if (pVStep2OutputData->step2ResultData.fScore == 0.0f) { outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_" + std::to_string(pVStep2OutputData->iDataSource)]->push(std::static_pointer_cast(pVStep2OutputData), true); // outputQueMap_[strPort3_]->push(std::static_pointer_cast(pSaveDebugImgData), true); continue; } std::map> mapLine; for (auto & it_singleData : vecSingleData) { mapLine[it_singleData.iLine].push_back(it_singleData); } bool bSortByX = (pVStep2OutputData->step2ResultData.fRBY - pVStep2OutputData->step2ResultData.fLTY) < ((pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX) * 1.5); //每一行按x坐标排序 for (auto & it : mapLine) { if (it.second.size() > 2) { std::set setX; std::set setY; for (auto & it_singleData : it.second) { setX.insert(it_singleData.fLTX); setY.insert(it_singleData.fLTY); } float X = *setX.rbegin() - *setX.begin(); float Y = *setY.rbegin() - *setY.begin(); bSortByX = (X > Y); } if (bSortByX) { std::sort(it.second.begin(), it.second.end(), CompareX); } else { std::sort(it.second.begin(), it.second.end(), CompareY); } // std::string strTemp; // for (auto & it_singleData : it.second) // { // strTemp += this->modelConfig_.vecClass.at(it_singleData.iClassId); // } } switch (pVStep2OutputData->step2ResultData.iClassId) { case 0: this->transContainerNum(pVStep2OutputData->step2ResultData, mapLine); break; default: break; } // 模型识别不稳定时才用。 // if (bSortByX && pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag) // { // if (mapLine.find(0) != mapLine.end() && mapLine.find(1) != mapLine.end()) // { // if (mapLine.at(1).at(0).fLTX < mapLine.at(0).at(0).fLTX) // { // pVStep2OutputData->step2ResultData.transInfo.strTmpResult = "invalid-" + pVStep2OutputData->step2ResultData.transInfo.strTmpResult; // pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag = false; // } // } // } pSaveDebugImgData->step2ResultData = pVStep2OutputData->step2ResultData; outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_" + std::to_string(pVStep2OutputData->iDataSource)]->push(std::static_pointer_cast(pVStep2OutputData), true); // outputQueMap_[strPort3_]->push(std::static_pointer_cast(pSaveDebugImgData), true); } return APP_ERR_OK; } \ No newline at end of file diff --git a/engine/ControlEngine/ControlEngine.cpp b/engine/ControlEngine/ControlEngine.cpp index 100589c..c6673e0 100644 --- a/engine/ControlEngine/ControlEngine.cpp +++ b/engine/ControlEngine/ControlEngine.cpp @@ -116,7 +116,7 @@ void ControlEngine::detectControl(std::shared_ptr pWSServerOrder) switch (jvOrder["commandType"].asInt()) { case IDENTIFY_START: - if (g_identify_type == 1) + if (g_identify_type == IDENTIFY_START) { std::string msg = "当前正在识别,无需重复发送识别信号"; LogWarn << msg; @@ -245,12 +245,12 @@ APP_ERROR ControlEngine::Process() outputQueMap_[strPort3_]->push(std::static_pointer_cast(pVDetectInfo), true); // 存图 -// std::shared_ptr pSaveImgData = std::make_shared(); -// pSaveImgData->strFilePath = strFilePath; -// pSaveImgData->strFileName = std::to_string(this->mapDetectNO_[pProcessData->iDataSource]) + "_" + std::to_string(pProcessData->iDataSource) + ".jpg"; -// pSaveImgData->cvImage = image; -// pSaveImgData->bIsEnd = pProcessData->bIsEnd; -// outputQueMap_[strPort4_]->push(std::static_pointer_cast(pSaveImgData), true); + std::shared_ptr pSaveImgData = std::make_shared(); + pSaveImgData->strFilePath = strFilePath; + pSaveImgData->strFileName = std::to_string(this->mapDetectNO_[pProcessData->iDataSource]) + "_" + std::to_string(pProcessData->iDataSource) + ".jpg"; + pSaveImgData->cvImage = image; + pSaveImgData->bIsEnd = pProcessData->bIsEnd; + outputQueMap_[strPort4_]->push(std::static_pointer_cast(pSaveImgData), true); this->mapDetectNO_[pProcessData->iDataSource]++; } diff --git a/engine/DataUploadEngine/ToMinioSrvEngine.cpp b/engine/DataUploadEngine/ToMinioSrvEngine.cpp index 065d531..cfdbd6e 100644 --- a/engine/DataUploadEngine/ToMinioSrvEngine.cpp +++ b/engine/DataUploadEngine/ToMinioSrvEngine.cpp @@ -166,7 +166,7 @@ APP_ERROR ToMinioSrvEngine::Process() strMinIoPath, strLocalPath)) { - LogWarn << "数据上传失败! -- " << this->baseConfig_.strDebugResultPath; + LogWarn << "数据上传失败! -- " << strLocalPath; } else { diff --git a/engine/DetectDivideEngine/ContainerDivideEngine.cpp b/engine/DetectDivideEngine/ContainerDivideEngine.cpp index 39d2c39..8647b98 100644 --- a/engine/DetectDivideEngine/ContainerDivideEngine.cpp +++ b/engine/DetectDivideEngine/ContainerDivideEngine.cpp @@ -1 +1 @@ -#include "ContainerDivideEngine.h" #include using namespace ai_matrix; ContainerDivideEngine::ContainerDivideEngine() {} ContainerDivideEngine::~ContainerDivideEngine() {} APP_ERROR ContainerDivideEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; this->vecDataSourceConfig_ = Config::getins()->getAllDataSourceConfig(); if (this->vecDataSourceConfig_.size() <= this->engineId_) { LogWarn << " -- " << engineName_ << "_" << engineId_ << " dataSource no set, Engine DeInit"; return APP_ERR_OK; } this->dataSourceConfig_ = this->vecDataSourceConfig_.at(engineId_); this->baseConfig_ = Config::getins()->getBaseConfig(); this->identifyConfig_ = Config::getins()->getIdentifyConfig(); this->initParam(); LogInfo << "DetectDivideEngine Init ok"; return APP_ERR_OK; } APP_ERROR ContainerDivideEngine::DeInit() { LogInfo << "DetectDivideEngine DeInit ok"; return APP_ERR_OK; } /** * 初始化参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void ContainerDivideEngine::initParam() { this->iContainerIndex = 0; this->vecContainerFail_.clear(); } void ContainerDivideEngine::sendBestData(const VSelectBestData& selectBestData) { // 直接发送第一个箱子的箱号 std::shared_ptr pVSelectBestData = std::make_shared(); *pVSelectBestData = selectBestData; outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); LogInfo << " 帧:" << selectBestData.iFrameId << " 数据源:" << selectBestData.iDataSource << " 节:" << selectBestData.iContainerIndex << " 发送识别结果 " << selectBestData.strNumResult; this->stdContainerResult_ = selectBestData.strNumResult; this->iContainerIndex++; } void ContainerDivideEngine::makeResult(const std::shared_ptr& pVStep2OutputData, VSelectBestData & selectBestData) const { selectBestData.strDetectDate = pVStep2OutputData->strDetectDate; selectBestData.strDetectTime = pVStep2OutputData->strDetectTime; selectBestData.iDataSource = pVStep2OutputData->iDataSource; selectBestData.iFrameId = pVStep2OutputData->iFrameId; selectBestData.strNumResult = pVStep2OutputData->step2ResultData.transInfo.strTmpResult; selectBestData.bIsChkFlag = pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag; selectBestData.fSumScore = pVStep2OutputData->step2ResultData.fSubScoreSum; selectBestData.iContainerIndex = this->iContainerIndex; selectBestData.bHaveTwoContainer = pVStep2OutputData->vecCornerResultData.size() > 2; } /** * 依据像素进行集装箱切分 * @param pVStep2OutputData */ void ContainerDivideEngine::divideByPixelInfo(std::shared_ptr pVStep2OutputData) { auto vCompare = [](std::string a, std::string b) { if (a.size() != b.size()) return 999; int count = 0; for (int i = 0; i < a.size(); ++i) { if (a[i] != b[i]) { ++count; } } return count; }; Step2ResultData step2ResultData_pre = this->pVStep2OutputDataPre_->step2ResultData; Step2ResultData step2ResultData = pVStep2OutputData->step2ResultData; float fCenterX = (step2ResultData.fRBX + step2ResultData.fLTX)/2; float fCenterY = (step2ResultData.fRBY + step2ResultData.fLTY)/2; float fCenterX_Pre = (step2ResultData_pre.fRBX + step2ResultData_pre.fLTX)/2; float fCenterY_Pre = (step2ResultData_pre.fRBY + step2ResultData_pre.fLTY)/2; LogDebug << " 帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " Y差值:" << std::abs(fCenterY - fCenterY_Pre) << " X差值:" << std::abs(fCenterX - fCenterX_Pre); if ((pVStep2OutputData->iDataSource == 0 && std::abs(fCenterY - fCenterY_Pre) > this->identifyConfig_.iTop_Y_SplitSpanPx) || (pVStep2OutputData->iDataSource != 0 && std::abs(fCenterX - fCenterX_Pre) > this->identifyConfig_.iSide_X_SplitSpanPx)) { if (step2ResultData.transInfo.bIsChkFlag) { if (stdContainerResult_ != step2ResultData.transInfo.strTmpResult) { if (stdContainerResult_.empty()) { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } sendBestData(this->vecContainerFail_[iIndex]); } // 记录第二箱子 this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); } } else { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } if (this->vecContainerFail_.size() > 0 && this->iContainerIndex < 1) { sendBestData(this->vecContainerFail_[iIndex]); } // 把之前的清理掉再存新箱子的 (有风险,有可能切分错) this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->vecContainerFail_.emplace_back(selectBestData); } } else {// 不满足像素差 if (!this->stdContainerResult_.empty()) { if (step2ResultData.transInfo.bIsChkFlag) { if (this->stdContainerResult_ != step2ResultData.transInfo.strTmpResult) { // if (vCompare(this->stdContainerResult_, step2ResultData.transInfo.strTmpResult) > 2) // { this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); // } } } } else { if (step2ResultData.transInfo.bIsChkFlag) { this->stdContainerResult_ = step2ResultData.transInfo.strTmpResult; this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); } else { VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->vecContainerFail_.emplace_back(selectBestData); } } } } bool ContainerDivideEngine::setectBestByCorner() { if (!this->vecContainer_.empty()) { // 汇总下vecContainer中,有几种正确的识别结果,选出识别次数最多的 std::map mapContainer_count; std::map mapContainer_index; int i = 0; for (auto &container: this->vecContainer_) { mapContainer_count[container.strNumResult]++; mapContainer_index[container.strNumResult] = i; ++i; } std::string strBestContainer; int count = 0; // 取出现次数最高的 且与第一个箱子不一样的 for (auto &it_max: mapContainer_count) { if (it_max.first.empty()) continue; if (it_max.second >= count) { count = it_max.second; strBestContainer = it_max.first; } } this->sendBestData(this->vecContainer_[mapContainer_index[strBestContainer]]); this->vecContainer_.clear(); this->vecContainerFail_.clear(); } else { if (this->vecContainerFail_.empty()) return false; // 汇总下vecContainer中,有几种正确的识别结果,选出识别次数最多的 int iMaxSize = 0, iIndex = 0; std::map mapContainer_index; int i = 0; for (auto &container: this->vecContainerFail_) { if (container.strNumResult.size() > iMaxSize) { iMaxSize = container.strNumResult.size(); iIndex = i; } ++i; } this->sendBestData(this->vecContainerFail_[iIndex]); this->vecContainer_.clear(); this->vecContainerFail_.clear(); } return true; } /** * 依据箱角切分 * @param pVStep2OutputData */ void ContainerDivideEngine::divideByCornerInfo(std::shared_ptr pVStep2OutputData) { Step2ResultData step2ResultData = pVStep2OutputData->step2ResultData; if (pVStep2OutputData->vecCornerResultData.size() > 1 && this->iContainerIndex < 1) { if (pVStep2OutputData->vecCornerResultData.size() > 2) { LogWarn << "帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " ---- >>> 检测到超过2个箱角,疑似画面过滤倾斜或模型训练不足!"; return; } LogInfo << "帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " ---- >>> 检测到多个箱角,准备切分"; if (pVStep2OutputData->iDataSource == 0 || this->dataSourceConfig_.strRunDirection == "right") { if (this->vecContainerFail_.empty()) { VSelectBestData selectBestData; selectBestData.strDetectDate = pVStep2OutputData->strDetectDate; selectBestData.strDetectTime = pVStep2OutputData->strDetectTime; selectBestData.iDataSource = pVStep2OutputData->iDataSource; selectBestData.iFrameId = 1; selectBestData.strNumResult = "invalid-?"; selectBestData.iContainerIndex = this->iContainerIndex; selectBestData.bHaveTwoContainer = true; this->vecContainerFail_.emplace_back(selectBestData); } this->setectBestByCorner(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); if (step2ResultData.transInfo.bIsChkFlag) { this->vecContainer_.emplace_back(selectBestData); } else { this->vecContainerFail_.emplace_back(selectBestData); } return; } if (this->dataSourceConfig_.strRunDirection == "left") { LogWarn << "向左行驶的一侧暂不支持箱角识别,请及时修改参数 divide_mode: \"pixel\""; return; } } else { VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); if (step2ResultData.transInfo.bIsChkFlag) { this->vecContainer_.emplace_back(selectBestData); } else { this->vecContainerFail_.emplace_back(selectBestData); } } } /** * 切分车厢 * @param pVStep2OutputData */ void ContainerDivideEngine::divideInfo(std::shared_ptr pVStep2OutputData) { if (!this->pVStep2OutputDataPre_) return; if (this->iContainerIndex > 1) return; if (this->vecDataSourceConfig_[pVStep2OutputData->iDataSource].strDivideModel == "corner") { this->divideByCornerInfo(pVStep2OutputData); } else { this->divideByPixelInfo(pVStep2OutputData); } } APP_ERROR ContainerDivideEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { //pop端口0 std::shared_ptr pVoidData0 = nullptr; iRet = inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr == pVoidData0) { usleep(1000); continue; } std::shared_ptr pVStep2OutputData = std::static_pointer_cast(pVoidData0); if (pVStep2OutputData->bIsEnd) { std::shared_ptr pVSelectBestData = std::make_shared(); pVSelectBestData->bIsEnd = true; pVSelectBestData->iDataSource = pVStep2OutputData->iDataSource; pVSelectBestData->strDetectDate = pVStep2OutputData->strDetectDate; pVSelectBestData->strDetectTime = pVStep2OutputData->strDetectTime; if (this->iContainerIndex > 1) { outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); this->initParam(); continue; } if (this->vecDataSourceConfig_[pVStep2OutputData->iDataSource].strDivideModel == "corner") { if (!this->vecContainerFail_.empty() || !this->vecContainer_.empty()) { this->setectBestByCorner(); } } else { if (!this->vecContainerFail_.empty()) { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } this->vecContainerFail_[iIndex].bIsEnd = true; sendBestData(this->vecContainerFail_[iIndex]); this->initParam(); continue; } } outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); this->initParam(); continue; } std::string strFilePath ; strFilePath = this->baseConfig_.strDebugResultPath + "/" + pVStep2OutputData->strDetectDate + "/" + StringUtil::getins()->replace_all_distinct(pVStep2OutputData->strDetectTime, ":", "-") + "/" + std::to_string(pVStep2OutputData->iFrameId) + "_" + std::to_string(pVStep2OutputData->iDataSource) + ".json"; // 先读取文本内容,追加新的信息后再写入 Json::Value jvFrameInfo; if (!FileUtil::getins()->readJsonInfo(jvFrameInfo, strFilePath)) { LogError << "read fail:" << strFilePath; } // jvFrameInfo["isEnd"] = (pVStep2OutputData->bIsEnd || jvFrameInfo["isEnd"].asBool()); // 识别结果存储 float fCenter = pVStep2OutputData->step2ResultData.fLTX + (pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX) / 2; // this->mapContainerCenterInfo_.insert(std::make_pair(pVStep2OutputData->iFrameId, fCenter)); Json::Value jvInfo; jvInfo["classid"] = pVStep2OutputData->step2ResultData.iClassId; jvInfo["score"] = pVStep2OutputData->step2ResultData.fScore; jvInfo["ltx"] = pVStep2OutputData->step2ResultData.fLTX; jvInfo["lty"] = pVStep2OutputData->step2ResultData.fLTY; jvInfo["rbx"] = pVStep2OutputData->step2ResultData.fRBX; jvInfo["rby"] = pVStep2OutputData->step2ResultData.fRBY; jvFrameInfo["step1"].append(jvInfo); for (auto &step2ResultData : pVStep2OutputData->vecCornerResultData) { float fCenter = step2ResultData.fLTX + (step2ResultData.fRBX - step2ResultData.fLTX) / 2; // this->mapContainerCenterInfo_.insert(std::make_pair(pVStep2OutputData->iFrameId, fCenter)); Json::Value jvInfo; jvInfo["classid"] = step2ResultData.iClassId; jvInfo["score"] = step2ResultData.fScore; jvInfo["ltx"] = step2ResultData.fLTX; jvInfo["lty"] = step2ResultData.fLTY; jvInfo["rbx"] = step2ResultData.fRBX; jvInfo["rby"] = step2ResultData.fRBY; jvFrameInfo["step1"].append(jvInfo); } FileUtil::getins()->writeJsonInfo(jvFrameInfo, strFilePath); if (pVStep2OutputData->step2ResultData.fScore != 0.0f) { LogDebug << " 帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " - "<< pVStep2OutputData->step2ResultData.transInfo.strTmpResult; } this->divideInfo(pVStep2OutputData); this->pVStep2OutputDataPre_ = pVStep2OutputData; } return APP_ERR_OK; } \ No newline at end of file +#include "ContainerDivideEngine.h" #include using namespace ai_matrix; ContainerDivideEngine::ContainerDivideEngine() {} ContainerDivideEngine::~ContainerDivideEngine() {} APP_ERROR ContainerDivideEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; this->vecDataSourceConfig_ = Config::getins()->getAllDataSourceConfig(); if (this->vecDataSourceConfig_.size() <= this->engineId_) { LogWarn << " -- " << engineName_ << "_" << engineId_ << " dataSource no set, Engine DeInit"; return APP_ERR_OK; } this->dataSourceConfig_ = this->vecDataSourceConfig_.at(engineId_); this->baseConfig_ = Config::getins()->getBaseConfig(); this->identifyConfig_ = Config::getins()->getIdentifyConfig(); this->initParam(); LogInfo << "DetectDivideEngine Init ok"; return APP_ERR_OK; } APP_ERROR ContainerDivideEngine::DeInit() { LogInfo << "DetectDivideEngine DeInit ok"; return APP_ERR_OK; } /** * 初始化参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void ContainerDivideEngine::initParam() { this->iContainerIndex = 0; this->pVStep2OutputDataPre_ = nullptr; this->vecContainerFail_.clear(); } void ContainerDivideEngine::sendBestData(const VSelectBestData& selectBestData) { // 直接发送第一个箱子的箱号 std::shared_ptr pVSelectBestData = std::make_shared(); *pVSelectBestData = selectBestData; outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); LogInfo << " 帧:" << selectBestData.iFrameId << " 数据源:" << selectBestData.iDataSource << " 节:" << selectBestData.iContainerIndex << " 发送识别结果 " << selectBestData.strNumResult; this->stdContainerResult_ = selectBestData.strNumResult; this->iContainerIndex++; } void ContainerDivideEngine::makeResult(const std::shared_ptr& pVStep2OutputData, VSelectBestData & selectBestData) const { selectBestData.strDetectDate = pVStep2OutputData->strDetectDate; selectBestData.strDetectTime = pVStep2OutputData->strDetectTime; selectBestData.iDataSource = pVStep2OutputData->iDataSource; selectBestData.iFrameId = pVStep2OutputData->iFrameId; selectBestData.strNumResult = pVStep2OutputData->step2ResultData.transInfo.strTmpResult; selectBestData.bIsChkFlag = pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag; selectBestData.fSumScore = pVStep2OutputData->step2ResultData.fSubScoreSum; selectBestData.iContainerIndex = this->iContainerIndex; selectBestData.bHaveTwoContainer = pVStep2OutputData->vecCornerResultData.size() > 2; } /** * 依据像素进行集装箱切分 * @param pVStep2OutputData */ void ContainerDivideEngine::divideByPixelInfo(std::shared_ptr pVStep2OutputData) { auto vCompare = [](std::string a, std::string b) { if (a.size() != b.size()) return 999; int count = 0; for (int i = 0; i < a.size(); ++i) { if (a[i] != b[i]) { ++count; } } return count; }; if (!this->pVStep2OutputDataPre_) { if (pVStep2OutputData->step2ResultData.fScore == 0.0f) return; this->pVStep2OutputDataPre_ = pVStep2OutputData; } Step2ResultData step2ResultData = pVStep2OutputData->step2ResultData; Step2ResultData step2ResultData_pre = this->pVStep2OutputDataPre_->step2ResultData; float fCenterX = (step2ResultData.fRBX + step2ResultData.fLTX)/2; float fCenterY = (step2ResultData.fRBY + step2ResultData.fLTY)/2; float fCenterX_Pre = (step2ResultData_pre.fRBX + step2ResultData_pre.fLTX)/2; float fCenterY_Pre = (step2ResultData_pre.fRBY + step2ResultData_pre.fLTY)/2; LogDebug << " 帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " Y差值:" << std::abs(fCenterY - fCenterY_Pre) << " X差值:" << std::abs(fCenterX - fCenterX_Pre); if ((pVStep2OutputData->iDataSource == 0 && std::abs(fCenterY - fCenterY_Pre) > this->identifyConfig_.iTop_Y_SplitSpanPx) || (pVStep2OutputData->iDataSource != 0 && std::abs(fCenterX - fCenterX_Pre) > this->identifyConfig_.iSide_X_SplitSpanPx)) { if (step2ResultData.transInfo.bIsChkFlag) { if (stdContainerResult_ != step2ResultData.transInfo.strTmpResult) { if (stdContainerResult_.empty()) { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } sendBestData(this->vecContainerFail_[iIndex]); } // 记录第二箱子 this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); } } else { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } if (this->vecContainerFail_.size() > 0 && this->iContainerIndex < 1) { sendBestData(this->vecContainerFail_[iIndex]); } // 把之前的清理掉再存新箱子的 (有风险,有可能切分错) this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->vecContainerFail_.emplace_back(selectBestData); } } else {// 不满足像素差 if (!this->stdContainerResult_.empty()) { if (step2ResultData.transInfo.bIsChkFlag) { if (this->stdContainerResult_ != step2ResultData.transInfo.strTmpResult) { // if (vCompare(this->stdContainerResult_, step2ResultData.transInfo.strTmpResult) > 2) // { this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); // } } } } else { if (step2ResultData.transInfo.bIsChkFlag) { this->stdContainerResult_ = step2ResultData.transInfo.strTmpResult; this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); } else { VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->vecContainerFail_.emplace_back(selectBestData); } } } } bool ContainerDivideEngine::setectBestByCorner() { if (!this->vecContainer_.empty()) { // 汇总下vecContainer中,有几种正确的识别结果,选出识别次数最多的 std::map mapContainer_count; std::map mapContainer_index; int i = 0; for (auto &container: this->vecContainer_) { mapContainer_count[container.strNumResult]++; mapContainer_index[container.strNumResult] = i; ++i; } std::string strBestContainer; int count = 0; // 取出现次数最高的 且与第一个箱子不一样的 for (auto &it_max: mapContainer_count) { if (it_max.first.empty()) continue; if (it_max.second >= count) { count = it_max.second; strBestContainer = it_max.first; } } this->sendBestData(this->vecContainer_[mapContainer_index[strBestContainer]]); this->vecContainer_.clear(); this->vecContainerFail_.clear(); } else { if (this->vecContainerFail_.empty()) return false; // 汇总下vecContainer中,有几种正确的识别结果,选出识别次数最多的 int iMaxSize = 0, iIndex = 0; std::map mapContainer_index; int i = 0; for (auto &container: this->vecContainerFail_) { if (container.strNumResult.size() > iMaxSize) { iMaxSize = container.strNumResult.size(); iIndex = i; } ++i; } this->sendBestData(this->vecContainerFail_[iIndex]); this->vecContainer_.clear(); this->vecContainerFail_.clear(); } return true; } /** * 依据箱角切分 * @param pVStep2OutputData */ void ContainerDivideEngine::divideByCornerInfo(std::shared_ptr pVStep2OutputData) { Step2ResultData step2ResultData = pVStep2OutputData->step2ResultData; if (pVStep2OutputData->vecCornerResultData.size() > 1 && this->iContainerIndex < 1) { if (pVStep2OutputData->vecCornerResultData.size() > 2) { LogWarn << "帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " ---- >>> 检测到超过2个箱角,疑似画面过于倾斜或模型训练不足!"; return; } float fDiffX = std::abs(pVStep2OutputData->vecCornerResultData[0].fLTX - pVStep2OutputData->vecCornerResultData[1].fLTX); float fDiffY = std::abs(pVStep2OutputData->vecCornerResultData[0].fLTY - pVStep2OutputData->vecCornerResultData[1].fLTY); if (fDiffX > this->identifyConfig_.iMaxContainerSpaceX || fDiffY > this->identifyConfig_.iMaxContainerSpaceY) { LogWarn << "帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " ---- >>> 检测到超过2个间隔过远的箱角,疑似画面过于倾斜看到一个箱子的多个角或模型训练不足!"; return; } LogInfo << "帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " ---- >>> 检测到多个箱角,准备切分"; if (pVStep2OutputData->iDataSource == 0 || this->dataSourceConfig_.strRunDirection == "right") { if (this->vecContainerFail_.empty()) { VSelectBestData selectBestData; selectBestData.strDetectDate = pVStep2OutputData->strDetectDate; selectBestData.strDetectTime = pVStep2OutputData->strDetectTime; selectBestData.iDataSource = pVStep2OutputData->iDataSource; selectBestData.iFrameId = 1; selectBestData.strNumResult = "invalid-?"; selectBestData.iContainerIndex = this->iContainerIndex; selectBestData.bHaveTwoContainer = true; this->vecContainerFail_.emplace_back(selectBestData); } this->setectBestByCorner(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); if (step2ResultData.transInfo.bIsChkFlag) { this->vecContainer_.emplace_back(selectBestData); } else { this->vecContainerFail_.emplace_back(selectBestData); } return; } if (this->dataSourceConfig_.strRunDirection == "left") { LogWarn << "向左行驶的一侧暂不支持箱角识别,请及时修改参数 divide_mode: \"pixel\""; return; } } else { VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); if (step2ResultData.transInfo.bIsChkFlag) { this->vecContainer_.emplace_back(selectBestData); } else { this->vecContainerFail_.emplace_back(selectBestData); } } } /** * 切分车厢 * @param pVStep2OutputData */ void ContainerDivideEngine::divideInfo(std::shared_ptr pVStep2OutputData) { // if (!this->pVStep2OutputDataPre_) return; if (this->iContainerIndex > 1) return; if (this->vecDataSourceConfig_[pVStep2OutputData->iDataSource].strDivideModel == "corner") { this->divideByCornerInfo(pVStep2OutputData); } else { this->divideByPixelInfo(pVStep2OutputData); } } APP_ERROR ContainerDivideEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { //pop端口0 std::shared_ptr pVoidData0 = nullptr; iRet = inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr == pVoidData0) { usleep(1000); continue; } std::shared_ptr pVStep2OutputData = std::static_pointer_cast(pVoidData0); if (pVStep2OutputData->bIsEnd) { std::shared_ptr pVSelectBestData = std::make_shared(); pVSelectBestData->bIsEnd = true; pVSelectBestData->iDataSource = pVStep2OutputData->iDataSource; pVSelectBestData->strDetectDate = pVStep2OutputData->strDetectDate; pVSelectBestData->strDetectTime = pVStep2OutputData->strDetectTime; if (this->iContainerIndex > 1) { outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); this->initParam(); continue; } if (this->vecDataSourceConfig_[pVStep2OutputData->iDataSource].strDivideModel == "corner") { if (!this->vecContainerFail_.empty() || !this->vecContainer_.empty()) { this->setectBestByCorner(); } } else { if (!this->vecContainerFail_.empty()) { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } this->vecContainerFail_[iIndex].bIsEnd = true; sendBestData(this->vecContainerFail_[iIndex]); this->initParam(); continue; } } outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); this->initParam(); continue; } std::string strFilePath ; strFilePath = this->baseConfig_.strDebugResultPath + "/" + pVStep2OutputData->strDetectDate + "/" + StringUtil::getins()->replace_all_distinct(pVStep2OutputData->strDetectTime, ":", "-") + "/" + std::to_string(pVStep2OutputData->iFrameId) + "_" + std::to_string(pVStep2OutputData->iDataSource) + ".json"; // 先读取文本内容,追加新的信息后再写入 Json::Value jvFrameInfo; if (!FileUtil::getins()->readJsonInfo(jvFrameInfo, strFilePath)) { LogError << "read fail:" << strFilePath; } // jvFrameInfo["isEnd"] = (pVStep2OutputData->bIsEnd || jvFrameInfo["isEnd"].asBool()); // 识别结果存储 float fCenter = pVStep2OutputData->step2ResultData.fLTX + (pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX) / 2; // this->mapContainerCenterInfo_.insert(std::make_pair(pVStep2OutputData->iFrameId, fCenter)); Json::Value jvInfo; jvInfo["classid"] = pVStep2OutputData->step2ResultData.iClassId; jvInfo["score"] = pVStep2OutputData->step2ResultData.fScore; jvInfo["ltx"] = pVStep2OutputData->step2ResultData.fLTX; jvInfo["lty"] = pVStep2OutputData->step2ResultData.fLTY; jvInfo["rbx"] = pVStep2OutputData->step2ResultData.fRBX; jvInfo["rby"] = pVStep2OutputData->step2ResultData.fRBY; jvFrameInfo["step1"].append(jvInfo); for (auto &step2ResultData : pVStep2OutputData->vecCornerResultData) { float fCenter = step2ResultData.fLTX + (step2ResultData.fRBX - step2ResultData.fLTX) / 2; // this->mapContainerCenterInfo_.insert(std::make_pair(pVStep2OutputData->iFrameId, fCenter)); Json::Value jvInfo; jvInfo["classid"] = step2ResultData.iClassId; jvInfo["score"] = step2ResultData.fScore; jvInfo["ltx"] = step2ResultData.fLTX; jvInfo["lty"] = step2ResultData.fLTY; jvInfo["rbx"] = step2ResultData.fRBX; jvInfo["rby"] = step2ResultData.fRBY; jvFrameInfo["step1"].append(jvInfo); } FileUtil::getins()->writeJsonInfo(jvFrameInfo, strFilePath); if (pVStep2OutputData->step2ResultData.fScore != 0.0f) { LogDebug << " 帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " - "<< pVStep2OutputData->step2ResultData.transInfo.strTmpResult; } this->divideInfo(pVStep2OutputData); } return APP_ERR_OK; } \ No newline at end of file diff --git a/engine/MergeEngine/Step1MergeEngine.cpp b/engine/MergeEngine/Step1MergeEngine.cpp index 06f0024..eeb46a8 100644 --- a/engine/MergeEngine/Step1MergeEngine.cpp +++ b/engine/MergeEngine/Step1MergeEngine.cpp @@ -1 +1 @@ -#include "Step1MergeEngine.h" using namespace ai_matrix; namespace { //按照x坐标排列 bool CompareX(const SingleData &a, const SingleData &b) { return a.fLTX < b.fLTX; } } Step1MergeEngine::Step1MergeEngine() {} Step1MergeEngine::~Step1MergeEngine() {} APP_ERROR Step1MergeEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; this->baseConfig_ = Config::getins()->getBaseConfig(); this->identifyConfig_ = Config::getins()->getIdentifyConfig(); this->multiTypeQueue_ = new ai_matrix::MultiTypeQueue(2); LogInfo << "MergeEngine Init ok"; return APP_ERR_OK; } APP_ERROR Step1MergeEngine::DeInit() { LogInfo << "MergeEngine DeInit ok"; return APP_ERR_OK; } APP_ERROR Step1MergeEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { std::shared_ptr pVoidData0 = nullptr; inputQueMap_[strPort0_]->pop(pVoidData0); std::shared_ptr pVoidData1 = nullptr; inputQueMap_[strPort1_]->pop(pVoidData1); if (nullptr == pVoidData0 && nullptr == pVoidData1) { usleep(1000); //1ms continue; } if (pVoidData0) { this->multiTypeQueue_->PushData(0, pVoidData0); } if (pVoidData1) { this->multiTypeQueue_->PushData(1, pVoidData1); } if (!this->multiTypeQueue_->PopAllData(pVoidData0, pVoidData1)) { usleep(1000); //1ms continue; } std::shared_ptr pInferenceResultData = std::static_pointer_cast(pVoidData0); std::shared_ptr pInferenceResultData_container = std::static_pointer_cast(pVoidData1); pInferenceResultData->vecSingleData = pInferenceResultData_container->vecSingleData; std::sort(pInferenceResultData->vecSingleData.begin(), pInferenceResultData->vecSingleData.end(), CompareX); if (pInferenceResultData->singleData.fScore > 0.0f) { // 箱号 // LogDebug << " 帧:" << pInferenceResultData->iFrameId // << " 数据源:" << pInferenceResultData->iDataSource // << " --iClassId:" << pInferenceResultData->singleData.iClassId // << " confidence=" << pInferenceResultData->singleData.fScore // << " lx=" << pInferenceResultData->singleData.fLTX // << " ly=" << pInferenceResultData->singleData.fLTY // << " rx=" << pInferenceResultData->singleData.fRBX // << " ry=" << pInferenceResultData->singleData.fRBY // << " clear:" << pInferenceResultData->singleData.fClear; } // 箱角 for (const auto & it_result : pInferenceResultData->vecSingleData) { LogDebug << " 帧:" << pInferenceResultData->iFrameId << " 数据源:" << pInferenceResultData->iDataSource << " --iClassId:" << it_result.iClassId << " confidence=" << it_result.fScore << " lx=" << it_result.fLTX << " ly=" << it_result.fLTY << " rx=" << it_result.fRBX << " ry=" << it_result.fRBY; } outputQueMap_[strPort0_]->push(std::static_pointer_cast(pInferenceResultData), true); } return APP_ERR_OK; } \ No newline at end of file +#include "Step1MergeEngine.h" using namespace ai_matrix; namespace { //按照x坐标排列 bool CompareX(const SingleData &a, const SingleData &b) { return a.fLTX < b.fLTX; } } Step1MergeEngine::Step1MergeEngine() {} Step1MergeEngine::~Step1MergeEngine() {} APP_ERROR Step1MergeEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; this->baseConfig_ = Config::getins()->getBaseConfig(); this->identifyConfig_ = Config::getins()->getIdentifyConfig(); this->multiTypeQueue_ = new ai_matrix::MultiTypeQueue(2); LogInfo << "MergeEngine Init ok"; return APP_ERR_OK; } APP_ERROR Step1MergeEngine::DeInit() { LogInfo << "MergeEngine DeInit ok"; return APP_ERR_OK; } APP_ERROR Step1MergeEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { std::shared_ptr pVoidData0 = nullptr; inputQueMap_[strPort0_]->pop(pVoidData0); std::shared_ptr pVoidData1 = nullptr; inputQueMap_[strPort1_]->pop(pVoidData1); if (nullptr == pVoidData0 && nullptr == pVoidData1) { usleep(1000); //1ms continue; } if (pVoidData0) { this->multiTypeQueue_->PushData(0, pVoidData0); } if (pVoidData1) { this->multiTypeQueue_->PushData(1, pVoidData1); } if (!this->multiTypeQueue_->PopAllData(pVoidData0, pVoidData1)) { usleep(1000); //1ms continue; } std::shared_ptr pInferenceResultData = std::static_pointer_cast(pVoidData0); std::shared_ptr pInferenceResultData_container = std::static_pointer_cast(pVoidData1); pInferenceResultData->vecSingleData = pInferenceResultData_container->vecSingleData; std::sort(pInferenceResultData->vecSingleData.begin(), pInferenceResultData->vecSingleData.end(), CompareX); if (pInferenceResultData->singleData.fScore > 0.0f) { // 箱号 LogDebug << " 帧:" << pInferenceResultData->iFrameId << " 数据源:" << pInferenceResultData->iDataSource << " --iClassId:" << pInferenceResultData->singleData.iClassId << " confidence=" << pInferenceResultData->singleData.fScore << " lx=" << pInferenceResultData->singleData.fLTX << " ly=" << pInferenceResultData->singleData.fLTY << " rx=" << pInferenceResultData->singleData.fRBX << " ry=" << pInferenceResultData->singleData.fRBY << " clear:" << pInferenceResultData->singleData.fClear; } // 箱角 for (const auto & it_result : pInferenceResultData->vecSingleData) { LogDebug << " 帧:" << pInferenceResultData->iFrameId << " 数据源:" << pInferenceResultData->iDataSource << " --iClassId:" << it_result.iClassId << " confidence=" << it_result.fScore << " lx=" << it_result.fLTX << " ly=" << it_result.fLTY << " rx=" << it_result.fRBX << " ry=" << it_result.fRBY; } outputQueMap_[strPort0_]->push(std::static_pointer_cast(pInferenceResultData), true); } return APP_ERR_OK; } \ No newline at end of file diff --git a/engine/SaveDebugImageEngine/SaveDebugImageEngine.cpp b/engine/SaveDebugImageEngine/SaveDebugImageEngine.cpp index 160366c..95d8729 100644 --- a/engine/SaveDebugImageEngine/SaveDebugImageEngine.cpp +++ b/engine/SaveDebugImageEngine/SaveDebugImageEngine.cpp @@ -43,6 +43,7 @@ APP_ERROR SaveDebugImageEngine::Process() } std::shared_ptr pVStep2OutputData = std::static_pointer_cast(pvoidd); + cv::Mat image = pVStep2OutputData->cvImage.clone(); std::string strDataDir = this->baseConfig_.strDebugResultPath + "/" + pVStep2OutputData->strDetectDate + "/" @@ -66,9 +67,9 @@ APP_ERROR SaveDebugImageEngine::Process() // cv::Mat image = cv::imread(strImagePath); - if (pVStep2OutputData->cvImage.empty()) + if (image.empty()) { - LogWarn << " 帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " debug图像未找到"; +// LogWarn << " 帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " debug图像未找到"; continue; } @@ -86,7 +87,7 @@ APP_ERROR SaveDebugImageEngine::Process() cv::Size text_size = cv::getTextSize(i, cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0); cv::Point baseline_loc(text_org); baseline_loc.y += base_line + text_size.height; - cv::putText(pVStep2OutputData->cvImage, i, baseline_loc, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0, 255), 2); + cv::putText(image, i, baseline_loc, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0, 255), 2); // 手动调整x位置,为下一个单词留出空间 text_org.x += text_size.width + 10; text_org.x = text_org.x > IMAGE_WIDTH ? 15 : text_org.x; @@ -98,17 +99,17 @@ APP_ERROR SaveDebugImageEngine::Process() float centerX = pVStep2OutputData->step2ResultData.fLTX + (pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX)/2; float centerY = pVStep2OutputData->step2ResultData.fLTY + (pVStep2OutputData->step2ResultData.fRBY - pVStep2OutputData->step2ResultData.fLTY)/2; // auto start = std::chrono::system_clock::now(); //计时开始 - cv::rectangle(pVStep2OutputData->cvImage, + cv::rectangle(image, cv::Point(pVStep2OutputData->step2ResultData.fLTX, pVStep2OutputData->step2ResultData.fLTY), cv::Point(pVStep2OutputData->step2ResultData.fRBX, pVStep2OutputData->step2ResultData.fRBY), cvScalar, 2); - cv::line(pVStep2OutputData->cvImage, + cv::line(image, cv::Point(centerX, pVStep2OutputData->step2ResultData.fLTY-30), cv::Point(centerX, pVStep2OutputData->step2ResultData.fRBY+30), cvScalar, 1); cv::Size text_size = cv::getTextSize(pVStep2OutputData->step2ResultData.transInfo.strTmpResult, cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0); cv::Point linePoint(pVStep2OutputData->step2ResultData.fLTX, pVStep2OutputData->step2ResultData.fRBY + text_size.height + 5); - cv::putText(pVStep2OutputData->cvImage, + cv::putText(image, pVStep2OutputData->step2ResultData.transInfo.strTmpResult, linePoint, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0, 180), 2); @@ -118,11 +119,11 @@ APP_ERROR SaveDebugImageEngine::Process() { cvScalar = {0, 255, 255, 255}; float centerX_corner = step2ResultData.fLTX + (step2ResultData.fRBX - step2ResultData.fLTX)/2; - cv::rectangle(pVStep2OutputData->cvImage, + cv::rectangle(image, cv::Point(step2ResultData.fLTX, step2ResultData.fLTY), cv::Point(step2ResultData.fRBX, step2ResultData.fRBY), cvScalar, 2); - cv::line(pVStep2OutputData->cvImage, + cv::line(image, cv::Point(centerX_corner, step2ResultData.fLTY-30), cv::Point(centerX_corner, step2ResultData.fRBY+30), cvScalar, 1); } @@ -131,7 +132,7 @@ APP_ERROR SaveDebugImageEngine::Process() // auto end = std::chrono::system_clock::now(); // LogDebug << "图片存储用时: " << std::chrono::duration_cast(end - start).count() << "ms " << strImagePath; - if (!cv::imwrite(strImagePath, pVStep2OutputData->cvImage, this->vecCompressionParams_)) + if (!cv::imwrite(strImagePath, image, this->vecCompressionParams_)) { LogError << "图片存储失败:" << strImagePath; } diff --git a/engine/SaveDebugImageEngine/SaveDebugImageEngine.h b/engine/SaveDebugImageEngine/SaveDebugImageEngine.h index bfb36a3..feb499d 100644 --- a/engine/SaveDebugImageEngine/SaveDebugImageEngine.h +++ b/engine/SaveDebugImageEngine/SaveDebugImageEngine.h @@ -24,7 +24,7 @@ private: ai_matrix::BaseConfig baseConfig_; std::string strPort0_; - int iPicQuality_ = 100; + int iPicQuality_ = 80; std::vector vecCompressionParams_; }; diff --git a/engine/SelectBestEngine/SelectBestEngine.cpp b/engine/SelectBestEngine/SelectBestEngine.cpp index 0f59f4f..897acf9 100644 --- a/engine/SelectBestEngine/SelectBestEngine.cpp +++ b/engine/SelectBestEngine/SelectBestEngine.cpp @@ -99,10 +99,24 @@ void SelectBestEngine::selectBest() auto contains = [] (const std::vector& vec, std::string value) -> bool { return std::find(vec.begin(), vec.end(), value) != vec.end(); }; + auto vCompare = [](std::string a, std::string b) { + if (a.size() != b.size()) return 999; + + int count = 0; + for (int i = 0; i < a.size(); ++i) + { + if (a[i] != b[i]) + { + ++count; + } + } + return count; + }; DetectResultData detectResultData; detectResultData.strDetectDate = this->strDetectDate_; detectResultData.strDetectTime = this->strDetectTime_; + std::string strAlternativeResult; bool bHaveTwoContainer = false; for (auto & it_container : this->mapIndex_Containers_) { bool bHaveVerify = false; @@ -129,21 +143,39 @@ void SelectBestEngine::selectBest() count = it_max.second; if (!contains(detectResultData.vecContainerNO, it_max.first)) { strBestContainer = it_max.first; + break; + } + } + } + if (mapContainer_count.size() > 1) + { + for (auto &it_max : mapContainer_count) + { + if (it_max.first != strBestContainer && vCompare(it_max.first, strBestContainer) > 2) + { + strAlternativeResult = it_max.first; } } } detectResultData.vecContainerNO.emplace_back(strBestContainer); } else { - // 取识别字数最长的 - std::string strBestContainer; - int iMaxSize = 0; - for (auto &it_max: mapContainer_count) { - if (it_max.first.size() > iMaxSize) { - iMaxSize = it_max.first.size(); - strBestContainer = it_max.first; - } + if (detectResultData.vecContainerNO.size() == 1 && !strAlternativeResult.empty()) + { + detectResultData.vecContainerNO.emplace_back(strAlternativeResult); + } + else + { + // 取识别字数最长的 + std::string strBestContainer; + int iMaxSize = 0; + for (auto &it_max: mapContainer_count) { + if (it_max.first.size() > iMaxSize) { + iMaxSize = it_max.first.size(); + strBestContainer = it_max.first; + } + } + detectResultData.vecContainerNO.emplace_back(strBestContainer); } - detectResultData.vecContainerNO.emplace_back(strBestContainer); } } if (bHaveTwoContainer && detectResultData.vecContainerNO.size() < 2) @@ -175,6 +207,12 @@ APP_ERROR SelectBestEngine::Process() if (pVSelectBestData->bIsEnd) { + if (this->strDetectDate_.empty()) + { + this->strDetectDate_ = pVSelectBestData->strDetectDate; + this->strDetectTime_ = pVSelectBestData->strDetectTime; + } + this->iEndCount_++; if (!(this->iEndCount_ % this->vecDataSourceConfig_.size())) { @@ -183,6 +221,7 @@ APP_ERROR SelectBestEngine::Process() } continue; } + this->iEndCount_ = 0; if (this->strImagePath_.empty()) { diff --git a/engine/Step1InferenceEngine/ContainerStep1InferenceEngine.cpp b/engine/Step1InferenceEngine/ContainerStep1InferenceEngine.cpp index 09c0ca1..1328405 100644 --- a/engine/Step1InferenceEngine/ContainerStep1InferenceEngine.cpp +++ b/engine/Step1InferenceEngine/ContainerStep1InferenceEngine.cpp @@ -268,6 +268,7 @@ APP_ERROR ContainerStep1InferenceEngine::Process() if (pVDetectInfo->cvImage.empty()) { + outputQueMap_[strPort0_]->push(std::static_pointer_cast(pInferenceResultData), true); usleep(1000); //1ms continue; } @@ -290,7 +291,7 @@ APP_ERROR ContainerStep1InferenceEngine::Process() pInferenceResultData->strDetectDate = pVDetectInfo->strDetectDate; pInferenceResultData->strDetectTime = pVDetectInfo->strDetectTime; - pInferenceResultData->cvImage = pVDetectInfo->cvImage; + pInferenceResultData->cvImage = pVDetectInfo->cvImage.clone(); // 筛选离中心点坐标最近的,如果一样近就选最右的 float fCenterX = IMAGE_WIDTH/2; @@ -323,7 +324,7 @@ APP_ERROR ContainerStep1InferenceEngine::Process() singledata.fLTY = inferenceResult.bbox[1]; singledata.fRBX = inferenceResult.bbox[2]; singledata.fRBY = inferenceResult.bbox[3]; - singledata.fClear = inferenceResult.clear_id; + singledata.fClear = inferenceResult.clear_conf; pInferenceResultData->singleData = singledata; diff --git a/engine/Step2InferenceEngine/ContainerStep2InferenceEngine.cpp b/engine/Step2InferenceEngine/ContainerStep2InferenceEngine.cpp index f6f7d68..e6acd64 100644 --- a/engine/Step2InferenceEngine/ContainerStep2InferenceEngine.cpp +++ b/engine/Step2InferenceEngine/ContainerStep2InferenceEngine.cpp @@ -1 +1 @@ -#include "ContainerStep2InferenceEngine.h" #include #include "myqueue.h" using namespace ai_matrix; ContainerStep2InferenceEngine::ContainerStep2InferenceEngine() {} ContainerStep2InferenceEngine::~ContainerStep2InferenceEngine() {} APP_ERROR ContainerStep2InferenceEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; this->modelConfig_ = Config::getins()->getModelByContainerStep2Config(); //读取模型信息 int iFolderExist = access(modelConfig_.strModelPath.c_str(), R_OK); if (iFolderExist == -1) { LogError << "模型:" << modelConfig_.strModelPath << " 不存在!"; return false; } class_num = this->modelConfig_.vecClass.size(); score_threshold = this->modelConfig_.fScoreThreshold; input_size = GET_INPUT_SIZE(model_width , model_height); output_size = GET_OUTPUT_SIZE(model_width, model_height, clear_num, class_num); det_size = clear_num + class_num + 5; int ret = initModel(); if (ret != APP_ERR_OK) { LogError << "Failed to read model info, ret = " << ret; return ret; } LogInfo << "ContainerStep2InferenceEngine Init ok"; return APP_ERR_OK; } APP_ERROR ContainerStep2InferenceEngine::initModel() { modelinfo.yolov5ClearityModelParam.uiClassNum = class_num; modelinfo.yolov5ClearityModelParam.uiClearNum = clear_num; modelinfo.yolov5ClearityModelParam.uiDetSize = det_size; modelinfo.yolov5ClearityModelParam.fScoreThreshold = score_threshold; modelinfo.yolov5ClearityModelParam.fNmsThreshold = nms_threshold; 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 = yolov5model.YoloV5ClearityInferenceInit(&modelinfo, strModelName, this->modelConfig_.strModelPath); if (nRet != 0) { LogInfo << "YoloV5ClassifyInferenceInit nRet:" << nRet; return APP_ERR_COMM_READ_FAIL; } return APP_ERR_OK; } APP_ERROR ContainerStep2InferenceEngine::DeInit() { yolov5model.YoloV5ClearityInferenceDeinit(); LogInfo << "ContainerStep2InferenceEngine DeInit ok"; return APP_ERR_OK; } void ContainerStep2InferenceEngine::resetLocation(SingleData &singleData, SingleData &step1SingleData, float fResizeRatio) { singleData.fLTX = singleData.fLTX * fResizeRatio + step1SingleData.fLTX; singleData.fLTY = singleData.fLTY * fResizeRatio + step1SingleData.fLTY; singleData.fRBX = singleData.fRBX * fResizeRatio + step1SingleData.fLTX; singleData.fRBY = singleData.fRBY * fResizeRatio + step1SingleData.fLTY; singleData.fLTX = (singleData.fLTX < IMAGE_WIDTH) ? singleData.fLTX : IMAGE_WIDTH; singleData.fLTY = (singleData.fLTY < IMAGE_HEIGHT) ? singleData.fLTY : IMAGE_HEIGHT; singleData.fRBX = (singleData.fRBX < IMAGE_WIDTH) ? singleData.fRBX : IMAGE_WIDTH; singleData.fRBY = (singleData.fRBY < IMAGE_HEIGHT) ? singleData.fRBY : IMAGE_HEIGHT; } APP_ERROR ContainerStep2InferenceEngine::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); std::shared_ptr pVStep2OutputData = std::make_shared(); pVStep2OutputData->iDataSource = pInferenceResultData->iDataSource; pVStep2OutputData->bIsEnd = pInferenceResultData->bIsEnd; pVStep2OutputData->strDetectDate = pInferenceResultData->strDetectDate; pVStep2OutputData->strDetectTime = pInferenceResultData->strDetectTime; pVStep2OutputData->cvImage = pInferenceResultData->cvImage; if (pInferenceResultData->bIsEnd) { outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVStep2OutputData), true); continue; } pVStep2OutputData->strDetectDate = pInferenceResultData->strDetectDate; pVStep2OutputData->strDetectTime = pInferenceResultData->strDetectTime; pVStep2OutputData->iFrameId = pInferenceResultData->iFrameId; // LogWarn << "-- 0 -->" << pVStep2InputData->vecSingleData.size(); for (auto & single : pInferenceResultData->vecSingleData) { Step2ResultData step2ResultData; step2ResultData.fLTX = single.fLTX; step2ResultData.fLTY = single.fLTY; step2ResultData.fRBX = single.fRBX; step2ResultData.fRBY = single.fRBY; step2ResultData.iClassId = single.iClassId; step2ResultData.fScore = single.fScore; step2ResultData.iTrainIndex = single.iTrainIndex; if (single.iTargetType == CORNER) { pVStep2OutputData->vecCornerResultData.emplace_back(step2ResultData); continue; }; } if (pInferenceResultData->singleData.fScore > 0.0f) { pVStep2OutputData->step2ResultData.fLTX = pInferenceResultData->singleData.fLTX; pVStep2OutputData->step2ResultData.fLTY = pInferenceResultData->singleData.fLTY; pVStep2OutputData->step2ResultData.fRBX = pInferenceResultData->singleData.fRBX; pVStep2OutputData->step2ResultData.fRBY = pInferenceResultData->singleData.fRBY; pVStep2OutputData->step2ResultData.iClassId = pInferenceResultData->singleData.iClassId; pVStep2OutputData->step2ResultData.fScore = pInferenceResultData->singleData.fScore; pVStep2OutputData->step2ResultData.iTrainIndex = pInferenceResultData->singleData.iTrainIndex; cv::Rect rect(cv::Point(pInferenceResultData->singleData.fLTX, pInferenceResultData->singleData.fLTY), cv::Point(pInferenceResultData->singleData.fRBX, pInferenceResultData->singleData.fRBY)); cv::Mat image = pInferenceResultData->cvImage(rect).clone(); //进行推理 std::vector vecInferenceResult; auto start = std::chrono::system_clock::now(); // 计时开始 yolov5model.YoloV5ClearityInferenceModel(image, vecInferenceResult, 2); auto end = std::chrono::system_clock::now(); for (const auto & j : vecInferenceResult) { if (j.class_conf < STEP2_SCORE_THRESH) { continue; } SingleData singledata; singledata.iLine = j.clear_id; singledata.iClassId = j.class_id; singledata.fScore = j.class_conf; singledata.fLTX = j.bbox[0]; singledata.fLTY = j.bbox[1]; singledata.fRBX = j.bbox[2]; singledata.fRBY = j.bbox[3]; this->resetLocation(singledata, pInferenceResultData->singleData); pVStep2OutputData->step2ResultData.vecSingleData.emplace_back(singledata); // LogDebug << "frameId:" << pVStep2OutputData->iFrameId // << " --iClassId:" << singledata.iClassId // << " iLine:" << singledata.iLine // << " score=" << singledata.fScore // << " [" // << singledata.fLTX << "," << singledata.fLTY // << "],[" // << singledata.fRBX << "," << singledata.fRBY // << "]"; } } outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVStep2OutputData), true); } return APP_ERR_OK; } \ No newline at end of file +#include "ContainerStep2InferenceEngine.h" #include #include "myqueue.h" using namespace ai_matrix; ContainerStep2InferenceEngine::ContainerStep2InferenceEngine() {} ContainerStep2InferenceEngine::~ContainerStep2InferenceEngine() {} APP_ERROR ContainerStep2InferenceEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; this->modelConfig_ = Config::getins()->getModelByContainerStep2Config(); //读取模型信息 int iFolderExist = access(modelConfig_.strModelPath.c_str(), R_OK); if (iFolderExist == -1) { LogError << "模型:" << modelConfig_.strModelPath << " 不存在!"; return false; } class_num = this->modelConfig_.vecClass.size(); score_threshold = this->modelConfig_.fScoreThreshold; input_size = GET_INPUT_SIZE(model_width , model_height); output_size = GET_OUTPUT_SIZE(model_width, model_height, clear_num, class_num); det_size = clear_num + class_num + 5; int ret = initModel(); if (ret != APP_ERR_OK) { LogError << "Failed to read model info, ret = " << ret; return ret; } LogInfo << "ContainerStep2InferenceEngine Init ok"; return APP_ERR_OK; } APP_ERROR ContainerStep2InferenceEngine::initModel() { modelinfo.yolov5ClearityModelParam.uiClassNum = class_num; modelinfo.yolov5ClearityModelParam.uiClearNum = clear_num; modelinfo.yolov5ClearityModelParam.uiDetSize = det_size; modelinfo.yolov5ClearityModelParam.fScoreThreshold = score_threshold; modelinfo.yolov5ClearityModelParam.fNmsThreshold = nms_threshold; 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 = yolov5model.YoloV5ClearityInferenceInit(&modelinfo, strModelName, this->modelConfig_.strModelPath); if (nRet != 0) { LogInfo << "YoloV5ClassifyInferenceInit nRet:" << nRet; return APP_ERR_COMM_READ_FAIL; } return APP_ERR_OK; } APP_ERROR ContainerStep2InferenceEngine::DeInit() { yolov5model.YoloV5ClearityInferenceDeinit(); LogInfo << "ContainerStep2InferenceEngine DeInit ok"; return APP_ERR_OK; } void ContainerStep2InferenceEngine::resetLocation(SingleData &singleData, SingleData &step1SingleData, float fResizeRatio) { singleData.fLTX = singleData.fLTX * fResizeRatio + step1SingleData.fLTX; singleData.fLTY = singleData.fLTY * fResizeRatio + step1SingleData.fLTY; singleData.fRBX = singleData.fRBX * fResizeRatio + step1SingleData.fLTX; singleData.fRBY = singleData.fRBY * fResizeRatio + step1SingleData.fLTY; singleData.fLTX = (singleData.fLTX < IMAGE_WIDTH) ? singleData.fLTX : IMAGE_WIDTH; singleData.fLTY = (singleData.fLTY < IMAGE_HEIGHT) ? singleData.fLTY : IMAGE_HEIGHT; singleData.fRBX = (singleData.fRBX < IMAGE_WIDTH) ? singleData.fRBX : IMAGE_WIDTH; singleData.fRBY = (singleData.fRBY < IMAGE_HEIGHT) ? singleData.fRBY : IMAGE_HEIGHT; } APP_ERROR ContainerStep2InferenceEngine::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); std::shared_ptr pVStep2OutputData = std::make_shared(); // VStep2OutputData vStep2OutputData; pVStep2OutputData->iFrameId = pInferenceResultData->iFrameId; pVStep2OutputData->iDataSource = pInferenceResultData->iDataSource; pVStep2OutputData->bIsEnd = pInferenceResultData->bIsEnd; pVStep2OutputData->strDetectDate = pInferenceResultData->strDetectDate; pVStep2OutputData->strDetectTime = pInferenceResultData->strDetectTime; pVStep2OutputData->cvImage = pInferenceResultData->cvImage.clone(); // *pVStep2OutputData = vStep2OutputData; if (pInferenceResultData->bIsEnd) { outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVStep2OutputData), true); continue; } if (pInferenceResultData->cvImage.empty()) { // LogWarn << " 帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " 所传图像为空"; outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVStep2OutputData), true); usleep(1000); //1ms continue; } // LogWarn << "-- 0 -->" << pInferenceResultData->vecSingleData.size(); for (auto & single : pInferenceResultData->vecSingleData) { Step2ResultData step2ResultData; step2ResultData.fLTX = single.fLTX; step2ResultData.fLTY = single.fLTY; step2ResultData.fRBX = single.fRBX; step2ResultData.fRBY = single.fRBY; step2ResultData.iClassId = single.iClassId; step2ResultData.fScore = single.fScore; step2ResultData.iTrainIndex = single.iTrainIndex; if (single.iTargetType == CORNER) { pVStep2OutputData->vecCornerResultData.emplace_back(step2ResultData); continue; }; } // LogInfo << " -V--- " << pInferenceResultData->singleData.fScore; if (pInferenceResultData->singleData.fScore > 0.0f) { pVStep2OutputData->step2ResultData.fLTX = pInferenceResultData->singleData.fLTX; pVStep2OutputData->step2ResultData.fLTY = pInferenceResultData->singleData.fLTY; pVStep2OutputData->step2ResultData.fRBX = pInferenceResultData->singleData.fRBX; pVStep2OutputData->step2ResultData.fRBY = pInferenceResultData->singleData.fRBY; pVStep2OutputData->step2ResultData.iClassId = pInferenceResultData->singleData.iClassId; pVStep2OutputData->step2ResultData.fScore = pInferenceResultData->singleData.fScore; pVStep2OutputData->step2ResultData.iTrainIndex = pInferenceResultData->singleData.iTrainIndex; cv::Rect rect(cv::Point(pInferenceResultData->singleData.fLTX, pInferenceResultData->singleData.fLTY), cv::Point(pInferenceResultData->singleData.fRBX, pInferenceResultData->singleData.fRBY)); cv::Mat image = pInferenceResultData->cvImage(rect).clone(); //进行推理 std::vector vecInferenceResult; auto start = std::chrono::system_clock::now(); // 计时开始 yolov5model.YoloV5ClearityInferenceModel(image, vecInferenceResult, 2); auto end = std::chrono::system_clock::now(); for (const auto & j : vecInferenceResult) { if (j.class_conf < STEP2_SCORE_THRESH) { continue; } SingleData singledata; singledata.iLine = j.clear_id; singledata.iClassId = j.class_id; singledata.fScore = j.class_conf; singledata.fLTX = j.bbox[0]; singledata.fLTY = j.bbox[1]; singledata.fRBX = j.bbox[2]; singledata.fRBY = j.bbox[3]; this->resetLocation(singledata, pInferenceResultData->singleData); pVStep2OutputData->step2ResultData.vecSingleData.emplace_back(singledata); // LogDebug << "frameId:" << pVStep2OutputData->iFrameId // << " --iClassId:" << singledata.iClassId // << " iLine:" << singledata.iLine // << " score=" << singledata.fScore // << " [" // << singledata.fLTX << "," << singledata.fLTY // << "],[" // << singledata.fRBX << "," << singledata.fRBY // << "]"; } } outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVStep2OutputData), true); } return APP_ERR_OK; } \ No newline at end of file