增加侧边右向行车摄像头使用箱角进行切分

This commit is contained in:
zhangwei 2025-02-13 18:43:42 +08:00
parent bdaaf2eca4
commit 0b8eadd54a
21 changed files with 247 additions and 120 deletions

View File

@ -70,6 +70,8 @@ namespace ai_matrix
this->identifyConfig_.iTargetMinWidth = config_["identify"]["target_min_width"].as<int>(); this->identifyConfig_.iTargetMinWidth = config_["identify"]["target_min_width"].as<int>();
this->identifyConfig_.iTargetMinY = config_["identify"]["target_min_y"].as<int>(); this->identifyConfig_.iTargetMinY = config_["identify"]["target_min_y"].as<int>();
this->identifyConfig_.iMaxIdentifyFrame = config_["identify"]["max_identify_frame"].as<int>(); this->identifyConfig_.iMaxIdentifyFrame = config_["identify"]["max_identify_frame"].as<int>();
this->identifyConfig_.iMaxContainerSpaceX = config_["identify"]["max_container_space_x"].as<int>();
this->identifyConfig_.iMaxContainerSpaceY = config_["identify"]["max_container_space_y"].as<int>();
// websocket server 服务端参数 // websocket server 服务端参数
this->wSocketConfig_.bIsUse = config_["wsocket_server"]["is_use"].as<bool>(); this->wSocketConfig_.bIsUse = config_["wsocket_server"]["is_use"].as<bool>();

View File

@ -88,6 +88,10 @@ namespace ai_matrix
int iTargetMinY; int iTargetMinY;
// 单次识别最大帧数 // 单次识别最大帧数
int iMaxIdentifyFrame; int iMaxIdentifyFrame;
// 两个箱子的箱角最大差值X
int iMaxContainerSpaceX;
// 两个箱子的箱角最大差值Y
int iMaxContainerSpaceY;
}; };
// websocket_server 的服务端参数 // websocket_server 的服务端参数

View File

@ -1,7 +1,7 @@
# 基础控制参数 # 基础控制参数
base: base:
# 股道名称 # 股道名称
track_name: "1" track_name: "1"
# 测试模式 # 测试模式
test_model: false test_model: false
# Api 监听端口 # Api 监听端口
@ -24,43 +24,63 @@ log:
# 数据源参数 # 数据源参数
data_source: data_source:
url: "./vedio/buertai2.mp4" - # 顶部摄像头(必须顶部摄像头)
# 跳帧数 url: "./videos/buertai2.mp4"
skip_interval: 3 # 跳帧数
# 行驶方向 0-自动识别 1-向左 2-向右 (与“首位信息”成对存在,形成例如向左就编号在前,向右就属性在前的对应) skip_interval: 3
direction: 0 # 识别区域
# 0-向左编号在前 1-向左属性在前 (向右行驶的情况2-向右编号在前 3-向右属性在前) identify_areas: [120, 0, 1800, 1080]
left_first: 0 # 切箱方式
# (向左行驶的情况0-向左编号在前 1-向左属性在前) 2-向右编号在前 3-向右属性在前 divide_mode: "corner" #[corner, pixel]
right_first: 3 # 汽车行进方向
# 识别区域 run_direction: "down" #[up, down, left, right]
identify_areas: [120, 0, 1800, 1080] - # 侧部摄像头
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: identify:
# 运行方式 # 切箱方式
run_mode: "always" #[always; command] divide_mode: "corner" #[corner, pixel]
# 是否开启动态检测
need_move_detect_flag: true
# 识别方向 [LEFT,RIGHT,ALL]
identify_direction: "LEFT"
# 大框帧跨度(比一个大框从出现到消失的跨度稍大一点, 跟跳帧有关系) # 大框帧跨度(比一个大框从出现到消失的跨度稍大一点, 跟跳帧有关系)
partition_frame_span: 20 partition_frame_span: 0
# 大框帧跨度的位置像素差异 # 顶部Y轴大框帧跨度的位置像素差异
split_frame_span_px: 200 top_y_split_span_px: 200
# 侧边X轴大框帧跨度的位置像素差异
side_x_split_span_px: 600
# 每帧大框位置差异最小值 (持续小于此值,则可能停车) # 每帧大框位置差异最小值 (持续小于此值,则可能停车)
chkstop_px: 15 chkstop_px: 15
# 持续X次续位置差异小于gc_chkstop_px则判断为停车。 # 持续X次续位置差异小于gc_chkstop_px则判断为停车。
chkstop_count: 10 chkstop_count: 10
# 过滤最小大框高度(不需要的话就写个很小的值) # 过滤最小大框高度(不需要的话就写个很小的值)
num_frame_height: 150 target_min_height: 95
pro_frame_height: 120 # 过滤最小大框宽度(不需要的话就写个很小的值)
# 过滤最大框宽度(不需要的话就写个很大的值) target_min_width: 50
space_frame_width: 500 # 过滤低于指定Y轴的大框
# 是否识别车头 target_min_y: 550
train_heard_detect: false # 单次识别最大帧数
# 是否识别集装箱 max_identify_frame: 600
container_detect: false # 两个箱子的箱角最大差值X
max_container_space_x: 600
# 两个箱子的箱角最大差值Y
max_container_space_y: 500
# websocket_server 的服务端参数 # websocket_server 的服务端参数
wsocket_server: wsocket_server:

