|
|
|
@ -424,6 +424,98 @@ bool QX_Merge_Analysis::IsOverlapDirtyInCorrelatedChannel(const std::vector<std:
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief 关联通道脏污重叠判断(供外部调用):使用内置关联通道/IOU配置判断缺陷是否与关联通道脏污重叠
|
|
|
|
|
|
|
|
* @param cur_channel_name 当前缺陷所属通道
|
|
|
|
|
|
|
|
* @param cur_camera_name 当前缺陷所属相机
|
|
|
|
|
|
|
|
* @param qx_product_roi 当前缺陷的产品坐标系ROI
|
|
|
|
|
|
|
|
* @param plog 日志
|
|
|
|
|
|
|
|
* @return bool 重叠返回true
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool QX_Merge_Analysis::IsDirtyOverlapInCorrelatedChannel(const std::string &cur_channel_name,
|
|
|
|
|
|
|
|
const std::string &cur_camera_name,
|
|
|
|
|
|
|
|
const cv::Rect &qx_product_roi,
|
|
|
|
|
|
|
|
std::shared_ptr<DetLog> plog)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (m_pbaseCheckFunction == nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Base_Function_AD_Check *pAd_checkParma = &m_pbaseCheckFunction->ad_check;
|
|
|
|
|
|
|
|
const std::vector<std::string> &correlated_channels = pAd_checkParma->analysis_bind.correlated_channels;
|
|
|
|
|
|
|
|
const int roi_expand = (int)(round)(pAd_checkParma->analysis_iou.AD_Expand);
|
|
|
|
|
|
|
|
const float iou_threshold = pAd_checkParma->analysis_iou.AD_IOU;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return IsOverlapDirtyInCorrelatedChannel(correlated_channels, cur_channel_name, cur_camera_name,
|
|
|
|
|
|
|
|
qx_product_roi, roi_expand, iou_threshold, plog);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief 关联通道脏污过滤:将与该通道内关联通道脏污缺陷重叠的缺陷从列表中移除,
|
|
|
|
|
|
|
|
* 使其不参与后续数量/距离/S分析,也不会被判为NG
|
|
|
|
|
|
|
|
* @param pALLTypeqxList 当前缺陷类型的缺陷列表
|
|
|
|
|
|
|
|
* @return int 被过滤的缺陷个数
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QX_Merge_Analysis::FilterCorrelatedDirtyQx(ALL_Qx_DataList *pALLTypeqxList)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (m_pbaseCheckFunction == nullptr || pALLTypeqxList == nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Base_Function_AD_Check *pAd_checkParma = &m_pbaseCheckFunction->ad_check;
|
|
|
|
|
|
|
|
const std::vector<std::string> correlated_channels = pAd_checkParma->analysis_bind.correlated_channels;
|
|
|
|
|
|
|
|
// 未配置关联通道(NONE/空)时不需要过滤
|
|
|
|
|
|
|
|
if (correlated_channels.empty())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const int roi_expand = (int)(round)(pAd_checkParma->analysis_iou.AD_Expand);
|
|
|
|
|
|
|
|
const float iou_threshold = pAd_checkParma->analysis_iou.AD_IOU;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int nFilterNum = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)pALLTypeqxList->channelqxList.size(); i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i];
|
|
|
|
|
|
|
|
std::vector<QX_Info> temQxList;
|
|
|
|
|
|
|
|
temQxList.reserve(pQXChannelList->qxList.size());
|
|
|
|
|
|
|
|
for (int j = 0; j < (int)pQXChannelList->qxList.size(); j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (IsOverlapDirtyInCorrelatedChannel(correlated_channels,
|
|
|
|
|
|
|
|
pQXChannelList->qxList.at(j).channel_name,
|
|
|
|
|
|
|
|
pQXChannelList->qxList.at(j).camera_name,
|
|
|
|
|
|
|
|
pQXChannelList->qxList.at(j).product_roi,
|
|
|
|
|
|
|
|
roi_expand, iou_threshold,
|
|
|
|
|
|
|
|
pQXChannelList->pChannelDetlog))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
nFilterNum++;
|
|
|
|
|
|
|
|
if (pQXChannelList->pChannelDetlog)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter",
|
|
|
|
|
|
|
|
"channel %s cam %s blob %d roi %s : 关联通道存在重叠脏污, 过滤该暗点(不参与数量/距离分析)",
|
|
|
|
|
|
|
|
pQXChannelList->qxList.at(j).channel_name.c_str(),
|
|
|
|
|
|
|
|
pQXChannelList->qxList.at(j).camera_name.c_str(),
|
|
|
|
|
|
|
|
pQXChannelList->qxList.at(j).blobIdx,
|
|
|
|
|
|
|
|
CheckUtil::GetRectString(pQXChannelList->qxList.at(j).product_roi).c_str());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_pMergedetlog)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter",
|
|
|
|
|
|
|
|
"channel %s cam %s blob %d roi %s : 关联通道存在重叠脏污, 过滤该暗点(不参与数量/距离分析)",
|
|
|
|
|
|
|
|
pQXChannelList->qxList.at(j).channel_name.c_str(),
|
|
|
|
|
|
|
|
pQXChannelList->qxList.at(j).camera_name.c_str(),
|
|
|
|
|
|
|
|
pQXChannelList->qxList.at(j).blobIdx,
|
|
|
|
|
|
|
|
CheckUtil::GetRectString(pQXChannelList->qxList.at(j).product_roi).c_str());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
temQxList.push_back(pQXChannelList->qxList.at(j));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pQXChannelList->qxList.swap(temQxList);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nFilterNum;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @brief 等待所有任务完成
|
|
|
|
* @brief 等待所有任务完成
|
|
|
|
* @param timeoutMs 超时时间(毫秒)
|
|
|
|
* @param timeoutMs 超时时间(毫秒)
|
|
|
|
@ -863,6 +955,16 @@ 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
|
|
|
|
|
|
|
|
if (qx_idx == QX_ANALYSIS_AD)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int nFilterNum = FilterCorrelatedDirtyQx(pALLTypeqxList);
|
|
|
|
|
|
|
|
if (nFilterNum > 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "DirtyCorrelatedFilter", "%s 关联通道脏污过滤 %d 个缺陷",
|
|
|
|
|
|
|
|
QX_ANALYSIS_NAME_Names[qx_idx].c_str(), nFilterNum);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
for (int i = 0; i < pALLTypeqxList->channelqxList.size(); i++)
|
|
|
|
for (int i = 0; i < pALLTypeqxList->channelqxList.size(); i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i];
|
|
|
|
QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i];
|
|
|
|
@ -1349,11 +1451,11 @@ int QX_Merge_Analysis::Analysis_AD_Bind(ALL_Qx_DataList *pALLTypeqxList, int qx_
|
|
|
|
vector<string> second_channel_2s = pAd_checkParma->analysis_bind.second_channel_2s;
|
|
|
|
vector<string> second_channel_2s = pAd_checkParma->analysis_bind.second_channel_2s;
|
|
|
|
vector<string> main_channel_3s = pAd_checkParma->analysis_bind.main_channel_3s;
|
|
|
|
vector<string> main_channel_3s = pAd_checkParma->analysis_bind.main_channel_3s;
|
|
|
|
vector<string> second_channel_3s = pAd_checkParma->analysis_bind.second_channel_3s;
|
|
|
|
vector<string> second_channel_3s = pAd_checkParma->analysis_bind.second_channel_3s;
|
|
|
|
/* 获取关联通道 */
|
|
|
|
/* 获取关联通道(已在 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",
|
|
|
|
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());
|
|
|
|
|
|
|
|
|
|
|
|
/* 获取主次通道的缺陷列表 */
|
|
|
|
/* 获取主次通道的缺陷列表 */
|
|
|
|
vector<QX_channel_List> main_channel_s_qxList;
|
|
|
|
vector<QX_channel_List> main_channel_s_qxList;
|
|
|
|
@ -1674,9 +1776,7 @@ int QX_Merge_Analysis::Analysis_AD_Bind(ALL_Qx_DataList *pALLTypeqxList, int qx_
|
|
|
|
// 已经NG
|
|
|
|
// 已经NG
|
|
|
|
if (bNG)
|
|
|
|
if (bNG)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 注意:按缺陷(blob)粒度逐条判断,避免把同一通道内与脏污无关的缺陷也一并放过
|
|
|
|
// 注:与关联通道脏污重叠的缺陷已在 FilterCorrelatedDirtyQx(AD分析前) 中过滤,此处不会再被记录NG
|
|
|
|
const int roi_expand = (int)(round)(pAd_checkParma->analysis_iou.AD_Expand);
|
|
|
|
|
|
|
|
const float iou_threshold = pAd_checkParma->analysis_iou.AD_IOU;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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++)
|
|
|
|
@ -1686,29 +1786,6 @@ int QX_Merge_Analysis::Analysis_AD_Bind(ALL_Qx_DataList *pALLTypeqxList, int qx_
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 关联通道存在与当前缺陷重叠的脏污缺陷时,该缺陷不记录NG结果
|
|
|
|
|
|
|
|
if (IsOverlapDirtyInCorrelatedChannel(correlated_channels,
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).channel_name,
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).camera_name,
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).product_roi,
|
|
|
|
|
|
|
|
roi_expand, iou_threshold,
|
|
|
|
|
|
|
|
pqxList->pChannelDetlog))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pqxList->pChannelDetlog->AddCheckstr(PrintLevel_1, 3, "result = NG skip",
|
|
|
|
|
|
|
|
"channel %s cam %s blob %d roi %s : 关联通道存在重叠, 不记录NG结果",
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).channel_name.c_str(),
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).camera_name.c_str(),
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).blobIdx,
|
|
|
|
|
|
|
|
CheckUtil::GetRectString(pqxList->qxList.at(idx).product_roi).c_str());
|
|
|
|
|
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_1, 3, "result = NG skip",
|
|
|
|
|
|
|
|
"channel %s cam %s blob %d roi %s : 关联通道存在重叠, 不记录NG结果",
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).channel_name.c_str(),
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).camera_name.c_str(),
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).blobIdx,
|
|
|
|
|
|
|
|
CheckUtil::GetRectString(pqxList->qxList.at(idx).product_roi).c_str());
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pqxList->qxList.at(idx).result = 1;
|
|
|
|
pqxList->qxList.at(idx).result = 1;
|
|
|
|
|
|
|
|
|
|
|
|
QX_RESULT tem;
|
|
|
|
QX_RESULT tem;
|
|
|
|
|