Compare commits

..

No commits in common. '01247bccb953d0ca1ec623ee6219ce1b73effdad' and '0bd86d0acbe0e2ff74807fb2000f2e8bf56c177e' have entirely different histories.

@ -132,7 +132,7 @@ private:
int AnalysisResult_Pre(QX_ERROR_INFO_ *QX_info); // 弱化处理 int AnalysisResult_Pre(QX_ERROR_INFO_ *QX_info); // 弱化处理
// 关联过滤源过滤:撤销与关联通道过滤源缺陷重叠的暗点NG结果(含单图判定的单点NG) // 关联通道脏污过滤:撤销与关联通道脏污重叠的暗点NG结果(含单图判定的单点NG)
int FilterCorrelatedDirtyNG(std::shared_ptr<ImageAllResult> pImageResult); int FilterCorrelatedDirtyNG(std::shared_ptr<ImageAllResult> pImageResult);
ChannelCheckFunction *GetChannelFuntion(std::string strChannelName); // 获得 通道的检测功能 ChannelCheckFunction *GetChannelFuntion(std::string strChannelName); // 获得 通道的检测功能

@ -174,14 +174,10 @@ public:
bool Idx(int qxidx); bool Idx(int qxidx);
bool AddQxInfo(int qxidx, QX_Info qxinfo, std::shared_ptr<DetLog> plog, std::shared_ptr<DetLog> pchannelLog); bool AddQxInfo(int qxidx, QX_Info qxinfo, std::shared_ptr<DetLog> plog, std::shared_ptr<DetLog> pchannelLog);
// 登记关联通道(非主/次通道)的过滤源缺陷信息(类型由 correlated_types 配置, 如脏污/暗点),供 AD 分析判断重叠缺陷 // 登记关联通道(非主/次通道)的缺陷信息,如脏污(dirty),供 AD 绑定分析判断重叠缺陷
bool AddCorrelatedQxInfo(Correlated_Qx_Info_ qxinfo, std::shared_ptr<DetLog> plog); bool AddCorrelatedQxInfo(Correlated_Qx_Info_ qxinfo, std::shared_ptr<DetLog> plog);
// 判断缺陷类型是否为配置的关联过滤源类型(analysis_bind.correlated_types, 如 "Dirty_L0"/"Dirty_L1"/"Dirty_L2"/"AD") // 关联通道脏污重叠判断(供外部调用):当前缺陷ROI是否与关联通道脏污缺陷重叠
// 配置为空时默认三种脏污; 登记与过滤两处共用此判定
bool IsCorrelatedSourceConfigType(int nconfigType);
// 关联通道过滤源重叠判断(供外部调用):当前缺陷ROI是否与关联通道过滤源缺陷(脏污/暗点等)重叠
bool IsDirtyOverlapInCorrelatedChannel(const std::string &cur_channel_name, bool IsDirtyOverlapInCorrelatedChannel(const std::string &cur_channel_name,
const std::string &cur_camera_name, const std::string &cur_camera_name,
const cv::Rect &qx_product_roi, const cv::Rect &qx_product_roi,
@ -214,14 +210,13 @@ private:
int Judge_OK_Config(); int Judge_OK_Config();
int Judge_NG_Config(); int Judge_NG_Config();
// pAllowChannels 非空时仅列表内通道参与分析(用于主通道为空回退时仅跑次通道); nullptr=不过滤 int Analysis_AD(ALL_Qx_DataList *pALLTypeqxList, int qx_idx);
int Analysis_AD(ALL_Qx_DataList *pALLTypeqxList, int qx_idx, const std::vector<std::string> *pAllowChannels = nullptr);
int Analysis_AD_Bind(ALL_Qx_DataList *pALLTypeqxList, int qx_idx); int Analysis_AD_Bind(ALL_Qx_DataList *pALLTypeqxList, int qx_idx);
// 关联过滤源过滤:移除与关联通道过滤源缺陷重叠的缺陷,使其不参与后续数量/距离/S分析 // 关联通道脏污过滤:移除与关联通道脏污重叠的缺陷,使其不参与后续数量/距离/S分析
int FilterCorrelatedDirtyQx(ALL_Qx_DataList *pALLTypeqxList); int FilterCorrelatedDirtyQx(ALL_Qx_DataList *pALLTypeqxList);
// 判断当前缺陷是否与关联通道(correlated_channels)中的过滤源缺陷(correlated_types)重叠 // 判断当前缺陷是否与关联通道(correlated_channels)中的脏污缺陷重叠
bool IsOverlapDirtyInCorrelatedChannel(const std::vector<std::string> &correlated_channels, bool IsOverlapDirtyInCorrelatedChannel(const std::vector<std::string> &correlated_channels,
const std::string &cur_channel_name, const std::string &cur_channel_name,
const std::string &cur_camera_name, const std::string &cur_camera_name,

@ -318,18 +318,18 @@ int ALLImgCheckAnalysisy::InitAIFactory()
GPU_Config gpu; GPU_Config gpu;
int num = 0; int num = 0;
// for (int i = 0; i < MAX_GPU_NUM; i++) for (int i = 0; i < MAX_GPU_NUM; i++)
// { {
// gpu.UseGPUList[i] = m_RunConfig.UseGPUList[i]; gpu.UseGPUList[i] = m_RunConfig.UseGPUList[i];
// if (gpu.UseGPUList[i] >= 0) if (gpu.UseGPUList[i] >= 0)
// { {
// num++; num++;
// } }
// } }
// if (num == 0) if (num == 0)
{ {
gpu.UseGPUList[0] = 1; gpu.UseGPUList[0] = 0;
gpu.UseGPUList[1] = -1; gpu.UseGPUList[1] = 1;
} }
for (int i = 0; i < MAX_GPU_NUM; i++) for (int i = 0; i < MAX_GPU_NUM; i++)
{ {

@ -748,9 +748,10 @@ int ImageResultJudge::ResultJudge(std::shared_ptr<ImageAllResult> pImageResult)
} }
} }
// 关联通道分析:登记关联过滤源缺陷位置(类型由 analysis_bind.correlated_types 配置, 如脏污/暗点), // 关联通道分析:登记脏污(dirty)缺陷位置,供 AD 绑定分析判断关联通道是否存在重叠脏污缺陷
// 供 AD 分析判断关联通道是否存在重叠缺陷 if (config_qx_type == CONFIG_QX_NAME_Dirty_L0 ||
if (m_pQX_Merge_Analysis->IsCorrelatedSourceConfigType(config_qx_type)) config_qx_type == CONFIG_QX_NAME_Dirty_L1 ||
config_qx_type == CONFIG_QX_NAME_Dirty_L2)
{ {
QX_Merge_Analysis::Correlated_Qx_Info_ corr_qx; QX_Merge_Analysis::Correlated_Qx_Info_ corr_qx;
corr_qx.channel_name = pImageResult->strChannel; corr_qx.channel_name = pImageResult->strChannel;
@ -808,7 +809,7 @@ int ImageResultJudge::UpdateMergedet(std::shared_ptr<CameraResult> pCheck_Result
} }
/** /**
* @brief 关联过滤源过滤:撤销与关联通道过滤源缺陷重叠的暗点NG结果(含单图判定的单点NG) * @brief 关联通道脏污过滤:撤销与关联通道脏污缺陷重叠的暗点NG结果(含单图判定的单点NG)
* 被过滤的暗点不再计入NG * 被过滤的暗点不再计入NG
* @param pImageResult 当前检测图片结果 * @param pImageResult 当前检测图片结果
* @return int 被过滤的缺陷个数 * @return int 被过滤的缺陷个数
@ -847,7 +848,7 @@ int ImageResultJudge::FilterCorrelatedDirtyNG(std::shared_ptr<ImageAllResult> pI
continue; continue;
} }
// 关联通道存在与当前缺陷重叠的过滤源缺陷时,过滤该暗点NG // 关联通道存在与当前缺陷重叠的脏污缺陷时,过滤该暗点NG
cv::Rect product_roi = QX_info->roi; cv::Rect product_roi = QX_info->roi;
product_roi.x += fproduct_offx_piexl; product_roi.x += fproduct_offx_piexl;
if (!m_pQX_Merge_Analysis->IsDirtyOverlapInCorrelatedChannel(pImageResult->strChannel, if (!m_pQX_Merge_Analysis->IsDirtyOverlapInCorrelatedChannel(pImageResult->strChannel,
@ -902,14 +903,14 @@ int ImageResultJudge::FilterCorrelatedDirtyNG(std::shared_ptr<ImageAllResult> pI
if (pImageLog) if (pImageLog)
{ {
pImageLog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "DirtyCorrelatedFilter", pImageLog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "DirtyCorrelatedFilter",
"img %s cam %s blob %d qx %s roi %s : 关联通道存在重叠的过滤源缺陷, 过滤该暗点NG", "img %s cam %s blob %d qx %s roi %s : 关联通道存在重叠脏污, 过滤该暗点NG",
pImageResult->strChannel.c_str(), pImageResult->cameraBaseResult->strCameraName.c_str(), pImageResult->strChannel.c_str(), pImageResult->cameraBaseResult->strCameraName.c_str(),
qxidx, QX_info->qx_name.c_str(), CheckUtil::GetRectString(product_roi).c_str()); qxidx, QX_info->qx_name.c_str(), CheckUtil::GetRectString(product_roi).c_str());
} }
if (m_pQX_Merge_Analysis->m_pMergedetlog) if (m_pQX_Merge_Analysis->m_pMergedetlog)
{ {
m_pQX_Merge_Analysis->m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter", m_pQX_Merge_Analysis->m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter",
"img %s cam %s blob %d qx %s roi %s : 关联通道存在重叠的过滤源缺陷, 过滤该暗点NG", "img %s cam %s blob %d qx %s roi %s : 关联通道存在重叠脏污, 过滤该暗点NG",
pImageResult->strChannel.c_str(), pImageResult->cameraBaseResult->strCameraName.c_str(), pImageResult->strChannel.c_str(), pImageResult->cameraBaseResult->strCameraName.c_str(),
qxidx, QX_info->qx_name.c_str(), CheckUtil::GetRectString(product_roi).c_str()); qxidx, QX_info->qx_name.c_str(), CheckUtil::GetRectString(product_roi).c_str());
} }
@ -940,7 +941,7 @@ int ImageResultJudge::MergeResult(std::shared_ptr<ImageAllResult> pImageResult,
} }
int qxNum = pDetResult->pQx_ErrorList->size(); int qxNum = pDetResult->pQx_ErrorList->size();
// 关联过滤源过滤:撤销与关联通道过滤源缺陷重叠的暗点NG(含单图判定的单点NG) // 关联通道脏污过滤:撤销与关联通道脏污重叠的暗点NG(含单图判定的单点NG)
FilterCorrelatedDirtyNG(pImageResult); FilterCorrelatedDirtyNG(pImageResult);
for (int iqx = 0; iqx < (int)ptemre->resultList.size(); iqx++) for (int iqx = 0; iqx < (int)ptemre->resultList.size(); iqx++)

@ -4,13 +4,9 @@
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include <chrono> #include <chrono>
#include <algorithm>
#include "CheckUtil.hpp" #include "CheckUtil.hpp"
#include "CheckConfigDefine.h" #include "CheckConfigDefine.h"
// Analysis_AD_Bind 返回码: 主通道为空(配置为空或本次无匹配通道), 调用方回退执行 Analysis_AD
static const int AD_BIND_RE_MAIN_EMPTY = 2;
QX_Merge_Analysis::QX_Merge_Analysis() QX_Merge_Analysis::QX_Merge_Analysis()
{ {
m_bExit = false; m_bExit = false;
@ -272,83 +268,35 @@ bool QX_Merge_Analysis::setSendStatus(std::string cameraName, RUN_STATUS_ status
} }
/** /**
* @brief 关联过滤源类型名称转配置类型(如 "Dirty_L0" -> CONFIG_QX_NAME_Dirty_L0), 大小写不敏感 * @brief 判断缺陷配置类型是否为脏污(dirty)
* @param strTypeName 缺陷类型名称(CONFIG_QX_NAME_Names 中的名称) * @param nconfigType 缺陷配置类型 CONFIG_QX_NAME_
* @return int 匹配的配置类型, 未匹配返回 -1 * @return bool 是脏污返回true
*/ */
static int CorrelatedTypeNameToConfigType(const std::string &strTypeName) static bool IsDirtyConfigType(int nconfigType)
{
for (int i = 0; i < (int)CONFIG_QX_NAME_Names.size(); i++)
{
if (CheckUtil::compareIgnoreCase(strTypeName, CONFIG_QX_NAME_Names.at(i)))
{ {
return i; return nconfigType == CONFIG_QX_NAME_Dirty_L0 ||
} nconfigType == CONFIG_QX_NAME_Dirty_L1 ||
} nconfigType == CONFIG_QX_NAME_Dirty_L2;
return -1;
} }
/** /**
* @brief 判断关联配置名称是否需要参与判断(为空或NONE则不参与) * @brief 判断关联通道名称是否需要参与判断(为空或NONE则不参与)
* @param strName 关联通道/缺陷类型名称 * @param strChannelName 关联通道名称
* @return bool 需要判断返回true * @return bool 需要判断返回true
*/ */
static bool IsValidCorrelatedName(const std::string &strName) static bool IsValidCorrelatedChannel(const std::string &strChannelName)
{ {
if (strName == "") if (strChannelName == "")
{ {
return false; return false;
} }
if (CheckUtil::compareIgnoreCase(strName, "NONE")) if (CheckUtil::compareIgnoreCase(strChannelName, "NONE"))
{ {
return false; return false;
} }
return true; return true;
} }
/**
* @brief 判断缺陷类型是否为配置的关联过滤源类型(analysis_bind.correlated_types,
* 如 "Dirty_L0"/"Dirty_L1"/"Dirty_L2"/"AD"), 登记与过滤两处共用此判定
* 配置为空时兼容旧行为, 默认三种脏污
* @param nconfigType 缺陷配置类型 CONFIG_QX_NAME_
* @return bool 是过滤源返回true
*/
bool QX_Merge_Analysis::IsCorrelatedSourceConfigType(int nconfigType)
{
// 防御:非法类型直接返回
if (nconfigType < 0 || nconfigType >= CONFIG_QX_NAME_count)
{
return false;
}
// 从配置读取过滤源类型名称并转换
std::vector<int> configTypes;
if (m_pbaseCheckFunction != nullptr)
{
const std::vector<std::string> &typeNames = m_pbaseCheckFunction->ad_check.analysis_bind.correlated_types;
for (int i = 0; i < (int)typeNames.size(); i++)
{
if (!IsValidCorrelatedName(typeNames.at(i)))
{
continue;
}
int type = CorrelatedTypeNameToConfigType(typeNames.at(i));
if (type >= 0)
{
configTypes.push_back(type);
}
}
}
if (!configTypes.empty())
{
return std::find(configTypes.begin(), configTypes.end(), nconfigType) != configTypes.end();
}
// 缺省过滤源(兼容旧配置):三种脏污
return false;
}
bool QX_Merge_Analysis::AddCorrelatedQxInfo(Correlated_Qx_Info_ qxinfo, std::shared_ptr<DetLog> plog) bool QX_Merge_Analysis::AddCorrelatedQxInfo(Correlated_Qx_Info_ qxinfo, std::shared_ptr<DetLog> plog)
{ {
// 防御:通道为空或ROI非法时不登记,避免无效数据参与后续判断 // 防御:通道为空或ROI非法时不登记,避免无效数据参与后续判断
@ -403,14 +351,14 @@ bool QX_Merge_Analysis::IsOverlapDirtyInCorrelatedChannel(const std::vector<std:
return false; return false;
} }
// 拷贝出需要比较的过滤源缺陷列表,避免在锁内做IoU计算 // 拷贝出需要比较的脏污缺陷列表,避免在锁内做IoU计算
std::vector<Correlated_Qx_Info_> sourceList; std::vector<Correlated_Qx_Info_> dirtyList;
{ {
std::lock_guard<std::mutex> lock(mtx_correlatedQx); std::lock_guard<std::mutex> lock(mtx_correlatedQx);
for (int i = 0; i < (int)correlated_channels.size(); i++) for (int i = 0; i < (int)correlated_channels.size(); i++)
{ {
const std::string &channel_name = correlated_channels.at(i); const std::string &channel_name = correlated_channels.at(i);
if (!IsValidCorrelatedName(channel_name)) if (!IsValidCorrelatedChannel(channel_name))
{ {
continue; continue;
} }
@ -421,15 +369,15 @@ bool QX_Merge_Analysis::IsOverlapDirtyInCorrelatedChannel(const std::vector<std:
} }
for (int j = 0; j < (int)it->second.size(); j++) for (int j = 0; j < (int)it->second.size(); j++)
{ {
if (IsCorrelatedSourceConfigType(it->second.at(j).config_qx_type)) if (IsDirtyConfigType(it->second.at(j).config_qx_type))
{ {
sourceList.push_back(it->second.at(j)); dirtyList.push_back(it->second.at(j));
} }
} }
} }
} }
if (sourceList.empty()) if (dirtyList.empty())
{ {
return false; return false;
} }
@ -438,22 +386,22 @@ bool QX_Merge_Analysis::IsOverlapDirtyInCorrelatedChannel(const std::vector<std:
cv::Rect roi_expanded(qx_product_roi.x - roi_expand, qx_product_roi.y - roi_expand, cv::Rect roi_expanded(qx_product_roi.x - roi_expand, qx_product_roi.y - roi_expand,
qx_product_roi.width + roi_expand * 2, qx_product_roi.height + roi_expand * 2); qx_product_roi.width + roi_expand * 2, qx_product_roi.height + roi_expand * 2);
for (int i = 0; i < (int)sourceList.size(); i++) for (int i = 0; i < (int)dirtyList.size(); i++)
{ {
cv::Rect source_roi = sourceList.at(i).product_roi; cv::Rect dirty_roi = dirtyList.at(i).product_roi;
cv::Rect source_expanded(source_roi.x - roi_expand, source_roi.y - roi_expand, cv::Rect dirty_expanded(dirty_roi.x - roi_expand, dirty_roi.y - roi_expand,
source_roi.width + roi_expand * 2, source_roi.height + roi_expand * 2); dirty_roi.width + roi_expand * 2, dirty_roi.height + roi_expand * 2);
float fiou = CheckUtil::CalIoU(roi_expanded, source_expanded); float fiou = CheckUtil::CalIoU(roi_expanded, dirty_expanded);
if (plog) if (plog)
{ {
plog->AddCheckstr(PrintLevel_3, 3, "CorrelatedDirty", plog->AddCheckstr(PrintLevel_3, 3, "CorrelatedDirty",
"cur %s cam %s roi %s <-> source %s roi %s expand %d iou %f", "cur %s cam %s roi %s <-> dirty %s roi %s expand %d iou %f",
cur_channel_name.c_str(), cur_camera_name.c_str(), cur_channel_name.c_str(), cur_camera_name.c_str(),
CheckUtil::GetRectString(qx_product_roi).c_str(), CheckUtil::GetRectString(qx_product_roi).c_str(),
sourceList.at(i).channel_name.c_str(), dirtyList.at(i).channel_name.c_str(),
CheckUtil::GetRectString(source_roi).c_str(), CheckUtil::GetRectString(dirty_roi).c_str(),
roi_expand, fiou); roi_expand, fiou);
} }
// IOU 为 NaN(ROI 非法导致的除零)时比较结果为 false,不会误抑制 NG // IOU 为 NaN(ROI 非法导致的除零)时比较结果为 false,不会误抑制 NG
@ -462,11 +410,11 @@ bool QX_Merge_Analysis::IsOverlapDirtyInCorrelatedChannel(const std::vector<std:
if (plog) if (plog)
{ {
plog->AddCheckstr(PrintLevel_1, 3, "CorrelatedDirty", plog->AddCheckstr(PrintLevel_1, 3, "CorrelatedDirty",
"cur %s cam %s roi %s overlap source %s cam %s roi %s expand %d iou %f > %f", "cur %s cam %s roi %s overlap dirty %s cam %s roi %s expand %d iou %f > %f",
cur_channel_name.c_str(), cur_camera_name.c_str(), cur_channel_name.c_str(), cur_camera_name.c_str(),
CheckUtil::GetRectString(qx_product_roi).c_str(), CheckUtil::GetRectString(qx_product_roi).c_str(),
sourceList.at(i).channel_name.c_str(), sourceList.at(i).camera_name.c_str(), dirtyList.at(i).channel_name.c_str(), dirtyList.at(i).camera_name.c_str(),
CheckUtil::GetRectString(source_roi).c_str(), CheckUtil::GetRectString(dirty_roi).c_str(),
roi_expand, fiou, iou_threshold); roi_expand, fiou, iou_threshold);
} }
return true; return true;
@ -477,7 +425,7 @@ bool QX_Merge_Analysis::IsOverlapDirtyInCorrelatedChannel(const std::vector<std:
} }
/** /**
* @brief 关联通道过滤源重叠判断(供外部调用):使用内置关联通道/IOU配置判断缺陷是否与关联通道过滤源缺陷重叠 * @brief 关联通道脏污重叠判断(供外部调用):使用内置关联通道/IOU配置判断缺陷是否与关联通道脏污重叠
* @param cur_channel_name 当前缺陷所属通道 * @param cur_channel_name 当前缺陷所属通道
* @param cur_camera_name 当前缺陷所属相机 * @param cur_camera_name 当前缺陷所属相机
* @param qx_product_roi 当前缺陷的产品坐标系ROI * @param qx_product_roi 当前缺陷的产品坐标系ROI
@ -503,7 +451,7 @@ bool QX_Merge_Analysis::IsDirtyOverlapInCorrelatedChannel(const std::string &cur
} }
/** /**
* @brief 关联过滤源过滤:将与该通道内关联通道过滤源缺陷(脏污/暗点等)重叠的缺陷从列表中移除, * @brief 关联通道脏污过滤:将与该通道内关联通道脏污缺陷重叠的缺陷从列表中移除,
* 使其不参与后续数量/距离/S分析,也不会被判为NG * 使其不参与后续数量/距离/S分析,也不会被判为NG
* @param pALLTypeqxList 当前缺陷类型的缺陷列表 * @param pALLTypeqxList 当前缺陷类型的缺陷列表
* @return int 被过滤的缺陷个数 * @return int 被过滤的缺陷个数
@ -543,7 +491,7 @@ int QX_Merge_Analysis::FilterCorrelatedDirtyQx(ALL_Qx_DataList *pALLTypeqxList)
if (pQXChannelList->pChannelDetlog) if (pQXChannelList->pChannelDetlog)
{ {
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter", pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter",
"channel %s cam %s blob %d roi %s : 关联通道存在重叠的过滤源缺陷, 过滤该暗点(不参与数量/距离分析)", "channel %s cam %s blob %d roi %s : 关联通道存在重叠脏污, 过滤该暗点(不参与数量/距离分析)",
pQXChannelList->qxList.at(j).channel_name.c_str(), pQXChannelList->qxList.at(j).channel_name.c_str(),
pQXChannelList->qxList.at(j).camera_name.c_str(), pQXChannelList->qxList.at(j).camera_name.c_str(),
pQXChannelList->qxList.at(j).blobIdx, pQXChannelList->qxList.at(j).blobIdx,
@ -552,7 +500,7 @@ int QX_Merge_Analysis::FilterCorrelatedDirtyQx(ALL_Qx_DataList *pALLTypeqxList)
if (m_pMergedetlog) if (m_pMergedetlog)
{ {
m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter", m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter",
"channel %s cam %s blob %d roi %s : 关联通道存在重叠的过滤源缺陷, 过滤该暗点(不参与数量/距离分析)", "channel %s cam %s blob %d roi %s : 关联通道存在重叠脏污, 过滤该暗点(不参与数量/距离分析)",
pQXChannelList->qxList.at(j).channel_name.c_str(), pQXChannelList->qxList.at(j).channel_name.c_str(),
pQXChannelList->qxList.at(j).camera_name.c_str(), pQXChannelList->qxList.at(j).camera_name.c_str(),
pQXChannelList->qxList.at(j).blobIdx, pQXChannelList->qxList.at(j).blobIdx,
@ -1007,13 +955,13 @@ int QX_Merge_Analysis::Analysis_QXtype(ALL_Qx_DataList *pALLTypeqxList, int qx_i
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "Num And Dis Judge", "pALLTypeqxList->channelqxList.size() %ld", m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "Num And Dis Judge", "pALLTypeqxList->channelqxList.size() %ld",
pALLTypeqxList->channelqxList.size()); pALLTypeqxList->channelqxList.size());
// 关联过滤源过滤:AD 分析前先过滤与关联通道过滤源缺陷重叠的缺陷,使其不参与数量/距离/S分析,也不会被判NG // 关联通道脏污过滤:AD 分析前先过滤与关联通道脏污重叠的缺陷,使其不参与数量/距离/S分析,也不会被判NG
if (qx_idx == QX_ANALYSIS_AD) if (qx_idx == QX_ANALYSIS_AD)
{ {
int nFilterNum = FilterCorrelatedDirtyQx(pALLTypeqxList); int nFilterNum = FilterCorrelatedDirtyQx(pALLTypeqxList);
if (nFilterNum > 0) if (nFilterNum > 0)
{ {
m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter", "%s 关联通道过滤源过滤 %d 个缺陷", m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter", "%s 关联通道脏污过滤 %d 个缺陷",
QX_ANALYSIS_NAME_Names[qx_idx].c_str(), nFilterNum); QX_ANALYSIS_NAME_Names[qx_idx].c_str(), nFilterNum);
} }
} }
@ -1028,35 +976,7 @@ int QX_Merge_Analysis::Analysis_QXtype(ALL_Qx_DataList *pALLTypeqxList, int qx_i
{ {
if(m_pbaseCheckFunction->ad_check.analysis_bind.bUse) if(m_pbaseCheckFunction->ad_check.analysis_bind.bUse)
{ {
// 主通道为空: Analysis_AD_Bind 返回回退码, 用次通道列表里的通道走 Analysis_AD 老逻辑 Analysis_AD_Bind(pALLTypeqxList, qx_idx);
if (Analysis_AD_Bind(pALLTypeqxList, qx_idx) == AD_BIND_RE_MAIN_EMPTY)
{
// 回退过滤: 仅次通道列表(2s_second_channel + 3s_second_channel, 去重)中的通道参与
std::vector<std::string> fallback_channels;
const std::vector<std::string> &fallback_sec2 = m_pbaseCheckFunction->ad_check.analysis_bind.second_channel_2s;
const std::vector<std::string> &fallback_sec3 = m_pbaseCheckFunction->ad_check.analysis_bind.second_channel_3s;
fallback_channels.insert(fallback_channels.end(), fallback_sec2.begin(), fallback_sec2.end());
for (size_t k = 0; k < fallback_sec3.size(); k++)
{
if (std::find(fallback_channels.begin(), fallback_channels.end(), fallback_sec3[k]) == fallback_channels.end())
{
fallback_channels.push_back(fallback_sec3[k]);
}
}
std::string strFallbackChannels;
for (size_t k = 0; k < fallback_channels.size(); k++)
{
strFallbackChannels += fallback_channels[k];
if (k + 1 < fallback_channels.size())
{
strFallbackChannels += ",";
}
}
m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "Analysis_AD_Bind",
"main channel empty --> fallback Analysis_AD (only second channels: %s)",
fallback_channels.empty() ? "<empty>" : strFallbackChannels.c_str());
Analysis_AD(pALLTypeqxList, qx_idx, &fallback_channels);
}
} }
else else
{ {
@ -1104,7 +1024,7 @@ int QX_Merge_Analysis::Judge_NG_Config()
return 0; return 0;
} }
int QX_Merge_Analysis::Analysis_AD(ALL_Qx_DataList *pALLTypeqxList, int qx_idx, const std::vector<std::string> *pAllowChannels) int QX_Merge_Analysis::Analysis_AD(ALL_Qx_DataList *pALLTypeqxList, int qx_idx)
{ {
AD_list.clear(); AD_list.clear();
if (!m_pbaseCheckFunction) if (!m_pbaseCheckFunction)
@ -1123,14 +1043,6 @@ int QX_Merge_Analysis::Analysis_AD(ALL_Qx_DataList *pALLTypeqxList, int qx_idx,
{ {
QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i]; QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i];
// 回退过滤: pAllowChannels 非空时仅允许列表内(次通道列表)的通道参与
if (pAllowChannels &&
std::find(pAllowChannels->begin(), pAllowChannels->end(), pQXChannelList->channel_name) == pAllowChannels->end())
{
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_1, 3, "Analysis_AD",
"channel %s not in allow list(fallback) --> skip", pQXChannelList->channel_name.c_str());
continue;
}
if (!pAd_checkParma) if (!pAd_checkParma)
{ {
continue; continue;
@ -1375,14 +1287,6 @@ int QX_Merge_Analysis::Analysis_AD(ALL_Qx_DataList *pALLTypeqxList, int qx_idx,
{ {
QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i]; QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i];
// 回退过滤: pAllowChannels 非空时仅允许列表内(次通道列表)的通道被判定NG
if (pAllowChannels &&
std::find(pAllowChannels->begin(), pAllowChannels->end(), pQXChannelList->channel_name) == pAllowChannels->end())
{
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_1, 3, "Analysis_AD",
"channel %s not in allow list(fallback) --> skip NG mark", pQXChannelList->channel_name.c_str());
continue;
}
if (!pAd_checkParma->bOpen) if (!pAd_checkParma->bOpen)
{ {
@ -1550,9 +1454,8 @@ int QX_Merge_Analysis::Analysis_AD_Bind(ALL_Qx_DataList *pALLTypeqxList, int qx_
/* 获取关联通道(已在 Analysis_QXtype 的过滤阶段使用, 此处仅打印) */ /* 获取关联通道(已在 Analysis_QXtype 的过滤阶段使用, 此处仅打印) */
vector<string> correlated_channels = pAd_checkParma->analysis_bind.correlated_channels; vector<string> correlated_channels = pAd_checkParma->analysis_bind.correlated_channels;
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "Analysis_AD_Bind", "bind main_2s %d second_2s %d main_3s %d second_3s %d correlated_channels %d correlated_types %d", m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "Analysis_AD_Bind", "bind main_2s %d second_2s %d main_3s %d second_3s %d correlated %d",
(int)main_channel_2s.size(), (int)second_channel_2s.size(), (int)main_channel_3s.size(), (int)second_channel_3s.size(), (int)main_channel_2s.size(), (int)second_channel_2s.size(), (int)main_channel_3s.size(), (int)second_channel_3s.size(), (int)correlated_channels.size());
(int)correlated_channels.size(), (int)pAd_checkParma->analysis_bind.correlated_types.size());
/* 获取主次通道的缺陷列表 */ /* 获取主次通道的缺陷列表 */
vector<QX_channel_List> main_channel_s_qxList; vector<QX_channel_List> main_channel_s_qxList;
@ -1593,12 +1496,6 @@ int QX_Merge_Analysis::Analysis_AD_Bind(ALL_Qx_DataList *pALLTypeqxList, int qx_
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "Analysis_AD_Bind", "main_channel %d second_channel %d", m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "Analysis_AD_Bind", "main_channel %d second_channel %d",
(int)main_channel_s_qxList.size(), (int)second_channel_s_qxList.size()); (int)main_channel_s_qxList.size(), (int)second_channel_s_qxList.size());
/* 主通道为空(配置为空或本次无匹配通道): 返回回退码, 由调用方改用 Analysis_AD 老逻辑 */
if (main_channel_s_qxList.empty())
{
return AD_BIND_RE_MAIN_EMPTY;
}
/* 画面分析 */ /* 画面分析 */
AD_list_bind.clear(); AD_list_bind.clear();
for(int i_main = 0; i_main < main_channel_s_qxList.size(); i_main++) for(int i_main = 0; i_main < main_channel_s_qxList.size(); i_main++)
@ -1879,7 +1776,7 @@ int QX_Merge_Analysis::Analysis_AD_Bind(ALL_Qx_DataList *pALLTypeqxList, int qx_
// 已经NG // 已经NG
if (bNG) if (bNG)
{ {
// 注:与关联通道过滤源缺陷重叠的缺陷已在 FilterCorrelatedDirtyQx(AD分析前) 中过滤,此处不会再被记录NG // 注:与关联通道脏污重叠的缺陷已在 FilterCorrelatedDirtyQx(AD分析前) 中过滤,此处不会再被记录NG
QX_channel_List *pqxList = pQXChannelList; QX_channel_List *pqxList = pQXChannelList;
for (int idx = 0; idx < (int)pqxList->qxList.size(); idx++) for (int idx = 0; idx < (int)pqxList->qxList.size(); idx++)

@ -1587,9 +1587,6 @@ struct AD_Analysisy_Bind
std::vector<std::string> main_channel_3s; std::vector<std::string> main_channel_3s;
std::vector<std::string> second_channel_3s; std::vector<std::string> second_channel_3s;
std::vector<std::string> correlated_channels; std::vector<std::string> correlated_channels;
// 关联过滤源缺陷类型名称(CONFIG_QX_NAME_Names 中的名称, 如 "Dirty_L0"/"Dirty_L1"/"Dirty_L2"/"AD")
// 仅这些类型的缺陷会被登记为过滤源(与 correlated_channels 配合使用); 为空时默认三种脏污(兼容旧配置)
std::vector<std::string> correlated_types;
AD_Analysisy_Bind() AD_Analysisy_Bind()
{ {
@ -1603,7 +1600,6 @@ struct AD_Analysisy_Bind
main_channel_3s.clear(); main_channel_3s.clear();
second_channel_3s.clear(); second_channel_3s.clear();
correlated_channels.clear(); correlated_channels.clear();
correlated_types.clear();
} }
void copy (AD_Analysisy_Bind tem) void copy (AD_Analysisy_Bind tem)
{ {
@ -1613,7 +1609,6 @@ struct AD_Analysisy_Bind
this->main_channel_3s = tem.main_channel_3s; this->main_channel_3s = tem.main_channel_3s;
this->second_channel_3s = tem.second_channel_3s; this->second_channel_3s = tem.second_channel_3s;
this->correlated_channels = tem.correlated_channels; this->correlated_channels = tem.correlated_channels;
this->correlated_types = tem.correlated_types;
} }
std::string GetInfo(std::string str) std::string GetInfo(std::string str)
{ {

@ -1482,17 +1482,6 @@ int BaseFuntonConfigJson::GetFunction(Json::Value value)
} }
} }
// 关联过滤源缺陷类型(如 ["Dirty_L0","Dirty_L1","Dirty_L2","AD"])
value_qx = value_f["form"]["Bind_Channel"]["correlated_types"];
if (value_qx.isArray())
{
for (int idx = 0; idx < value_qx.size(); idx++)
{
std::string qx_type = value_qx[idx].asString();
_config.ad_check.analysis_bind.correlated_types.push_back(qx_type);
}
}
// 同画面分析 // 同画面分析
value_qx = value_f["form"]["Single_Channel"]["s_channel"]; value_qx = value_f["form"]["Single_Channel"]["s_channel"];
if (value_qx.isArray()) if (value_qx.isArray())

Loading…
Cancel
Save