diff --git a/AlgorithmModule/src/ImgCheckAnalysisy.cpp b/AlgorithmModule/src/ImgCheckAnalysisy.cpp index 5b9a729..23cf0d0 100644 --- a/AlgorithmModule/src/ImgCheckAnalysisy.cpp +++ b/AlgorithmModule/src/ImgCheckAnalysisy.cpp @@ -25,7 +25,7 @@ #define HANDLE_SIZE_MAX_RATIO 1.2f // "附近"的搜索范围:把手区域外接矩形在宽/高方向各外扩该比例 #define HANDLE_NEAR_EXPAND_RATIO 5 -// 把手缺失检测开关见 Function_Support_Det::bDetHandle(CheckConfigDefine.h) +// 把手缺失检测开关见 Base层 Function_Support_Det::bDetHandle(CheckConfigDefine.h) // 用于排序轮廓的比较函数 static bool compareContourAreas(const vector &contour1, const vector &contour2) @@ -723,7 +723,6 @@ int ImgCheckAnalysisy::CheckRun() long time_edge_s = CheckUtil::getcurTime(); m_pFuntion = GetChannelFuntion(m_strCurDetChannel); - int nfunction = 0; if (m_pFuntion != NULL) { m_pdetlog->AddCheckstr(PrintLevel_0, "Detect function", "%s", @@ -731,12 +730,8 @@ int ImgCheckAnalysisy::CheckRun() } else { - nfunction = 1; - m_pdetlog->AddCheckstr(PrintLevel_0, "Error", "m_pFuntion is NULL"); - PublishAlignShare(false); // 本图不会产出定位结果,通知可能的等待方(暗场复用) - m_nErrorCode = 22; - m_nCheckResultErrorCode = m_nErrorCode; - return m_nErrorCode; + // 通道层允许为空(仅打印,不再按错误处理) + m_pdetlog->AddCheckstr(PrintLevel_0, "Detect function", "no channel config, use base function only"); } /*AI 边缘定位(内外边缘)*/ @@ -764,7 +759,7 @@ int ImgCheckAnalysisy::CheckRun() } // 标签检测(独立步骤):暗场图像 + 明场 bigmask(不再沿用明场检出的标签);bDetTag 关闭时跳过 { - if (m_pFuntion->function.f_supportDet.bDetTag) + if (m_pbaseCheckFunction->supportDet.bDetTag) { long tag_s = CheckUtil::getcurTime(); int reTag = CheckTagByBigMask(m_CheckResult_shareP->in_shareImage->img, m_pEdge_Align_Result->bigmask); @@ -895,8 +890,8 @@ int ImgCheckAnalysisy::CheckRun() 3、按 edge_select 指定方向(left/right/up/down)计算 rs 中心到 rp 对应边缘的距离 4、计算值与标准值(x_standard/y_standard)做差取平均,平均差超过 offset(x_offset) → 偏移 */ { - Function_Support_Det &supportDet = m_pFuntion->function.f_supportDet; - if (supportDet.bOpen && supportDet.bDetSupport) + Function_Support_Det &supportDet = m_pbaseCheckFunction->supportDet; + if (supportDet.bDetSupport) { const cv::Mat &bigmask = m_pEdge_Align_Result->bigmask; const cv::Mat &smallmask = m_pEdge_Align_Result->smallmask; @@ -1138,7 +1133,7 @@ int ImgCheckAnalysisy::CheckRun() /* Tag检测(bDetTag 关闭时不上报标签 NG) */ { - if (!m_pFuntion->function.f_supportDet.bDetTag) + if (!m_pbaseCheckFunction->supportDet.bDetTag) { m_tag_roiList.clear(); } @@ -2546,7 +2541,7 @@ int ImgCheckAnalysisy::AI_Edge(const cv::Mat &img, cv::RotatedRect &outerRoi, cv } config.strChannel = DetImgInfo_shareP->strChannel; config.pBaseCheckFunction = m_pbaseCheckFunction; - config.bDetTag = m_pFuntion->function.f_supportDet.bDetTag; // 标签检测开关:关闭时不跑 Tag_Loc + config.bDetTag = m_pbaseCheckFunction->supportDet.bDetTag; // 标签检测开关:关闭时不跑 Tag_Loc config.strProductID = DetImgInfo_shareP->strImgProductID; // 定位存图文件名首位使用产品ID /* 定位获取三个roi */ @@ -2609,9 +2604,9 @@ int ImgCheckAnalysisy::CheckHandleByBigMask(const cv::Mat &bigmask) // 2、把手检测开关 + 把手区域(最多4个,非空区域表示该处应该有一个把手) bool bDetHandle = false; std::vector regionBoxList; - if (m_pFuntion != NULL) + if (m_pbaseCheckFunction != NULL) { - const Function_Support_Det &supportDet = m_pFuntion->function.f_supportDet; + const Function_Support_Det &supportDet = m_pbaseCheckFunction->supportDet; bDetHandle = supportDet.bDetHandle; for (size_t i = 0; i < supportDet.handleBoxes.size() && i < HANDLE_REGION_MAX_NUM; i++) { diff --git a/ConfigModule/include/CheckConfigDefine.h b/ConfigModule/include/CheckConfigDefine.h index 5d6c1b7..3b6c547 100644 --- a/ConfigModule/include/CheckConfigDefine.h +++ b/ConfigModule/include/CheckConfigDefine.h @@ -919,26 +919,28 @@ struct Function_Image_Align // 把手区域最大数量(参数里最多可画4个把手区域) #define HANDLE_REGION_MAX_NUM 4 -// 支架检测 struct Function_Support_Det { - bool bOpen; // 是否开启 - // 支架参数 - bool bDetSupport; - std::vector supportRegion; - cv::RotatedRect supportRect; + // 支架参数(Support_Detect) + bool bDetSupport; // 支架偏位检测开关(Support_Detect.isOpen) float x_standard; // 水平方向标准距离(left/right 用) float y_standard; // 垂直方向标准距离(up/down 用) std::vector edge_select; // 参与计算的方向:up/down/left/right float x_offset; float y_offset; float r_offset; + // 把手参数(Handle_Detect) + bool bDetHandle; // 把手缺失检测开关(Handle_Detect.isOpen) // 把手区域(最多 HANDLE_REGION_MAX_NUM 个,只保存非空的;区域宽高用于把手卡控) - bool bDetHandle; // 把手缺失检测开关 std::vector> handleRegions; std::vector handleBoxes; - // 标签参数 - bool bDetTag; + float handle_diff; // 把手差异阈值 + // 标签参数(BQ_Detect) + bool bDetTag; // 标签检测开关(BQ_Detect.isOpen) + float BQ_area; // 标签检测参数:面积 + float BQ_energy; // 标签检测参数:能量 + float BQ_len; // 标签检测参数:长度 + float BQ_hj; // 标签检测参数:灰阶 Function_Support_Det () { @@ -947,10 +949,7 @@ struct Function_Support_Det void Init() { - bOpen = false; bDetSupport = false; - supportRegion.clear(); - supportRect = cv::RotatedRect(); x_standard = 0; y_standard = 0; edge_select.clear(); @@ -960,14 +959,16 @@ struct Function_Support_Det bDetHandle = false; handleRegions.clear(); handleBoxes.clear(); + handle_diff = 20; bDetTag = false; + BQ_area = 0; + BQ_energy = 0; + BQ_len = 0; + BQ_hj = 0; } void copy(Function_Support_Det tem) { - this->bOpen = tem.bOpen; this->bDetSupport = tem.bDetSupport; - this->supportRegion.assign(tem.supportRegion.begin(), tem.supportRegion.end()); - this->supportRect = tem.supportRect; this->x_standard = tem.x_standard; this->y_standard = tem.y_standard; this->edge_select.assign(tem.edge_select.begin(), tem.edge_select.end()); @@ -977,18 +978,23 @@ struct Function_Support_Det this->bDetHandle = tem.bDetHandle; this->handleRegions.assign(tem.handleRegions.begin(), tem.handleRegions.end()); this->handleBoxes.assign(tem.handleBoxes.begin(), tem.handleBoxes.end()); + this->handle_diff = tem.handle_diff; this->bDetTag = tem.bDetTag; + this->BQ_area = tem.BQ_area; + this->BQ_energy = tem.BQ_energy; + this->BQ_len = tem.BQ_len; + this->BQ_hj = tem.BQ_hj; } void print(std::string str) { - printf("%s>>bOpen %d bDetSupport %d bDetHandle %d bDetTag %d x_standard %f y_standard %f x_offset %f y_offset %f r_offset %f edge num %ld handleRegion num %ld\n", - str.c_str(), bOpen, bDetSupport, bDetHandle, bDetTag, x_standard, y_standard, x_offset, y_offset, r_offset, edge_select.size(), handleRegions.size()); + printf("%s>>bDetSupport %d bDetHandle %d bDetTag %d x_standard %f y_standard %f x_offset %f y_offset %f r_offset %f edge num %ld handleRegion num %ld handle_diff %f BQ[area %f energy %f len %f hj %f]\n", + str.c_str(), bDetSupport, bDetHandle, bDetTag, x_standard, y_standard, x_offset, y_offset, r_offset, edge_select.size(), handleRegions.size(), handle_diff, BQ_area, BQ_energy, BQ_len, BQ_hj); } std::string GetInfo(std::string str) { - char buffer[256]; - sprintf(buffer, "%s>>bOpen %d bDetSupport %d bDetHandle %d bDetTag %d x_standard %f y_standard %f x_offset %f y_offset %f r_offset %f edge num %ld handleRegion num %ld\n", - str.c_str(), bOpen, bDetSupport, bDetHandle, bDetTag, x_standard, y_standard, x_offset, y_offset, r_offset, edge_select.size(), handleRegions.size()); + char buffer[512]; + sprintf(buffer, "%s>>bDetSupport %d bDetHandle %d bDetTag %d x_standard %f y_standard %f x_offset %f y_offset %f r_offset %f edge num %ld handleRegion num %ld handle_diff %f BQ[area %f energy %f len %f hj %f]\n", + str.c_str(), bDetSupport, bDetHandle, bDetTag, x_standard, y_standard, x_offset, y_offset, r_offset, edge_select.size(), handleRegions.size(), handle_diff, BQ_area, BQ_energy, BQ_len, BQ_hj); std::string str123 = buffer; return str123; } @@ -1004,7 +1010,6 @@ struct CheckFunction Function_ShieldRegion f_ShieldRegion; Function_EdgeROI f_EdgeROI; Function_Image_Align f_Image_Align; // 图片特征对齐 - Function_Support_Det f_supportDet; CheckFunction() { Init(); @@ -1017,7 +1022,6 @@ struct CheckFunction f_ShieldRegion.Init(); f_EdgeROI.Init(); f_Image_Align.Init(); - f_supportDet.Init(); } void copy(CheckFunction tem) { @@ -1028,7 +1032,6 @@ struct CheckFunction this->f_ShieldRegion.copy(tem.f_ShieldRegion); this->f_EdgeROI.copy(tem.f_EdgeROI); this->f_Image_Align.copy(tem.f_Image_Align); - this->f_supportDet.copy(tem.f_supportDet); } void print(std::string str) { @@ -1039,7 +1042,6 @@ struct CheckFunction f_ShieldRegion.print("ShieldRegion"); f_EdgeROI.print("EdgeROI"); f_Image_Align.print("Image_Align"); - f_supportDet.print("supportDet"); } std::string GetInfo(std::string str) { @@ -1051,7 +1053,6 @@ struct CheckFunction str123 += f_ShieldRegion.GetInfo("ShieldRegion"); str123 += f_EdgeROI.GetInfo("EdgeROI"); str123 += f_Image_Align.GetInfo("Image_Align"); - str123 += f_supportDet.GetInfo("supportDet"); return str123; } }; @@ -1377,6 +1378,7 @@ struct BaseCheckFunction Base_Function_Edge_Det edgeDet; Base_Function_SaveImg saveImg; Base_Function_BigNG bigNG; + Function_Support_Det supportDet; // 支架/把手/标签检测(Support_Detect/Handle_Detect/BQ_Detect) BaseCheckFunction() { @@ -1388,6 +1390,7 @@ struct BaseCheckFunction edgeDet.Init(); saveImg.Init(); bigNG.Init(); + supportDet.Init(); } void copy(BaseCheckFunction tem) { @@ -1395,6 +1398,7 @@ struct BaseCheckFunction this->edgeDet.copy(tem.edgeDet); this->saveImg.copy(tem.saveImg); this->bigNG.copy(tem.bigNG); + this->supportDet.copy(tem.supportDet); } void print(std::string str) { @@ -1403,6 +1407,7 @@ struct BaseCheckFunction edgeDet.print("edgeDet"); saveImg.print("saveImg"); bigNG.print("bigNG"); + supportDet.print("supportDet"); } std::string GetInfo(std::string str) { @@ -1411,6 +1416,7 @@ struct BaseCheckFunction str123 += edgeDet.GetInfo("edgeDet"); str123 += saveImg.GetInfo("saveImg"); str123 += bigNG.GetInfo("bigNG"); + str123 += supportDet.GetInfo("supportDet"); // str123 += "\n"; return str123; } diff --git a/ConfigModule/src/JsonConfig.cpp b/ConfigModule/src/JsonConfig.cpp index bf49b44..4d0bc20 100644 --- a/ConfigModule/src/JsonConfig.cpp +++ b/ConfigModule/src/JsonConfig.cpp @@ -411,130 +411,8 @@ int ChannelFuntonConfigJson::GetFunction(Json::Value value, CheckFunction &funct std::string strCode = value[i]["itemCode"].asString(); // std::cout << strCode << std::endl; - // 支架偏移缺失检测 - if ("Support_QX_Detect" == strCode) - { - auto value_f = value[i]; - // std::cout << value_f << std::endl; - function.f_supportDet.bOpen = value_f["isOpen"].asBool(); - if (function.f_supportDet.bOpen) - { - // 支架参数 - { - if (value_f["form"]["support_param"]["bDetSupport"]) - { - function.f_supportDet.bDetSupport = value_f["form"]["support_param"]["bDetSupport"].asBool(); - } - - auto value_region = value_f["form"]["support_param"]["support_region"]; - if (value_region.isArray()) - { - for (int idx = 0; idx < value_region.size(); idx++) - { - cv::Point p; - p.x = value_region[idx][0].asInt(); - p.y = value_region[idx][1].asInt(); - - function.f_supportDet.supportRegion.emplace_back(p); - } - if (function.f_supportDet.supportRegion.size() > 0) - { - function.f_supportDet.supportRect = minAreaRect(function.f_supportDet.supportRegion); - } - } - - if (value_f["form"]["support_param"]["x_standard"]) - { - function.f_supportDet.x_standard = value_f["form"]["support_param"]["x_standard"].asFloat(); - } - if (value_f["form"]["support_param"]["y_standard"]) - { - function.f_supportDet.y_standard = value_f["form"]["support_param"]["y_standard"].asFloat(); - } + // 注:支架/把手/标签检测(Support_Detect/Handle_Detect/BQ_Detect)已移至Base层(baseCheckData)解析 - auto value_qx = value_f["form"]["support_param"]["edge_select"]; - if (value_qx.isArray()) - { - for (int idx = 0; idx < value_qx.size(); idx++) - { - std::string channel = value_qx[idx].asString(); - function.f_supportDet.edge_select.push_back(channel); - } - } - - if (value_f["form"]["support_param"]["x_offset"]) - { - function.f_supportDet.x_offset = value_f["form"]["support_param"]["x_offset"].asFloat(); - } - if (value_f["form"]["support_param"]["y_offset"]) - { - function.f_supportDet.y_offset = value_f["form"]["support_param"]["y_offset"].asFloat(); - } - if (value_f["form"]["support_param"]["r_offset"]) - { - function.f_supportDet.r_offset = value_f["form"]["support_param"]["r_offset"].asFloat(); - } - } - // 把手参数 - { - if (value_f["form"]["handle_param"]["bDetHandle"]) - { - function.f_supportDet.bDetHandle = value_f["form"]["handle_param"]["bDetHandle"].asBool(); - } - auto handle_p = value_f["form"]["handle_param"]; - bool bNewFormat = handle_p["handle_region1"].isArray(); - for (int idx = 0; idx < HANDLE_REGION_MAX_NUM; idx++) - { - std::string strKey = bNewFormat ? ("handle_region" + std::to_string(idx + 1)) - : ((idx == 0) ? std::string("handle_region") : std::string("")); - if (strKey.empty()) - { - break; - } - // 该把手区域被禁用时跳过 - if (handle_p[strKey + "_disabled"].isBool() && handle_p[strKey + "_disabled"].asBool()) - { - continue; - } - auto value_region = handle_p[strKey]; - if (!value_region.isArray() || value_region.size() < 3) - { - continue; // 空区域:表示该处不需要检测把手 - } - std::vector region; - for (int ip = 0; ip < value_region.size(); ip++) - { - if (!value_region[ip].isArray() || value_region[ip].size() < 2) - { - continue; - } - cv::Point p; - p.x = value_region[ip][0].asInt(); - p.y = value_region[ip][1].asInt(); - region.emplace_back(p); - } - if (region.size() < 3) - { - continue; - } - function.f_supportDet.handleRegions.push_back(region); - function.f_supportDet.handleBoxes.push_back(cv::boundingRect(region)); - } - } - // 标签参数 - { - if (value_f["form"]["tag_param"]["bDetTag"]) - { - function.f_supportDet.bDetTag = value_f["form"]["tag_param"]["bDetTag"].asBool(); - } - } - } - else - { - function.f_supportDet.Init(); - } - } - // 大缺陷检测 if ("BigQX_Detect" == strCode) { @@ -973,7 +851,8 @@ int BaseFuntonConfigJson::GetFunction(Json::Value value) _config.markLine.Init(); } } - if ("Det_Image_Save" == strCode) + // 存图项(2026-10 平台将 Det_Image_Save 改名为 BM_Image_Save,两个名称都兼容) + if ("Det_Image_Save" == strCode || "BM_Image_Save" == strCode) { auto value_f = value; // std::cout << value_f << std::endl; @@ -1032,5 +911,128 @@ int BaseFuntonConfigJson::GetFunction(Json::Value value) // _config.edgeDet.print("edgeDet"); // getchar(); } + // 支架偏位检测(Support_Detect,2026-10 从通道层 Support_QX_Detect 移至Base层并拆分独立) + if ("Support_Detect" == strCode) + { + auto value_f = value; + // 检测项开关即支架偏位检测开关 + _config.supportDet.bDetSupport = value_f["isOpen"].asBool(); + if (_config.supportDet.bDetSupport) + { + auto value_param = value_f["form"]["support_param"]; + + if (value_param["x_standard"]) + { + _config.supportDet.x_standard = value_param["x_standard"].asFloat(); + } + if (value_param["y_standard"]) + { + _config.supportDet.y_standard = value_param["y_standard"].asFloat(); + } + if (value_param["x_offset"]) + { + _config.supportDet.x_offset = value_param["x_offset"].asFloat(); + } + if (value_param["y_offset"]) + { + _config.supportDet.y_offset = value_param["y_offset"].asFloat(); + } + if (value_param["r_offset"]) + { + _config.supportDet.r_offset = value_param["r_offset"].asFloat(); + } + + auto value_qx = value_param["edge_select"]; + if (value_qx.isArray()) + { + for (int idx = 0; idx < value_qx.size(); idx++) + { + std::string strEdge = value_qx[idx].asString(); + _config.supportDet.edge_select.push_back(strEdge); + } + } + } + } + // 把手检测(Handle_Detect,2026-10 从通道层 Support_QX_Detect 移至Base层并拆分独立) + if ("Handle_Detect" == strCode) + { + auto value_f = value; + // 检测项开关即把手缺失检测开关 + _config.supportDet.bDetHandle = value_f["isOpen"].asBool(); + if (_config.supportDet.bDetHandle) + { + auto handle_p = value_f["form"]["handle_param"]; + // 把手差异阈值 + if (handle_p["handle_diff"]) + { + _config.supportDet.handle_diff = handle_p["handle_diff"].asFloat(); + } + bool bNewFormat = handle_p["handle_region1"].isArray(); + for (int idx = 0; idx < HANDLE_REGION_MAX_NUM; idx++) + { + std::string strKey = bNewFormat ? ("handle_region" + std::to_string(idx + 1)) + : ((idx == 0) ? std::string("handle_region") : std::string("")); + if (strKey.empty()) + { + break; + } + // 该把手区域被禁用时跳过 + if (handle_p[strKey + "_disabled"].isBool() && handle_p[strKey + "_disabled"].asBool()) + { + continue; + } + auto value_region = handle_p[strKey]; + if (!value_region.isArray() || value_region.size() < 3) + { + continue; // 空区域:表示该处不需要检测把手 + } + std::vector region; + for (int ip = 0; ip < value_region.size(); ip++) + { + if (!value_region[ip].isArray() || value_region[ip].size() < 2) + { + continue; + } + cv::Point p; + p.x = value_region[ip][0].asInt(); + p.y = value_region[ip][1].asInt(); + region.emplace_back(p); + } + if (region.size() < 3) + { + continue; + } + _config.supportDet.handleRegions.push_back(region); + _config.supportDet.handleBoxes.push_back(cv::boundingRect(region)); + } + } + } + // 标签检测(BQ_Detect,2026-10 从通道层 Support_QX_Detect 移至Base层并拆分独立) + if ("BQ_Detect" == strCode) + { + auto value_f = value; + // 检测项开关即标签检测开关 + _config.supportDet.bDetTag = value_f["isOpen"].asBool(); + if (_config.supportDet.bDetTag) + { + auto tag_p = value_f["form"]["tag_param"]; + if (tag_p["BQ_area"]) + { + _config.supportDet.BQ_area = tag_p["BQ_area"].asFloat(); + } + if (tag_p["BQ_energy"]) + { + _config.supportDet.BQ_energy = tag_p["BQ_energy"].asFloat(); + } + if (tag_p["BQ_len"]) + { + _config.supportDet.BQ_len = tag_p["BQ_len"].asFloat(); + } + if (tag_p["BQ_hj"]) + { + _config.supportDet.BQ_hj = tag_p["BQ_hj"].asFloat(); + } + } + } return 0; }