|
|
|
@ -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++)
|
|
|
|
|