View File

@ -1,44 +1,56 @@
#use_deviceid:
# #engineid: deviceid
# 0: 0
#engine实例 #engine实例
engines: engines:
ApiEngine: 0 ApiEngine: 0
DeleteExpiredFolderEngine: 0
WSServerEngine: 0
VideoEngine: 0 VideoEngine: 0
VideoEngine: 1
VideoEngine: 2
VideoDecodeEngine: 0 VideoDecodeEngine: 0
MoveEngine: 0 VideoDecodeEngine: 1
SaveMoveImageEngine: 0 VideoDecodeEngine: 2
ControlEngine: 0
# SaveMoveImageEngine: 0
SaveMoveInfoEngine: 0 SaveMoveInfoEngine: 0
TrainStep1DataReadEngine: 0 ContainerStep1InferenceEngine: 0
TrainStep1InferenceEngine: 0 CornerInferenceEngine: 0
TrainStep1FilterEngine: 0 Step1MergeEngine: 0
TrainDivideEngine: 0 ContainerStep2InferenceEngine: 0
TrainStep2DataReadEngine: 0 ContainerCharacterConversionEngine: 0
TrainStep2InferenceEngine: 0 ContainerDivideEngine: 0
TrainCharacterConversionEngine: 0 ContainerDivideEngine: 1
ContainerDivideEngine: 2
SelectBestEngine: 0 SelectBestEngine: 0
SaveResultCSVEngine: 0 SaveResultCSVEngine: 0
ToHttpSrvEngine: 0
ToMinioSrvEngine: 0 ToMinioSrvEngine: 0
SaveDebugImageEngine: 0 SaveDebugImageEngine: 0
#engine连接 #engine连接
connects: connects:
WSServerEngine_0_0: "ControlEngine_0_0 1024"
VideoEngine_0_0: "VideoDecodeEngine_0_0 1024" VideoEngine_0_0: "VideoDecodeEngine_0_0 1024"
VideoDecodeEngine_0_0: "MoveEngine_0_0 1024" VideoEngine_1_0: "VideoDecodeEngine_1_0 1024"
MoveEngine_0_0: "SaveMoveImageEngine_0_0 1024" VideoEngine_2_0: "VideoDecodeEngine_2_0 1024"
MoveEngine_0_1: "SaveMoveInfoEngine_0_0 1024" VideoDecodeEngine_0_0: "ControlEngine_0_1 1024"
SaveMoveImageEngine_0_0: "TrainStep1DataReadEngine_0_0 1024" VideoDecodeEngine_1_0: "ControlEngine_0_1 1024"
TrainStep1DataReadEngine_0_0: "TrainStep1InferenceEngine_0_0 1024" VideoDecodeEngine_2_0: "ControlEngine_0_1 1024"
TrainStep1InferenceEngine_0_0: "TrainStep1FilterEngine_0_0 1024" ControlEngine_0_0: "WSServerEngine_0_0 1024"
TrainStep1FilterEngine_0_0: "TrainDivideEngine_0_0 1024" ControlEngine_0_1: "ContainerStep1InferenceEngine_0_0 1024"
TrainDivideEngine_0_0: "TrainStep2DataReadEngine_0_0 1024" ControlEngine_0_2: "CornerInferenceEngine_0_0 1024"
TrainStep2DataReadEngine_0_0: "TrainStep2InferenceEngine_0_0 1024" ControlEngine_0_3: "SaveMoveInfoEngine_0_0 1024"
TrainStep2InferenceEngine_0_0: "TrainCharacterConversionEngine_0_0 1024" ControlEngine_0_4: "SaveMoveImageEngine_0_0 1024"
TrainCharacterConversionEngine_0_0: "SelectBestEngine_0_0 1024" ContainerStep1InferenceEngine_0_0: "Step1MergeEngine_0_0 1024"
TrainCharacterConversionEngine_0_1: "SaveDebugImageEngine_0_0 1024" CornerInferenceEngine_0_0: "Step1MergeEngine_0_1 1024"
SelectBestEngine_0_0: "SaveResultCSVEngine_0_0 1024" Step1MergeEngine_0_0: "ContainerStep2InferenceEngine_0_0 1024"
SaveResultCSVEngine_0_0: "ToHttpSrvEngine_0_0 1024" ContainerStep2InferenceEngine_0_0: "ContainerCharacterConversionEngine_0_0 1024"
SaveResultCSVEngine_0_1: "ToMinioSrvEngine_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"

