|
|
#include "QX_Merge_Analysis.h"
|
|
|
#include <memory>
|
|
|
#include <string>
|
|
|
#include <mutex>
|
|
|
#include <thread>
|
|
|
#include <chrono>
|
|
|
#include "CheckUtil.hpp"
|
|
|
#include "CheckConfigDefine.h"
|
|
|
|
|
|
QX_Merge_Analysis::QX_Merge_Analysis()
|
|
|
{
|
|
|
m_bExit = false;
|
|
|
Clear();
|
|
|
StartThread(0);
|
|
|
}
|
|
|
|
|
|
QX_Merge_Analysis::~QX_Merge_Analysis()
|
|
|
{
|
|
|
StopThread();
|
|
|
}
|
|
|
|
|
|
std::shared_ptr<QX_Merge_Analysis> QX_Merge_Analysis::GetInstance()
|
|
|
{
|
|
|
std::shared_ptr<QX_Merge_Analysis> instance = std::make_shared<QX_Merge_Analysis>();
|
|
|
return instance;
|
|
|
}
|
|
|
int QX_Merge_Analysis::Clear()
|
|
|
{
|
|
|
m_pdetlogList.clear();
|
|
|
m_statusList.clear();
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
int QX_Merge_Analysis::AddCamer(std::string cameraName)
|
|
|
{
|
|
|
setSendStatus(cameraName, RUN_STATUS_NULL);
|
|
|
for (auto &it : m_statusList)
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "QX_Merge_Analysis", "AddCamer %s %d", it.first.c_str(), it.second);
|
|
|
}
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "QX_Merge_Analysis", "AddCamer %s %s", cameraName.c_str(),CheckUtil::getCurTimeHMS().c_str());
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
int QX_Merge_Analysis::InitData()
|
|
|
{
|
|
|
m_reultList.Init();
|
|
|
m_pMergedetlog = std::make_shared<DetLog>();
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "QX_Merge_Analysis", "InitData %s",CheckUtil::getCurTimeHMS().c_str());
|
|
|
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_QXList);
|
|
|
for (int i = 0; i < QX_ANALYSIS_COUNT; i++)
|
|
|
{
|
|
|
m_QXList[i].Init();
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::GetReusult(QX_Analysis_Result_List *&presult)
|
|
|
{
|
|
|
presult = &m_reultList;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
void QX_Merge_Analysis::SetConfig(std::string cameraName, int qxidx,
|
|
|
QXAnalysis_Config config)
|
|
|
{
|
|
|
if (cameraName == "")
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
// if (cameraName != QX_MEREGE_CONFIG_CAMERA_NAME)
|
|
|
// {
|
|
|
// return;
|
|
|
// }
|
|
|
|
|
|
ALL_QX_ParamList *pqxConfigList = nullptr;
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_ConfigList); //
|
|
|
pqxConfigList = &m_ConfigList[qxidx];
|
|
|
pqxConfigList->configlsit.push_back(config);
|
|
|
}
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "QX_Merge_Analysis", "SetConfig cameraName %s qxidx %d ", cameraName.c_str(), qxidx);
|
|
|
}
|
|
|
|
|
|
void QX_Merge_Analysis::InitConfig(std::string cameraName)
|
|
|
{
|
|
|
// if (cameraName != QX_MEREGE_CONFIG_CAMERA_NAME)
|
|
|
// {
|
|
|
// return;
|
|
|
// }
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_ConfigList);
|
|
|
for (int i = 0; i < QX_ANALYSIS_COUNT; i++)
|
|
|
{
|
|
|
m_ConfigList[i].Init();
|
|
|
}
|
|
|
}
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "QX_Merge_Analysis", "InitConfig cameraName %s ", cameraName.c_str());
|
|
|
}
|
|
|
|
|
|
void QX_Merge_Analysis::SetbaseCheckFunction(std::string cameraName, ALLChannelCheckFunction *pChannelFuntion, BaseCheckFunction *pbaseCheckFunction)
|
|
|
{
|
|
|
if (cameraName == "")
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
// if (cameraName != QX_MEREGE_CONFIG_CAMERA_NAME)
|
|
|
// {
|
|
|
// return;
|
|
|
// }
|
|
|
m_pChannelFuntion = pChannelFuntion;
|
|
|
m_pbaseCheckFunction = pbaseCheckFunction;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::ConfigTypeToQXAnalysis(int nconfigType)
|
|
|
{
|
|
|
int QXAnalysis_type = -1;
|
|
|
switch (nconfigType)
|
|
|
{
|
|
|
case CONFIG_QX_NAME_POL_Cell:
|
|
|
QXAnalysis_type = QX_ANALYSIS_POL_CELL; // 异物
|
|
|
break;
|
|
|
case CONFIG_QX_NAME_AD:
|
|
|
QXAnalysis_type = QX_ANALYSIS_AD; // 暗点
|
|
|
break;
|
|
|
case CONFIG_QX_NAME_Scratch_L1:
|
|
|
case CONFIG_QX_NAME_Scratch_L2:
|
|
|
QXAnalysis_type = QX_ANALYSIS_Scratch; // 划伤
|
|
|
break;
|
|
|
case CONFIG_QX_NAME_X_line:
|
|
|
case CONFIG_QX_NAME_Y_line:
|
|
|
case CONFIG_QX_NAME_line:
|
|
|
case CONFIG_QX_NAME_Fangge:
|
|
|
QXAnalysis_type = QX_ANALYSIS_LINE; // 线类
|
|
|
break;
|
|
|
case CONFIG_QX_NAME_MTX:
|
|
|
QXAnalysis_type = QX_ANALYSIS_MTX; // MTX
|
|
|
break;
|
|
|
// case CONFIG_QX_NAME_Broken_line:
|
|
|
// QXAnalysis_type = QX_ANALYSIS_ALL, // MTX&异物
|
|
|
// break;
|
|
|
|
|
|
default:
|
|
|
QXAnalysis_type = -1;
|
|
|
break;
|
|
|
}
|
|
|
return QXAnalysis_type;
|
|
|
}
|
|
|
bool QX_Merge_Analysis::Idx(int qxidx)
|
|
|
{
|
|
|
if (qxidx < 0 || qxidx >= QX_ANALYSIS_COUNT)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
bool QX_Merge_Analysis::AddQxInfo(int qxidx, QX_Info qxinfo, std::shared_ptr<DetLog> plog, std::shared_ptr<DetLog> pchannelLog)
|
|
|
{
|
|
|
std::string channel_name = qxinfo.channel_name;
|
|
|
std::string cam_name = qxinfo.camera_name;
|
|
|
ALL_QX_ParamList *pconfigList = nullptr;
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_ConfigList);
|
|
|
pconfigList = &m_ConfigList[qxidx];
|
|
|
}
|
|
|
|
|
|
if (pconfigList == nullptr)
|
|
|
{
|
|
|
plog->AddCheckstr(PrintLevel_3, 3, "AddQxInfo", "cam_name = %s config error",
|
|
|
cam_name.c_str());
|
|
|
return false;
|
|
|
}
|
|
|
if (!Idx(qxidx))
|
|
|
{
|
|
|
plog->AddCheckstr(PrintLevel_3, 3, "AddQxInfo", "qxidx error");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 初步筛选一次
|
|
|
bool badd = false;
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_ConfigList);
|
|
|
for (int i = 0; i < (int)pconfigList->configlsit.size(); i++)
|
|
|
{
|
|
|
QXAnalysis_Config *pconfig = &pconfigList->configlsit.at(i);
|
|
|
// 面积 灰阶满足要求
|
|
|
if (qxinfo.area >= pconfig->area &&
|
|
|
qxinfo.hj >= pconfig->hj &&
|
|
|
qxinfo.length >= pconfig->len &&
|
|
|
qxinfo.density >= pconfig->density)
|
|
|
{
|
|
|
badd = true;
|
|
|
}
|
|
|
plog->AddCheckstr(PrintLevel_3, 3, "preA", "add = %s congfig idx %d / %d ", BOOL_TO_STR(badd), i, (int)pconfigList->configlsit.size());
|
|
|
plog->AddCheckstr(PrintLevel_4, 3, "Area", "%s -> %f %s %f ",
|
|
|
BOOL_TO_STR(qxinfo.area >= pconfig->area), qxinfo.area, BOOL_TO_ThanLess(qxinfo.area >= pconfig->area), pconfig->area);
|
|
|
plog->AddCheckstr(PrintLevel_4, 3, "HJ", "%s -> %f %s %d ",
|
|
|
BOOL_TO_STR(qxinfo.hj >= pconfig->hj), qxinfo.hj, BOOL_TO_ThanLess(qxinfo.hj >= pconfig->hj), pconfig->hj);
|
|
|
plog->AddCheckstr(PrintLevel_4, 3, "Len", "%s -> %f %s %f ",
|
|
|
BOOL_TO_STR(qxinfo.length >= pconfig->len), qxinfo.length, BOOL_TO_ThanLess(qxinfo.length >= pconfig->len), pconfig->len);
|
|
|
plog->AddCheckstr(PrintLevel_4, 3, "md", "%s -> %f %s %f ",
|
|
|
BOOL_TO_STR(qxinfo.density >= pconfig->density), qxinfo.density, BOOL_TO_ThanLess(qxinfo.density >= pconfig->density), pconfig->density);
|
|
|
|
|
|
if (badd)
|
|
|
{
|
|
|
break;
|
|
|
/* code */
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_QXList);
|
|
|
|
|
|
if (badd)
|
|
|
{
|
|
|
QX_channel_List *pQXChannelList = nullptr;
|
|
|
for (auto &config : m_QXList[qxidx].channelqxList)
|
|
|
{
|
|
|
if (config.channel_name == channel_name)
|
|
|
{
|
|
|
pQXChannelList = &config;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (pQXChannelList == nullptr)
|
|
|
{
|
|
|
plog->AddCheckstr(PrintLevel_3, 3, "AddQxInfo", "new channel_name %s ", channel_name.c_str());
|
|
|
QX_channel_List tempchannel;
|
|
|
tempchannel.channel_name = channel_name;
|
|
|
tempchannel.pChannelDetlog = pchannelLog;
|
|
|
tempchannel.qxList.push_back(qxinfo);
|
|
|
|
|
|
m_QXList[qxidx].channelqxList.push_back(tempchannel);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
plog->AddCheckstr(PrintLevel_3, 3, "AddQxInfo", "have channel_name %s ", channel_name.c_str());
|
|
|
pQXChannelList->pChannelDetlog2 = pchannelLog;
|
|
|
pQXChannelList->qxList.push_back(qxinfo);
|
|
|
}
|
|
|
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_3, 3, "AddQxInfo", "m_QXList[%d].channelqxList.size() = %d cam %s channel %s %s",
|
|
|
qxidx, (int)m_QXList[qxidx].channelqxList.size(), cam_name.c_str(), channel_name.c_str(), CheckUtil::getCurTimeHMS().c_str());
|
|
|
}
|
|
|
}
|
|
|
return badd;
|
|
|
}
|
|
|
|
|
|
bool QX_Merge_Analysis::setSendStatus(std::string cameraName, RUN_STATUS_ status)
|
|
|
{
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_status);
|
|
|
m_statusList[cameraName] = status;
|
|
|
}
|
|
|
cv_status.notify_all();
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief 等待所有任务完成
|
|
|
* @param timeoutMs 超时时间(毫秒)
|
|
|
* @return bool 如果所有任务在超时前完成返回true,否则返回false
|
|
|
*/
|
|
|
bool QX_Merge_Analysis::waitComplete(int timeoutMs)
|
|
|
{
|
|
|
// 使用互斥锁保护共享资源m_statusList
|
|
|
std::unique_lock<std::mutex> lock(mtx_status);
|
|
|
// 记录开始时间
|
|
|
auto startTime = std::chrono::steady_clock::now();
|
|
|
// 循环检查直到所有任务完成或超时或退出标志被设置
|
|
|
while (!m_bExit)
|
|
|
{
|
|
|
// 假设所有任务已完成
|
|
|
bool allComplete = !m_statusList.empty();
|
|
|
// 遍历状态列表检查每个任务的状态
|
|
|
for (auto &it : m_statusList)
|
|
|
{
|
|
|
// 如果发现未完成的任务,设置allComplete为false并跳出循环
|
|
|
if (it.second != RUN_STATUS_COMPLETE)
|
|
|
{
|
|
|
allComplete = false;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
// 如果所有任务都已完成,返回true
|
|
|
if (allComplete)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
|
std::chrono::steady_clock::now() - startTime)
|
|
|
.count();
|
|
|
if (elapsedMs >= timeoutMs)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
cv_status.wait_for(lock, std::chrono::milliseconds(100));
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::Run(int nId)
|
|
|
{
|
|
|
std::unique_lock<std::mutex> lock(mtx_status);
|
|
|
|
|
|
while (!m_bExit)
|
|
|
{
|
|
|
cv_status.wait(lock, [this]()
|
|
|
{
|
|
|
if (m_bExit)
|
|
|
return true;
|
|
|
if (m_statusList.empty())
|
|
|
return false;
|
|
|
for (auto &it : m_statusList)
|
|
|
{
|
|
|
if (it.second != RUN_STATUS_READY)
|
|
|
return false;
|
|
|
}
|
|
|
return true; });
|
|
|
|
|
|
if (m_bExit)
|
|
|
break;
|
|
|
|
|
|
if (!m_statusList.empty())
|
|
|
{
|
|
|
|
|
|
for (auto &it : m_statusList)
|
|
|
{
|
|
|
|
|
|
it.second = RUN_STATUS_BUSY;
|
|
|
}
|
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
StartAnalysis();
|
|
|
lock.lock();
|
|
|
|
|
|
for (auto &it : m_statusList)
|
|
|
{
|
|
|
it.second = RUN_STATUS_COMPLETE;
|
|
|
}
|
|
|
cv_status.notify_all();
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::StartThread(int nId)
|
|
|
{
|
|
|
// 开启检测线程
|
|
|
ptr_thread_Run = std::make_shared<std::thread>(std::bind(&QX_Merge_Analysis::Run, this, nId));
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::StopThread()
|
|
|
{
|
|
|
m_bExit = true;
|
|
|
cv_status.notify_all();
|
|
|
if (ptr_thread_Run != nullptr)
|
|
|
{
|
|
|
if (ptr_thread_Run->joinable())
|
|
|
{
|
|
|
ptr_thread_Run->join();
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::StartAnalysis()
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_0, 3, "Num And Dis Judge", "==========Start========%s", CheckUtil::getCurTimeHMS().c_str());
|
|
|
// 分析每一个缺陷类型
|
|
|
for (int i = 0; i < QX_ANALYSIS_COUNT; i++)
|
|
|
{
|
|
|
if (QX_ANALYSIS_POL_CELL != i && QX_ANALYSIS_AD != i && QX_ANALYSIS_MTX != i && QX_ANALYSIS_Scratch != i && QX_ANALYSIS_LINE != i)
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_0, 3, "Num And Dis Judge", "== %d 11", i);
|
|
|
continue;
|
|
|
}
|
|
|
if (m_QXList[i].channelqxList.size() <= 0 || m_ConfigList[i].configlsit.size() <= 0)
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_0, 3, "Num And Dis Judge", "== %d channelqxList %ld configlsit %ld",
|
|
|
i, m_QXList[i].channelqxList.size(), m_ConfigList[i].configlsit.size());
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_0, 3, "Num And Dis Judge", "%s start", QX_ANALYSIS_NAME_Names[i].c_str());
|
|
|
Analysis_QXtype(&m_QXList[i], i);
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_0, 3, "Num And Dis Judge", "%s end", QX_ANALYSIS_NAME_Names[i].c_str());
|
|
|
}
|
|
|
|
|
|
// presult = &m_reultList;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::Analysis_single_Config(QXAnalysis_Config *pconfig, QX_channel_List *pqxList, int qx_type, std::shared_ptr<DetLog> pchannelLog)
|
|
|
{
|
|
|
pchannelLog->AddCheckstr(PrintLevel_2, 3, "param",
|
|
|
" okparam = %d area %f max_area %f hj %d num %d dis %f len %f md %f",
|
|
|
pconfig->bok, pconfig->area, pconfig->sum_area, pconfig->hj, pconfig->num, pconfig->dis, pconfig->len, pconfig->density);
|
|
|
|
|
|
float sumarea = 0;
|
|
|
float fmaxarea = 0;
|
|
|
int num = 0;
|
|
|
// 遍历每一个相机
|
|
|
Pre_Analysisy_Param param;
|
|
|
param.fAreaMin = pconfig->area;
|
|
|
param.fHJMin = pconfig->hj;
|
|
|
param.fLenMin = pconfig->len;
|
|
|
param.fMdMin = pconfig->density;
|
|
|
|
|
|
pqxList->Initstatus();
|
|
|
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
|
|
|
{
|
|
|
std::string str = "";
|
|
|
// 面积 灰阶满足要求
|
|
|
if (pqxList->preDet(i, param, str))
|
|
|
{
|
|
|
num++;
|
|
|
pqxList->qxList.at(i).nstatus = 1;
|
|
|
sumarea += pqxList->qxList.at(i).area;
|
|
|
if (pqxList->qxList.at(i).area > fmaxarea)
|
|
|
{
|
|
|
fmaxarea = pqxList->qxList.at(i).area;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
pchannelLog->AddCheckstr(PrintLevel_3, 3, "preA", "qx_idx %d : %s count = %d; %s ",
|
|
|
i, Re_TO_STR_Pass_1(pqxList->qxList.at(i).nstatus), num,
|
|
|
pqxList->qxList.at(i).GetInfo().c_str(), str.c_str());
|
|
|
}
|
|
|
if (num <= 0 && pconfig->num > 0)
|
|
|
{
|
|
|
pchannelLog->AddCheckstr(PrintLevel_3, 3, "result", "fail num = 0");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
// 对距离有要求
|
|
|
if (pconfig->dis > 0)
|
|
|
{
|
|
|
pqxList->claDis();
|
|
|
}
|
|
|
|
|
|
if (pconfig->bok == 1 && num > 0)
|
|
|
{
|
|
|
// 只要有一个条件大于阈值参数,就NG;
|
|
|
std::string strresult = "param type=OK:";
|
|
|
bool bresult = true;
|
|
|
// 数量不满足要求。
|
|
|
if (num >= pconfig->num)
|
|
|
{
|
|
|
bresult = false;
|
|
|
strresult += "Num = false : " + std::to_string(num) + ">=" + std::to_string(pconfig->num) + ";";
|
|
|
int are = QX_ERROR_TYPE_NUM;
|
|
|
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
|
|
|
{
|
|
|
if (pqxList->qxList.at(i).nstatus == 1)
|
|
|
{
|
|
|
pqxList->qxList.at(i).nqx_type = QX_ERROR_TYPE_NUM;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
strresult += "Num = true: " + std::to_string(num) + "<" + std::to_string(pconfig->num) + ";";
|
|
|
}
|
|
|
|
|
|
float fmaxLen = 0;
|
|
|
bool blenerror = false;
|
|
|
float allmindis = 99999999999;
|
|
|
bool bdiserror = false;
|
|
|
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
|
|
|
{
|
|
|
if (pqxList->qxList.at(i).nstatus == 1)
|
|
|
{
|
|
|
if (pqxList->qxList.at(i).length > fmaxLen)
|
|
|
{
|
|
|
fmaxLen = pqxList->qxList.at(i).length;
|
|
|
}
|
|
|
// 长度超过阈值
|
|
|
if (pqxList->qxList.at(i).length > pconfig->len)
|
|
|
{
|
|
|
blenerror = true;
|
|
|
pqxList->qxList.at(i).nqx_type = QX_ERROR_TYPE_Len;
|
|
|
}
|
|
|
|
|
|
// 对距离有要求
|
|
|
if (pconfig->dis > 0)
|
|
|
{
|
|
|
if (pqxList->qxList.at(i).tem_dis_idx >= 0)
|
|
|
{
|
|
|
// 最小距离 大于 阈值
|
|
|
if (pqxList->qxList.at(i).tem_dis <= pconfig->dis)
|
|
|
{
|
|
|
bdiserror = true;
|
|
|
pqxList->qxList.at(i).nqx_type = QX_ERROR_TYPE_DIS;
|
|
|
pqxList->qxList.at(i).fmindis = pqxList->qxList.at(i).tem_dis;
|
|
|
pqxList->qxList.at(i).nmindis_BlobIdx = pqxList->qxList.at(i).tem_dis_idx;
|
|
|
}
|
|
|
if (pqxList->qxList.at(i).tem_dis < allmindis)
|
|
|
{
|
|
|
allmindis = pqxList->qxList.at(i).tem_dis;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (blenerror)
|
|
|
{
|
|
|
bresult = false;
|
|
|
strresult += "Len = false : " + std::to_string(fmaxLen) + ">=" + std::to_string(pconfig->len) + ";";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
strresult += "Len = true: " + std::to_string(fmaxLen) + ">=" + std::to_string(pconfig->len) + ";";
|
|
|
}
|
|
|
if (bdiserror)
|
|
|
{
|
|
|
bresult = false;
|
|
|
strresult += "dis = false : " + std::to_string(allmindis) + ">=" + std::to_string(pconfig->dis) + ";";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
strresult += "dis = true: " + std::to_string(allmindis) + ">=" + std::to_string(pconfig->dis) + ";";
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
|
|
|
{
|
|
|
|
|
|
if (pqxList->qxList.at(i).nqx_type > QX_ERROR_TYPE_OK)
|
|
|
{
|
|
|
if (pqxList->qxList.at(i).result == 0)
|
|
|
{
|
|
|
pqxList->qxList.at(i).result = 1;
|
|
|
|
|
|
QX_RESULT tem;
|
|
|
tem.blobIdx = pqxList->qxList.at(i).blobIdx;
|
|
|
tem.qx_Num = num;
|
|
|
tem.mindis = pqxList->qxList.at(i).fmindis;
|
|
|
tem.flen = pqxList->qxList.at(i).length;
|
|
|
tem.error_Type = pqxList->qxList.at(i).nqx_type;
|
|
|
tem.camera_name = pqxList->qxList.at(i).camera_name;
|
|
|
tem.channel_name = pqxList->qxList.at(i).channel_name;
|
|
|
pchannelLog->AddCheckstr(PrintLevel_4, 3, "result = NG", "Add New qx,Blob idx %d type %d num %d dis %f len %f ", tem.blobIdx, tem.error_Type, tem.qx_Num, tem.mindis, tem.flen);
|
|
|
|
|
|
m_reultList.resultList.push_back(tem);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
std::string strresult = "param type=NG:";
|
|
|
bool bpass = true;
|
|
|
if (num >= pconfig->num)
|
|
|
{
|
|
|
strresult += "Num = true : " + std::to_string(num) + ">=" + std::to_string(pconfig->num) + ";";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bpass = false;
|
|
|
strresult += "Num = false: " + std::to_string(num) + "<" + std::to_string(pconfig->num) + ";";
|
|
|
}
|
|
|
if (fmaxarea >= pconfig->sum_area)
|
|
|
{
|
|
|
strresult += "maxarea = true : " + std::to_string(fmaxarea) + ">=" + std::to_string(pconfig->sum_area) + ";";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bpass = false;
|
|
|
strresult += "maxarea = false: " + std::to_string(fmaxarea) + "<" + std::to_string(pconfig->sum_area) + ";";
|
|
|
}
|
|
|
// 数量满足要求
|
|
|
if (bpass)
|
|
|
{
|
|
|
float allmindis = 99999999999;
|
|
|
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
|
|
|
{
|
|
|
// pchannelLog->AddCheckstr(PrintLevel_4, 3, "ddddddd", "%d %f %f %s ",
|
|
|
// i, pqxList->qxList.at(i).plocatin_mm.x, pqxList->qxList.at(i).plocatin_mm.y,
|
|
|
// pqxList->qxList.at(i).GetInfo().c_str());
|
|
|
|
|
|
// 面积 灰阶满足要求
|
|
|
if (pqxList->qxList.at(i).nstatus == 1)
|
|
|
{
|
|
|
|
|
|
int minidx = -1;
|
|
|
bool bdis = true;
|
|
|
double remindis = 0;
|
|
|
// 对距离有要求
|
|
|
if (pconfig->dis > 0)
|
|
|
{
|
|
|
// pchannelLog->AddCheckstr(PrintLevel_3, 3, "result", "%d %f",i,pqxList->qxList.at(i).tem_dis);
|
|
|
if (pqxList->qxList.at(i).tem_dis_idx >= 0)
|
|
|
{
|
|
|
|
|
|
// 最小距离 大于 阈值
|
|
|
if (pqxList->qxList.at(i).tem_dis > pconfig->dis)
|
|
|
{
|
|
|
bdis = false;
|
|
|
}
|
|
|
if (pqxList->qxList.at(i).tem_dis < allmindis)
|
|
|
{
|
|
|
allmindis = pqxList->qxList.at(i).tem_dis;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
remindis = pqxList->qxList.at(i).tem_dis;
|
|
|
}
|
|
|
|
|
|
// 距离满足要求
|
|
|
if (bdis && pqxList->qxList.at(i).result == 0)
|
|
|
{
|
|
|
pqxList->qxList.at(i).result = 1;
|
|
|
|
|
|
QX_RESULT tem;
|
|
|
tem.blobIdx = pqxList->qxList.at(i).blobIdx;
|
|
|
tem.qx_Num = num;
|
|
|
tem.mindis = remindis;
|
|
|
tem.camera_name = pqxList->qxList.at(i).camera_name;
|
|
|
tem.channel_name = pqxList->qxList.at(i).channel_name;
|
|
|
if (pconfig->num <= 0 && pconfig->dis <= 0)
|
|
|
{
|
|
|
tem.error_Type = QX_ERROR_TYPE_AREA;
|
|
|
}
|
|
|
else if (pconfig->dis <= 0)
|
|
|
{
|
|
|
tem.error_Type = QX_ERROR_TYPE_NUM;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
tem.error_Type = QX_ERROR_TYPE_DIS;
|
|
|
}
|
|
|
pchannelLog->AddCheckstr(PrintLevel_4, 3, "Add New QX",
|
|
|
"result = NG, Add New qx,Blob idx %d -> num %d >= %d is true; dis %f <= %f is true; max_area %f >= %f is true ",
|
|
|
tem.blobIdx, num, pconfig->num, remindis, pconfig->dis, fmaxarea, pconfig->sum_area);
|
|
|
|
|
|
m_reultList.resultList.push_back(tem);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (pconfig->dis > 0)
|
|
|
{
|
|
|
if (allmindis <= pconfig->dis)
|
|
|
{
|
|
|
strresult += "dis = true : " + std::to_string(allmindis) + "<=" + std::to_string(pconfig->dis) + ";";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bpass = false;
|
|
|
strresult += "dis = false : " + std::to_string(allmindis) + ">" + std::to_string(pconfig->dis) + ";";
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
strresult += "dis = true : dis param is 0";
|
|
|
}
|
|
|
}
|
|
|
if (!bpass)
|
|
|
{
|
|
|
pchannelLog->AddCheckstr(PrintLevel_2, 3, "result", "OK==>%s", strresult.c_str());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
pchannelLog->AddCheckstr(PrintLevel_2, 3, "result", "NG==>%s", strresult.c_str());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::Analysis_QXtype(ALL_Qx_DataList *pALLTypeqxList, int qx_idx)
|
|
|
{
|
|
|
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "Num And Dis Judge", "pALLTypeqxList->channelqxList.size() %ld",
|
|
|
pALLTypeqxList->channelqxList.size());
|
|
|
for (int i = 0; i < pALLTypeqxList->channelqxList.size(); i++)
|
|
|
{
|
|
|
QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i];
|
|
|
|
|
|
Analysis_Channel(pQXChannelList, qx_idx);
|
|
|
}
|
|
|
// AD 要进行额外的分析
|
|
|
if (qx_idx == QX_ANALYSIS_AD)
|
|
|
{
|
|
|
Analysis_AD(pALLTypeqxList, qx_idx);
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::Analysis_Channel(QX_channel_List *pChannelqxList, int qx_idx)
|
|
|
{
|
|
|
int param_num = 0;
|
|
|
int param_dis = 0;
|
|
|
|
|
|
ALL_QX_ParamList *pConfigList = &m_ConfigList[qx_idx];
|
|
|
// 用单面相机的参数去处理 所有相机的缺陷。
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_3, 3, "Num And Dis Judge", "pConfigList->configlsit.size() %ld",
|
|
|
pConfigList->configlsit.size());
|
|
|
for (int i = 0; i < (int)pConfigList->configlsit.size(); i++)
|
|
|
{
|
|
|
pChannelqxList->pChannelDetlog->AddCheckstr(PrintLevel_1, 3, "Num And Dis Judge", "QX %s channel %s param %d / %d Analysis start ",
|
|
|
QX_ANALYSIS_NAME_Names[qx_idx].c_str(), pChannelqxList->channel_name.c_str(), i, (int)pConfigList->configlsit.size());
|
|
|
Analysis_single_Config(&pConfigList->configlsit.at(i), pChannelqxList, qx_idx, pChannelqxList->pChannelDetlog);
|
|
|
}
|
|
|
if (pChannelqxList->pChannelDetlog2 && pChannelqxList->pChannelDetlog)
|
|
|
{
|
|
|
for (auto log : pChannelqxList->pChannelDetlog->logList)
|
|
|
{
|
|
|
pChannelqxList->pChannelDetlog2->logList.push_back(log);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::Judge_OK_Config()
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::Judge_NG_Config()
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int QX_Merge_Analysis::Analysis_AD(ALL_Qx_DataList *pALLTypeqxList, int qx_idx)
|
|
|
{
|
|
|
AD_list.clear();
|
|
|
if (!m_pbaseCheckFunction)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
Base_Function_AD_Check *pAd_checkParma = &m_pbaseCheckFunction->ad_check;
|
|
|
|
|
|
int product_AD_num = 0; // 整个产品的 暗点数目。
|
|
|
int check_s_Num = 0;
|
|
|
int s_param_value = -1;
|
|
|
int s_param_num = 0;
|
|
|
// 遍历每个通道,找到开启的 进行分析。
|
|
|
for (int i = 0; i < pALLTypeqxList->channelqxList.size(); i++)
|
|
|
{
|
|
|
QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i];
|
|
|
|
|
|
if (!pAd_checkParma)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
if (pAd_checkParma && !pAd_checkParma->bOpen)
|
|
|
{
|
|
|
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_2, 3, "Analysis_AD ",
|
|
|
"channel %s AD Check is close", pQXChannelList->channel_name.c_str());
|
|
|
continue;
|
|
|
}
|
|
|
bool bana_num = false;
|
|
|
bool bana_dis = false;
|
|
|
bool bana_S = false;
|
|
|
if (pAd_checkParma->analysis_num.bOpen)
|
|
|
{
|
|
|
bana_num = true;
|
|
|
}
|
|
|
if (pAd_checkParma->analysis_dis.bOpen)
|
|
|
{
|
|
|
bana_dis = true;
|
|
|
}
|
|
|
if (pAd_checkParma->analysis_s.bOpen)
|
|
|
{
|
|
|
bana_S = true;
|
|
|
}
|
|
|
{
|
|
|
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_2, 3, "Analysis_AD ", "NUM --> %s Param num check %d dis check %d S check %d",
|
|
|
pQXChannelList->channel_name.c_str(), bana_num, bana_dis, bana_S);
|
|
|
}
|
|
|
if (!bana_num && !bana_dis && !bana_S)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
for (int j = 0; j < pQXChannelList->qxList.size(); j++)
|
|
|
{
|
|
|
if (pQXChannelList->qxList[j].area >= pAd_checkParma->S_standard_1s.area &&
|
|
|
pQXChannelList->qxList[j].length >= pAd_checkParma->S_standard_1s.len)
|
|
|
{
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
tem_AD_QX_Info tem_AD_qx; // 暗点信息
|
|
|
tem_AD_qx.channelidx = i;
|
|
|
tem_AD_qx.qxidx = j;
|
|
|
|
|
|
int s_det_value = 0;
|
|
|
// 当前通道 要参与s标准分析
|
|
|
if (pAd_checkParma->analysis_s.bOpen)
|
|
|
{
|
|
|
s_param_num = pAd_checkParma->analysis_s.Check_s_Num;
|
|
|
s_param_value = pAd_checkParma->analysis_s.Check_s_Value;
|
|
|
|
|
|
if (pQXChannelList->qxList[j].area >= pAd_checkParma->S_standard_3s.area &&
|
|
|
pQXChannelList->qxList[j].length >= pAd_checkParma->S_standard_3s.len)
|
|
|
{
|
|
|
s_det_value = 3;
|
|
|
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_3, 3, "add AD ",
|
|
|
"%d %s 3S: cur[A %0.2f L %0.2f] parm[A %0.2f L %0.2f]",
|
|
|
j, pQXChannelList->channel_name.c_str(),
|
|
|
pQXChannelList->qxList[j].area, pQXChannelList->qxList[j].length,
|
|
|
pAd_checkParma->S_standard_3s.area, pAd_checkParma->S_standard_3s.len);
|
|
|
}
|
|
|
else if (pQXChannelList->qxList[j].area >= pAd_checkParma->S_standard_2s.area &&
|
|
|
pQXChannelList->qxList[j].length >= pAd_checkParma->S_standard_2s.len)
|
|
|
{
|
|
|
s_det_value = 2;
|
|
|
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_3, 3, " add AD ",
|
|
|
"%d %s 2S: cur[A %0.2f L %0.2f] parm[A %0.2f L %0.2f]",
|
|
|
j, pQXChannelList->channel_name.c_str(),
|
|
|
pQXChannelList->qxList[j].area, pQXChannelList->qxList[j].length,
|
|
|
pAd_checkParma->S_standard_2s.area, pAd_checkParma->S_standard_1s.len);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_3, 3, "add AD ",
|
|
|
"%d %s 1S: cur[A %0.2f L %0.2f] parm[A %0.2f L %0.2f]",
|
|
|
j, pQXChannelList->channel_name.c_str(),
|
|
|
pQXChannelList->qxList[j].area, pQXChannelList->qxList[j].length,
|
|
|
pAd_checkParma->S_standard_2s.area, pAd_checkParma->S_standard_1s.len);
|
|
|
s_det_value = 1;
|
|
|
}
|
|
|
if (s_det_value >= s_param_value)
|
|
|
{
|
|
|
check_s_Num++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
cv::Rect roi = pQXChannelList->qxList[j].product_roi;
|
|
|
|
|
|
int list_idx = -1;
|
|
|
int channel_s = 0;
|
|
|
bool bnew_add = true;
|
|
|
for (int idx = 0; idx < AD_list.size(); idx++)
|
|
|
{
|
|
|
float fiou = CheckUtil::CalIoU(AD_list.at(idx).roi, roi);
|
|
|
if (fiou > 0.15)
|
|
|
{
|
|
|
list_idx = idx;
|
|
|
}
|
|
|
}
|
|
|
// 在list已存在。
|
|
|
if (list_idx >= 0)
|
|
|
{
|
|
|
AD_list.at(list_idx).num++;
|
|
|
AD_list.at(list_idx).numIdxList.push_back(tem_AD_qx);
|
|
|
|
|
|
channel_s = AD_list.at(list_idx).num;
|
|
|
if (s_det_value == 1)
|
|
|
{
|
|
|
AD_list.at(list_idx).num_1s++;
|
|
|
}
|
|
|
else if (s_det_value == 2)
|
|
|
{
|
|
|
AD_list.at(list_idx).num_2s++;
|
|
|
AD_list.at(list_idx).num_2sIdxList.push_back(tem_AD_qx);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
AD_list.at(list_idx).num_3s++;
|
|
|
AD_list.at(list_idx).num_3sIdxList.push_back(tem_AD_qx);
|
|
|
}
|
|
|
bnew_add = false;
|
|
|
}
|
|
|
else
|
|
|
{ // 在list不存在。
|
|
|
AD_Channel_Info_ tem;
|
|
|
tem.roi = roi;
|
|
|
tem.location_product_mm = pQXChannelList->qxList[j].pLocation_Product_mm;
|
|
|
tem.num = 1;
|
|
|
channel_s = 1;
|
|
|
tem.fdis = 99999999999;
|
|
|
|
|
|
tem.numIdxList.push_back(tem_AD_qx);
|
|
|
|
|
|
if (s_det_value == 1)
|
|
|
{
|
|
|
tem.num_1s++;
|
|
|
}
|
|
|
else if (s_det_value == 2)
|
|
|
{
|
|
|
tem.num_2s++;
|
|
|
tem.num_2sIdxList.push_back(tem_AD_qx);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
tem.num_3s++;
|
|
|
tem.num_3sIdxList.push_back(tem_AD_qx);
|
|
|
}
|
|
|
AD_list.push_back(tem);
|
|
|
// 如果要参与数量统计
|
|
|
if (bana_num)
|
|
|
{
|
|
|
product_AD_num++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "AD list size %ld; channel %s blob idx %d,new_add %d ,A %f len %f p %d %d",
|
|
|
AD_list.size(), pQXChannelList->channel_name.c_str(), j, bnew_add, pQXChannelList->qxList[j].area,
|
|
|
pQXChannelList->qxList[j].length, roi.x, roi.y);
|
|
|
|
|
|
pQXChannelList->pChannelDetlog->AddCheckstr(PrintLevel_2, 3, "Analysis_AD ",
|
|
|
"%d %s AD list size %ld product_AD_num Num %d; cur channel num = %d;cur S = %ds; param :%ds num %d;->S check_s_Num = %d",
|
|
|
j, pQXChannelList->channel_name.c_str(), AD_list.size(),
|
|
|
product_AD_num, channel_s, s_det_value, s_param_value, s_param_num, check_s_Num);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
float min_dis = 9999999999;
|
|
|
// 求最小距离
|
|
|
if (true)
|
|
|
{
|
|
|
for (int ad_i = 0; ad_i < AD_list.size(); ad_i++)
|
|
|
{
|
|
|
for (int ad_j = 0; ad_j < AD_list.size(); ad_j++)
|
|
|
{
|
|
|
if (ad_i == ad_j)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
// double dis = DistanceBetweenRectCenters(AD_list.at(ad_i).roi, AD_list.at(ad_j).roi,
|
|
|
// 1,
|
|
|
// 1);
|
|
|
|
|
|
float dis = CheckUtil::calDis(AD_list.at(ad_i).location_product_mm, AD_list.at(ad_j).location_product_mm);
|
|
|
if (dis < AD_list.at(ad_i).fdis)
|
|
|
{
|
|
|
AD_list.at(ad_i).fdis = dis;
|
|
|
AD_list.at(ad_i).dist_idx = ad_j;
|
|
|
if (dis < min_dis)
|
|
|
{
|
|
|
min_dis = dis;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
int A_2S_num = 0;
|
|
|
int A_3S_num = 0;
|
|
|
// 统计 2s 总数
|
|
|
if (s_param_value > 0)
|
|
|
{
|
|
|
int channels = 0;
|
|
|
int oneimgs = check_s_Num;
|
|
|
|
|
|
for (int ad_i = 0; ad_i < AD_list.size(); ad_i++)
|
|
|
{
|
|
|
if (AD_list.at(ad_i).num > 1)
|
|
|
{
|
|
|
AD_list.at(ad_i).num_2s++;
|
|
|
for (int i = 0; i < AD_list.at(ad_i).numIdxList.size(); i++)
|
|
|
{
|
|
|
AD_list.at(ad_i).num_2sIdxList.push_back(AD_list.at(ad_i).numIdxList.at(i));
|
|
|
}
|
|
|
}
|
|
|
A_2S_num += AD_list.at(ad_i).num_2s;
|
|
|
A_3S_num += AD_list.at(ad_i).num_3s;
|
|
|
if(AD_list.at(ad_i).num_1s >= 3) A_3S_num++;
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "AD_list %d %s",
|
|
|
ad_i, AD_list.at(ad_i).GetInfo().c_str());
|
|
|
}
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "product_AD_num %d 2S_num = %d 3S_num s = %d min_dis %0.2f",
|
|
|
product_AD_num, A_2S_num, A_3S_num, min_dis);
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < pALLTypeqxList->channelqxList.size(); i++)
|
|
|
{
|
|
|
QX_channel_List *pQXChannelList = &pALLTypeqxList->channelqxList[i];
|
|
|
|
|
|
if (!pAd_checkParma->bOpen)
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
}
|
|
|
bool bNG = false;
|
|
|
|
|
|
bool NG_num = false;
|
|
|
bool NG_3S = false;
|
|
|
bool NG_2S = false;
|
|
|
bool NG_dis = false;
|
|
|
|
|
|
if (pAd_checkParma->analysis_num.bOpen)
|
|
|
{
|
|
|
// 数量分析
|
|
|
if (product_AD_num >= pAd_checkParma->analysis_num.numT)
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "Num Analysis --> %s result NG ,product_AD_num %d >= parm num %d",
|
|
|
pQXChannelList->channel_name.c_str(), product_AD_num, pAd_checkParma->analysis_num.numT);
|
|
|
bNG = true;
|
|
|
NG_num = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "Num Analysis--> %s result OK ,product_AD_num %d < parm num %d",
|
|
|
pQXChannelList->channel_name.c_str(), product_AD_num, pAd_checkParma->analysis_num.numT);
|
|
|
}
|
|
|
}
|
|
|
// 不NG
|
|
|
if (!bNG)
|
|
|
{
|
|
|
// 3S直接 NG
|
|
|
if (pAd_checkParma->analysis_s.NG_3s)
|
|
|
{
|
|
|
// 数量分析
|
|
|
if (A_3S_num >= 1)
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "3S Analysis --> %s result NG 3S %d >= 1",
|
|
|
pQXChannelList->channel_name.c_str(), A_3S_num);
|
|
|
|
|
|
bNG = true;
|
|
|
NG_3S = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "3S Analysis --> %s result OK 3S %d < 1",
|
|
|
pQXChannelList->channel_name.c_str(), A_3S_num);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// 不NG
|
|
|
if (!bNG)
|
|
|
{
|
|
|
// 距离判断
|
|
|
if (pAd_checkParma->analysis_dis.bOpen)
|
|
|
{
|
|
|
// 数量分析
|
|
|
if (min_dis <= pAd_checkParma->analysis_dis.disT)
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "Dis Analysis--> %s Dis result NG ,min dis %f <= parm dis %f",
|
|
|
pQXChannelList->channel_name.c_str(), min_dis, pAd_checkParma->analysis_dis.disT);
|
|
|
|
|
|
bNG = true;
|
|
|
NG_2S = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "Dis Analysis--> %s Dis result OK ,min dis %f > parm dis %f",
|
|
|
pQXChannelList->channel_name.c_str(), min_dis, pAd_checkParma->analysis_dis.disT);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// 不NG
|
|
|
if (!bNG)
|
|
|
{
|
|
|
// S标准判断
|
|
|
if (pAd_checkParma->analysis_s.bOpen)
|
|
|
{
|
|
|
// 数量分析
|
|
|
if (A_2S_num >= pAd_checkParma->analysis_s.Check_s_Num)
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "S Analysis--> %s result NG , Check %ds Num %d >= parm S Num %d",
|
|
|
pQXChannelList->channel_name.c_str(), pAd_checkParma->analysis_s.Check_s_Value, A_2S_num, pAd_checkParma->analysis_s.Check_s_Num);
|
|
|
|
|
|
bNG = true;
|
|
|
NG_2S = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_2, 3, "AD RGBL255", "S Analysis--> %s result OK , Check %ds Num %d < parm S Num %d",
|
|
|
pQXChannelList->channel_name.c_str(), pAd_checkParma->analysis_s.Check_s_Value, A_2S_num, pAd_checkParma->analysis_s.Check_s_Num);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// 已经NG
|
|
|
if (bNG)
|
|
|
{
|
|
|
|
|
|
QX_channel_List *pqxList = pQXChannelList;
|
|
|
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
|
|
|
{
|
|
|
|
|
|
if (pqxList->qxList.at(i).result == 0)
|
|
|
{
|
|
|
pqxList->qxList.at(i).result = 1;
|
|
|
|
|
|
QX_RESULT tem;
|
|
|
tem.blobIdx = pqxList->qxList.at(i).blobIdx;
|
|
|
tem.mindis = pqxList->qxList.at(i).fmindis;
|
|
|
tem.flen = pqxList->qxList.at(i).length;
|
|
|
tem.error_Type = pqxList->qxList.at(i).nqx_type;
|
|
|
tem.camera_name = pqxList->qxList.at(i).camera_name;
|
|
|
tem.channel_name = pqxList->qxList.at(i).channel_name;
|
|
|
pqxList->pChannelDetlog->AddCheckstr(PrintLevel_4, 3, "result = NG", "Add New qx,Blob idx %d type %d num %d dis %f len %f ", tem.blobIdx, tem.error_Type, tem.qx_Num, tem.mindis, tem.flen);
|
|
|
m_pMergedetlog->AddCheckstr(PrintLevel_4, 3, "result = NG", "%s Add New qx,Blob idx %d type %d num %d dis %f len %f ",
|
|
|
tem.channel_name.c_str(), tem.blobIdx, tem.error_Type, tem.qx_Num, tem.mindis, tem.flen);
|
|
|
|
|
|
m_reultList.resultList.push_back(tem);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
ChannelCheckFunction *QX_Merge_Analysis::GetChannelFuntion(std::string strChannelName)
|
|
|
{
|
|
|
ChannelCheckFunction *p = NULL;
|
|
|
for (int i = 0; i < m_pChannelFuntion->channelFunctionArr.size(); i++)
|
|
|
{
|
|
|
if (CheckUtil::compareIgnoreCase(m_pChannelFuntion->channelFunctionArr[i].strChannelName, strChannelName))
|
|
|
{
|
|
|
p = &m_pChannelFuntion->channelFunctionArr[i];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return p;
|
|
|
}
|
|
|
double QX_Merge_Analysis::DistanceBetweenRectCenters(const cv::Rect &rect1, const cv::Rect &rect2, float fx, float fy)
|
|
|
{
|
|
|
// 计算矩形1的中心点
|
|
|
cv::Point center1(rect1.x + rect1.width / 2, rect1.y + rect1.height / 2);
|
|
|
|
|
|
// 计算矩形2的中心点
|
|
|
cv::Point center2(rect2.x + rect2.width / 2, rect2.y + rect2.height / 2);
|
|
|
center1.x *= fx;
|
|
|
center1.y *= fy;
|
|
|
|
|
|
center2.x *= fx;
|
|
|
center2.y *= fy;
|
|
|
|
|
|
// 计算中心点之间的欧几里得距离
|
|
|
double distance = cv::norm(center1 - center2);
|
|
|
|
|
|
return distance;
|
|
|
} |