View File

@ -39,9 +39,17 @@ train_step2_model:
container_step1_model: container_step1_model:
model_path: "./model/container_step1/con1.engine" model_path: "./model/container_step1/con1.engine"
score_threshold: 0.6 score_threshold: 0.6
class: [] class: ["CONTAINERNUM","CONTAINERNUM_REVERSE"] # ,"SPACE_T","SPACENX_T","SPACEG_T","SPACEP_T","SPACEP_T"
# 集装箱字符识别 # 集装箱字符识别
container_step2_model: container_step2_model:
model_path: "./model/container_step2/con2.engine" model_path: "./model/container_step2/con2.engine"
score_threshold: 0.7 score_threshold: 0.7
class: [] 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"]

View File

@ -380,4 +380,22 @@ typedef struct
} DetectResultData; } DetectResultData;
// 存图数据
typedef struct
{
// 数据来源标识
int iDataSource;
std::string strDetectDate;
std::string strDetectTime;
// 帧序号
int iFrameId;
// 箱号大框以及对应小框的集合
Step2ResultData step2ResultData;
// 箱角大框
std::vector<Step2ResultData> vecCornerResultData;
// 图片
cv::Mat cvImage;
} SaveDebugImgData;
#endif //TRAIN_COMMONSTRUCT_H #endif //TRAIN_COMMONSTRUCT_H

View File

@ -77,6 +77,10 @@ identify:
target_min_y: 550 target_min_y: 550
# 单次识别最大帧数 # 单次识别最大帧数
max_identify_frame: 600 max_identify_frame: 600
# 两个箱子的箱角最大差值X
max_container_space_x: 600
# 两个箱子的箱角最大差值Y
max_container_space_y: 500
# websocket_server 的服务端参数 # websocket_server 的服务端参数
wsocket_server: wsocket_server:

View File

@ -38,7 +38,7 @@ connects:
ControlEngine_0_1: "ContainerStep1InferenceEngine_0_0 1024" ControlEngine_0_1: "ContainerStep1InferenceEngine_0_0 1024"
ControlEngine_0_2: "CornerInferenceEngine_0_0 1024" ControlEngine_0_2: "CornerInferenceEngine_0_0 1024"
ControlEngine_0_3: "SaveMoveInfoEngine_0_0 1024" ControlEngine_0_3: "SaveMoveInfoEngine_0_0 1024"
ControlEngine_0_4: "SaveMoveImageEngine_0_0 1024" ControlEngine_0_4: "SaveMoveImageEngine_0_0 1024"
ContainerStep1InferenceEngine_0_0: "Step1MergeEngine_0_0 1024" ContainerStep1InferenceEngine_0_0: "Step1MergeEngine_0_0 1024"
CornerInferenceEngine_0_0: "Step1MergeEngine_0_1 1024" CornerInferenceEngine_0_0: "Step1MergeEngine_0_1 1024"
Step1MergeEngine_0_0: "ContainerStep2InferenceEngine_0_0 1024" Step1MergeEngine_0_0: "ContainerStep2InferenceEngine_0_0 1024"

File diff suppressed because one or more lines are too long

View File

@ -47,7 +47,9 @@ void ControlEngine::initParam()
this->strDetectDate_ = ""; this->strDetectDate_ = "";
for (int i = 0; i < this->vecDataSourceConfig_.size(); ++i) for (int i = 0; i < this->vecDataSourceConfig_.size(); ++i)
{ {
this->mapDetectNO_[i] = 1; this->mapDetectNO_[i] = 0;
this->mapIdentifyType_[i] = IDENTIFY_INIT;
} }
} }
@ -62,18 +64,10 @@ void ControlEngine::endIdentify(int iDataSource)
outputQueMap_[strPort1_]->push(std::static_pointer_cast<void>(pVDetectInfo), true); outputQueMap_[strPort1_]->push(std::static_pointer_cast<void>(pVDetectInfo), true);
outputQueMap_[strPort2_]->push(std::static_pointer_cast<void>(pVDetectInfo), true); outputQueMap_[strPort2_]->push(std::static_pointer_cast<void>(pVDetectInfo), true);
this->mapDetectNO_[iDataSource] = 1; this->mapDetectNO_[iDataSource] = 0;
this->mapIdentifyType_[iDataSource] = IDENTIFY_INIT;
bool bAllEnd = true; LogInfo << " 数据源:" << iDataSource << " --- 识别结束!";
for (const auto & dataSource_it : this->mapDetectNO_)
{
if (dataSource_it.second != 1) bAllEnd = false;
}
if (bAllEnd)
{
g_identify_type = IDENTIFY_INIT;
this->strDetectDate_ = "";
}
} }
void ControlEngine::sendWSEngine(std::string msg) void ControlEngine::sendWSEngine(std::string msg)
@ -83,6 +77,19 @@ void ControlEngine::sendWSEngine(std::string msg)
outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(std::make_shared<std::string>(msg))); outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(std::make_shared<std::string>(msg)));
} }
bool ControlEngine::isDetecting()
{
for (const auto & dataSource : this->mapIdentifyType_)
{
if (dataSource.second == IDENTIFY_START)
{
return true;
}
}
return false;
}
void ControlEngine::detectControl(std::shared_ptr<std::string> pWSServerOrder) void ControlEngine::detectControl(std::shared_ptr<std::string> pWSServerOrder)
{ {
Json::CharReaderBuilder readerBuilder; Json::CharReaderBuilder readerBuilder;
@ -116,24 +123,25 @@ void ControlEngine::detectControl(std::shared_ptr<std::string> pWSServerOrder)
switch (jvOrder["commandType"].asInt()) { switch (jvOrder["commandType"].asInt()) {
case IDENTIFY_START: case IDENTIFY_START:
if (g_identify_type == 1)
if (this->isDetecting())
{ {
std::string msg = "当前正在识别,无需重复发送识别信号"; std::string msg = "当前正在识别,无需重复发送识别信号";
LogWarn << msg; LogWarn << msg;
this->sendWSEngine(msg); this->sendWSEngine(msg);
break; break;
} }
g_identify_type = IDENTIFY_START; this->mapIdentifyType_ = {{0, IDENTIFY_START}, {1, IDENTIFY_START}, {2, IDENTIFY_START}};
break; break;
case IDENTIFY_STOP: case IDENTIFY_STOP:
if (!g_identify_type) if (!this->isDetecting())
{ {
std::string msg = "当前已停止识别,无需重复发送结束信号"; std::string msg = "当前已停止识别,无需重复发送结束信号";
LogWarn << msg; LogWarn << msg;
this->sendWSEngine(msg); this->sendWSEngine(msg);
break; break;
} }
g_identify_type = IDENTIFY_INIT; this->mapIdentifyType_ = {{0, IDENTIFY_INIT}, {1, IDENTIFY_INIT}, {2, IDENTIFY_INIT}};
break; break;
case IDENTIFY_RECORD: case IDENTIFY_RECORD:
if (!jvOrder.isMember("containerNo")) if (!jvOrder.isMember("containerNo"))
@ -181,29 +189,36 @@ APP_ERROR ControlEngine::Process()
if (pProcessData->bIsEnd) if (pProcessData->bIsEnd)
{ {
// 仅读是视频模式下会进行 if (!this->isDetecting()) continue;
if (this->mapDetectNO_[pProcessData->iDataSource] == 1) continue;
this->endIdentify(pProcessData->iDataSource); this->endIdentify(pProcessData->iDataSource);
LogInfo << "数据源:" << pProcessData->iDataSource << " 视频画面播放结束:停止识别!"; LogInfo << "数据源:" << pProcessData->iDataSource << " 画面读取结束:停止识别!";
continue; continue;
} }
if (!g_identify_type) if (!this->isDetecting())
{ {
if (this->mapDetectNO_[pProcessData->iDataSource] != 1) if (this->mapDetectNO_[pProcessData->iDataSource] > 0)
{ {
this->endIdentify(pProcessData->iDataSource); this->endIdentify(pProcessData->iDataSource);
} }
this->strDetectDate_ = "";
continue;
}
if (this->mapIdentifyType_[pProcessData->iDataSource] == IDENTIFY_INIT)
{
continue; continue;
} }
if (this->mapDetectNO_[pProcessData->iDataSource] > this->identifyConfig_.iMaxIdentifyFrame) if (this->mapDetectNO_[pProcessData->iDataSource] > this->identifyConfig_.iMaxIdentifyFrame)
{ {
LogInfo << " 数据源:" << pProcessData->iDataSource << " 超过最大允许识别帧数:" << this->identifyConfig_.iMaxIdentifyFrame << " 停止识别!";
this->endIdentify(pProcessData->iDataSource); this->endIdentify(pProcessData->iDataSource);
LogInfo << "数据源:" << pProcessData->iDataSource << " 超过最大允许识别帧数:" << this->identifyConfig_.iMaxIdentifyFrame << " 停止识别!";
continue; continue;
} }
this->mapDetectNO_[pProcessData->iDataSource]++;
cv::Mat image(pProcessData->dataSourceInfo.iHeight, cv::Mat image(pProcessData->dataSourceInfo.iHeight,
pProcessData->dataSourceInfo.iWidth, pProcessData->dataSourceInfo.iWidth,
CV_8UC3, CV_8UC3,
@ -245,14 +260,14 @@ APP_ERROR ControlEngine::Process()
outputQueMap_[strPort3_]->push(std::static_pointer_cast<void>(pVDetectInfo), true); outputQueMap_[strPort3_]->push(std::static_pointer_cast<void>(pVDetectInfo), true);
// 存图 // 存图
// std::shared_ptr<SaveImgData> pSaveImgData = std::make_shared<SaveImgData>(); std::shared_ptr<SaveImgData> pSaveImgData = std::make_shared<SaveImgData>();
// pSaveImgData->strFilePath = strFilePath; pSaveImgData->strFilePath = strFilePath;
// pSaveImgData->strFileName = std::to_string(this->mapDetectNO_[pProcessData->iDataSource]) + "_" + std::to_string(pProcessData->iDataSource) + ".jpg"; pSaveImgData->strFileName = std::to_string(this->mapDetectNO_[pProcessData->iDataSource]) + "_" + std::to_string(pProcessData->iDataSource) + ".jpg";
// pSaveImgData->cvImage = image; pSaveImgData->cvImage = image;
// pSaveImgData->bIsEnd = pProcessData->bIsEnd; pSaveImgData->bIsEnd = pProcessData->bIsEnd;
// outputQueMap_[strPort4_]->push(std::static_pointer_cast<void>(pSaveImgData), true); outputQueMap_[strPort4_]->push(std::static_pointer_cast<void>(pSaveImgData), true);
this->mapDetectNO_[pProcessData->iDataSource]++;
} }
} }

View File

@ -36,6 +36,7 @@ private:
uint32_t iDetectNO_ = 1; //动态检测数据编号 uint32_t iDetectNO_ = 1; //动态检测数据编号
std::map<int, uint32_t> mapDetectNO_; std::map<int, uint32_t> mapDetectNO_;
std::map<int, int> mapIdentifyType_;
std::string strDetectDate_; std::string strDetectDate_;
std::string strDetectTime_; std::string strDetectTime_;
@ -45,6 +46,7 @@ private:
void endIdentify(int iDataSource); void endIdentify(int iDataSource);
void sendWSEngine(std::string msg); void sendWSEngine(std::string msg);
void detectControl(std::shared_ptr<std::string> pWSServerOrder); void detectControl(std::shared_ptr<std::string> pWSServerOrder);
bool isDetecting();
}; };

File diff suppressed because one or more lines are too long

View File

@ -166,7 +166,7 @@ APP_ERROR ToMinioSrvEngine::Process()
strMinIoPath, strMinIoPath,
strLocalPath)) strLocalPath))
{ {
LogWarn << "数据上传失败! -- " << this->baseConfig_.strDebugResultPath; LogWarn << "数据上传失败! -- " << strLocalPath;
} }
else else
{ {

View File

@ -151,7 +151,7 @@ APP_ERROR VideoDecodeEngine::Process()
} }
else else
{ {
LogError << " 硬解码失败... 返回失败信息:" << iDecodeRet; LogError << "数据源:" << pProcessData->iDataSource << " 硬解码失败... 返回失败信息:" << iDecodeRet;
} }
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -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<void> pVoidData0 = nullptr; inputQueMap_[strPort0_]->pop(pVoidData0); std::shared_ptr<void> 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<InferenceResultData> pInferenceResultData = std::static_pointer_cast<InferenceResultData>(pVoidData0); std::shared_ptr<InferenceResultData> pInferenceResultData_container = std::static_pointer_cast<InferenceResultData>(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; // LogDebug << " 帧:" << pInferenceResultData->iFrameId } // 箱角 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<void>(pInferenceResultData), true); } return APP_ERR_OK; } #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<void> pVoidData0 = nullptr; inputQueMap_[strPort0_]->pop(pVoidData0); std::shared_ptr<void> 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<InferenceResultData> pInferenceResultData = std::static_pointer_cast<InferenceResultData>(pVoidData0); std::shared_ptr<InferenceResultData> pInferenceResultData_container = std::static_pointer_cast<InferenceResultData>(pVoidData1); pInferenceResultData->vecSingleData = pInferenceResultData_container->vecSingleData; std::sort(pInferenceResultData->vecSingleData.begin(), pInferenceResultData->vecSingleData.end(), CompareX); if (pInferenceResultData->singleData.fScore > 0.0f) { // 箱号 // LogDebug << " 帧:" << pInferenceResultData->iFrameId // LogDebug << " 帧:" << pInferenceResultData->iFrameId // LogDebug << " 帧:" << pInferenceResultData->iFrameId // << " 数据源:" << pInferenceResultData->iDataSource // LogDebug << " 帧:" << pInferenceResultData->iFrameId // << " --iClassId:" << pInferenceResultData->singleData.iClassId // LogDebug << " 帧:" << pInferenceResultData->iFrameId // << " confidence=" << pInferenceResultData->singleData.fScore // LogDebug << " 帧:" << pInferenceResultData->iFrameId // << " lx=" << pInferenceResultData->singleData.fLTX // LogDebug << " 帧:" << pInferenceResultData->iFrameId // << " ly=" << pInferenceResultData->singleData.fLTY // LogDebug << " 帧:" << pInferenceResultData->iFrameId // << " rx=" << pInferenceResultData->singleData.fRBX // LogDebug << " 帧:" << pInferenceResultData->iFrameId // << " ry=" << pInferenceResultData->singleData.fRBY // LogDebug << " 帧:" << pInferenceResultData->iFrameId // << " 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<void>(pInferenceResultData), true); } return APP_ERR_OK; }

View File

@ -43,6 +43,7 @@ APP_ERROR SaveDebugImageEngine::Process()
} }
std::shared_ptr<VStep2OutputData> pVStep2OutputData = std::static_pointer_cast<VStep2OutputData>(pvoidd); std::shared_ptr<VStep2OutputData> pVStep2OutputData = std::static_pointer_cast<VStep2OutputData>(pvoidd);
cv::Mat image = pVStep2OutputData->cvImage.clone();
std::string strDataDir = this->baseConfig_.strDebugResultPath + "/" std::string strDataDir = this->baseConfig_.strDebugResultPath + "/"
+ pVStep2OutputData->strDetectDate + "/" + pVStep2OutputData->strDetectDate + "/"
@ -66,9 +67,9 @@ APP_ERROR SaveDebugImageEngine::Process()
// cv::Mat image = cv::imread(strImagePath); // 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; continue;
} }
@ -86,7 +87,7 @@ APP_ERROR SaveDebugImageEngine::Process()
cv::Size text_size = cv::getTextSize(i, cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0); cv::Size text_size = cv::getTextSize(i, cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0);
cv::Point baseline_loc(text_org); cv::Point baseline_loc(text_org);
baseline_loc.y += base_line + text_size.height; 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位置为下一个单词留出空间 // 手动调整x位置为下一个单词留出空间
text_org.x += text_size.width + 10; text_org.x += text_size.width + 10;
text_org.x = text_org.x > IMAGE_WIDTH ? 15 : text_org.x; 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 centerX = pVStep2OutputData->step2ResultData.fLTX + (pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX)/2;
float centerY = pVStep2OutputData->step2ResultData.fLTY + (pVStep2OutputData->step2ResultData.fRBY - pVStep2OutputData->step2ResultData.fLTY)/2; float centerY = pVStep2OutputData->step2ResultData.fLTY + (pVStep2OutputData->step2ResultData.fRBY - pVStep2OutputData->step2ResultData.fLTY)/2;
// auto start = std::chrono::system_clock::now(); //计时开始 // 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.fLTX, pVStep2OutputData->step2ResultData.fLTY),
cv::Point(pVStep2OutputData->step2ResultData.fRBX, pVStep2OutputData->step2ResultData.fRBY), cv::Point(pVStep2OutputData->step2ResultData.fRBX, pVStep2OutputData->step2ResultData.fRBY),
cvScalar, 2); cvScalar, 2);
cv::line(pVStep2OutputData->cvImage, cv::line(image,
cv::Point(centerX, pVStep2OutputData->step2ResultData.fLTY-30), cv::Point(centerX, pVStep2OutputData->step2ResultData.fRBY+30), cv::Point(centerX, pVStep2OutputData->step2ResultData.fLTY-30), cv::Point(centerX, pVStep2OutputData->step2ResultData.fRBY+30),
cvScalar, 1); cvScalar, 1);
cv::Size text_size = cv::getTextSize(pVStep2OutputData->step2ResultData.transInfo.strTmpResult, cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0); 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::Point linePoint(pVStep2OutputData->step2ResultData.fLTX, pVStep2OutputData->step2ResultData.fRBY + text_size.height + 5);
cv::putText(pVStep2OutputData->cvImage, cv::putText(image,
pVStep2OutputData->step2ResultData.transInfo.strTmpResult, pVStep2OutputData->step2ResultData.transInfo.strTmpResult,
linePoint, linePoint,
cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0, 180), 2); 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}; cvScalar = {0, 255, 255, 255};
float centerX_corner = step2ResultData.fLTX + (step2ResultData.fRBX - step2ResultData.fLTX)/2; 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.fLTX, step2ResultData.fLTY),
cv::Point(step2ResultData.fRBX, step2ResultData.fRBY), cv::Point(step2ResultData.fRBX, step2ResultData.fRBY),
cvScalar, 2); cvScalar, 2);
cv::line(pVStep2OutputData->cvImage, cv::line(image,
cv::Point(centerX_corner, step2ResultData.fLTY-30), cv::Point(centerX_corner, step2ResultData.fRBY+30), cv::Point(centerX_corner, step2ResultData.fLTY-30), cv::Point(centerX_corner, step2ResultData.fRBY+30),
cvScalar, 1); cvScalar, 1);
} }
@ -131,7 +132,7 @@ APP_ERROR SaveDebugImageEngine::Process()
// auto end = std::chrono::system_clock::now(); // auto end = std::chrono::system_clock::now();
// LogDebug << "图片存储用时: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms " << strImagePath; // LogDebug << "图片存储用时: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms " << strImagePath;
if (!cv::imwrite(strImagePath, pVStep2OutputData->cvImage, this->vecCompressionParams_)) if (!cv::imwrite(strImagePath, image, this->vecCompressionParams_))
{ {
LogError << "图片存储失败:" << strImagePath; LogError << "图片存储失败:" << strImagePath;
} }

View File

@ -24,7 +24,7 @@ private:
ai_matrix::BaseConfig baseConfig_; ai_matrix::BaseConfig baseConfig_;
std::string strPort0_; std::string strPort0_;
int iPicQuality_ = 100; int iPicQuality_ = 80;
std::vector<int> vecCompressionParams_; std::vector<int> vecCompressionParams_;
}; };

View File

@ -50,8 +50,7 @@ void SelectBestEngine::sendWSServer(DetectResultData &detectResultData)
Json::Value jsonData; Json::Value jsonData;
for (int i = 0; i < detectResultData.vecImage.size(); ++i) for (int i = 0; i < detectResultData.vecImage.size(); ++i)
{ {
jsonData["bestImgSid" + std::to_string(i)] = detectResultData.vecImage[i]; strImage += (detectResultData.strDetectDate + "/" + ai_matrix::StringUtil::getins()->replace_all_distinct(detectResultData.strDetectTime, ":", "-") + "/" + detectResultData.vecImage[i]);
strImage += detectResultData.vecImage[i];
if (i < detectResultData.vecImage.size() - 1) if (i < detectResultData.vecImage.size() - 1)
{ {
strImage += ","; strImage += ",";
@ -68,6 +67,8 @@ void SelectBestEngine::sendWSServer(DetectResultData &detectResultData)
strContainerNo += ","; strContainerNo += ",";
} }
} }
jsonData["detectDate"] = detectResultData.strDetectDate;
jsonData["detectTime"] = detectResultData.strDetectTime;
jsonData["containerNo"] = strContainerNo; jsonData["containerNo"] = strContainerNo;
jsonData["images"] = strImage; jsonData["images"] = strImage;
jsonData["status"] = "normal"; jsonData["status"] = "normal";
@ -99,10 +100,24 @@ void SelectBestEngine::selectBest()
auto contains = [] (const std::vector<std::string>& vec, std::string value) -> bool { auto contains = [] (const std::vector<std::string>& vec, std::string value) -> bool {
return std::find(vec.begin(), vec.end(), value) != vec.end(); 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 detectResultData;
detectResultData.strDetectDate = this->strDetectDate_; detectResultData.strDetectDate = this->strDetectDate_;
detectResultData.strDetectTime = this->strDetectTime_; detectResultData.strDetectTime = this->strDetectTime_;
std::string strAlternativeResult;
bool bHaveTwoContainer = false; bool bHaveTwoContainer = false;
for (auto & it_container : this->mapIndex_Containers_) { for (auto & it_container : this->mapIndex_Containers_) {
bool bHaveVerify = false; bool bHaveVerify = false;
@ -129,21 +144,39 @@ void SelectBestEngine::selectBest()
count = it_max.second; count = it_max.second;
if (!contains(detectResultData.vecContainerNO, it_max.first)) { if (!contains(detectResultData.vecContainerNO, it_max.first)) {
strBestContainer = 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); detectResultData.vecContainerNO.emplace_back(strBestContainer);
} else { } else {
// 取识别字数最长的 if (detectResultData.vecContainerNO.size() == 1 && !strAlternativeResult.empty())
std::string strBestContainer; {
int iMaxSize = 0; detectResultData.vecContainerNO.emplace_back(strAlternativeResult);
for (auto &it_max: mapContainer_count) { }
if (it_max.first.size() > iMaxSize) { else
iMaxSize = it_max.first.size(); {
strBestContainer = it_max.first; // 取识别字数最长的
} 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) if (bHaveTwoContainer && detectResultData.vecContainerNO.size() < 2)
@ -175,6 +208,12 @@ APP_ERROR SelectBestEngine::Process()
if (pVSelectBestData->bIsEnd) if (pVSelectBestData->bIsEnd)
{ {
if (this->strDetectDate_.empty())
{
this->strDetectDate_ = pVSelectBestData->strDetectDate;
this->strDetectTime_ = pVSelectBestData->strDetectTime;
}
this->iEndCount_++; this->iEndCount_++;
if (!(this->iEndCount_ % this->vecDataSourceConfig_.size())) if (!(this->iEndCount_ % this->vecDataSourceConfig_.size()))
{ {
@ -183,6 +222,7 @@ APP_ERROR SelectBestEngine::Process()
} }
continue; continue;
} }
this->iEndCount_ = 0;
if (this->strImagePath_.empty()) if (this->strImagePath_.empty())
{ {

View File

@ -268,6 +268,7 @@ APP_ERROR ContainerStep1InferenceEngine::Process()
if (pVDetectInfo->cvImage.empty()) if (pVDetectInfo->cvImage.empty())
{ {
outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pInferenceResultData), true);
usleep(1000); //1ms usleep(1000); //1ms
continue; continue;
} }
@ -290,7 +291,7 @@ APP_ERROR ContainerStep1InferenceEngine::Process()
pInferenceResultData->strDetectDate = pVDetectInfo->strDetectDate; pInferenceResultData->strDetectDate = pVDetectInfo->strDetectDate;
pInferenceResultData->strDetectTime = pVDetectInfo->strDetectTime; pInferenceResultData->strDetectTime = pVDetectInfo->strDetectTime;
pInferenceResultData->cvImage = pVDetectInfo->cvImage; pInferenceResultData->cvImage = pVDetectInfo->cvImage.clone();
// 筛选离中心点坐标最近的,如果一样近就选最右的 // 筛选离中心点坐标最近的,如果一样近就选最右的
float fCenterX = IMAGE_WIDTH/2; float fCenterX = IMAGE_WIDTH/2;
@ -323,7 +324,7 @@ APP_ERROR ContainerStep1InferenceEngine::Process()
singledata.fLTY = inferenceResult.bbox[1]; singledata.fLTY = inferenceResult.bbox[1];
singledata.fRBX = inferenceResult.bbox[2]; singledata.fRBX = inferenceResult.bbox[2];
singledata.fRBY = inferenceResult.bbox[3]; singledata.fRBY = inferenceResult.bbox[3];
singledata.fClear = inferenceResult.clear_id; singledata.fClear = inferenceResult.clear_conf;
pInferenceResultData->singleData = singledata; pInferenceResultData->singleData = singledata;

File diff suppressed because one or more lines are too long