You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1591 lines
41 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* @Descripttion:
* @version:
* @Author: sueRimn
* @Date: 2022-03-16 17:09:11
* @LastEditors: xiewenji 527774126@qq.com
* @LastEditTime: 2025-09-16 22:05:01
*/
/***********************************************/
/************ ***************/
/************金佰利检测算法参数定义**************/
/************ **************/
/**********************************************/
#ifndef _CheckConfigDefine_HPP_
#define _CheckConfigDefine_HPP_
#include <string>
#include "ConfigBase.h"
#include <opencv2/opencv.hpp>
#define MASK_IMG_STEP 16
#define MASK_IMG_STARTVALUE 48
// 一个检测缺陷 最多有几组参数
#define MASK_QX_PARAM_NUM 3
enum REGIONTYPE_
{
REGION_TYPE_CHECK, // 检测区域
REGION_TYPE_SHIELD, // 屏蔽区域
};
enum CONFIG_QX_WHITE_BLCAK
{
CONFIG_QX_BLACK, // 分类 AD异显(P6873)
CONFIG_QX_WHITE, // 分类 AD异显(P6873)
};
static const std::string WHITE_BLCAK_Names[] =
{
"black",
"white"};
// 检测缺陷的种类
enum CONFIG_QX_NAME_
{
CONFIG_QX_NAME_cell_aotudian, // 分类 凹凸点
CONFIG_QX_NAME_cell_other, // 分类 其他
CONFIG_QX_NAME_cell_line, // 分类 线状
CONFIG_QX_NAME_cell_zangwu, // 分类 脏污
CONFIG_QX_NAME_cell_edge, // 分类 边缘
CONFIG_QX_NAME_cell_ymhs, // 分类 异物
CONFIG_QX_NAME_cell_dianzhuang, // 分类 点状
CONFIG_QX_NAME_cell_posun, // 分类 破损
CONFIG_QX_NAME_cell_xianwei, // 分类 纤维
CONFIG_QX_NAME_cell_shuizi, // 分类 水渍
CONFIG_QX_NAME_cell_danban, // 分类 淡斑
CONFIG_QX_NAME_cell_fuchen, // 分类 浮尘
CONFIG_QX_NAME_cell_tag, // 分类 标签
CONFIG_QX_NAME_support_offset, // 支架偏移
CONFIG_QX_NAME_support_loss, // 支架缺失
CONFIG_QX_NAME_count,
};
// 缺陷项对应在参数中的名称
static std::vector<std::string> CONFIG_QX_NAME_Names =
{
"aotudian",
"other",
"line",
"zangwu",
"edge",
"ymhs",
"dianzhuang",
"posun",
"xianwei",
"shuizi",
"danban",
"fuchen",
"tag",
"support_offset",
"support_loss",
};
// 分析类型
enum ANALYSIS_TYPE_
{
ANALYSIS_TYPE_TF, // 踢废 打标分析
ANALYSIS_TYPE_YS, // 疑是 分析
ANALYSIS_TYPE_COUNT,
};
static const std::string ANALYSIS_TYPE_Names[] =
{
"Check_Param",
"SaveImg_Param"};
// 分析类型
enum QX_RESULT_TYPE_
{
QX_RESULT_TYPE_OK, // 踢废 打标分析
QX_RESULT_TYPE_NG, // 疑是 分析
QX_RESULT_TYPE_YS,
QX_RESULT_TYPE_NoJduge, // 未判断
QX_RESULT_TYPE_COUNT
};
static const std::string QX_RESULT_TYPE_Names[] =
{
"OK",
"NG",
"YS",
"NoJudge"};
struct CAM_CONFIGINFO_
{
float fscale_x;
float fscale_y; // 相机分辨率
CAM_CONFIGINFO_()
{
fscale_x = 0.15f;
fscale_y = 0.15f;
}
void copy(CAM_CONFIGINFO_ tem)
{
this->fscale_x = tem.fscale_x;
this->fscale_y = tem.fscale_y;
}
};
struct RegionBasicInfo
{
std::string name; // 区域名称
int type; // 区域类型
int lay; // 层级
std::vector<cv::Point> pointArry; // 区域点
std::vector<std::string> ChannelArry; // 通道区域
bool bdraw; // 是否绘制
RegionBasicInfo()
{
Init();
}
void Init()
{
name = "";
type = 0;
lay = 0;
bdraw = false;
pointArry.clear();
pointArry.shrink_to_fit();
ChannelArry.clear();
ChannelArry.shrink_to_fit();
}
void copy(RegionBasicInfo tem)
{
this->name = tem.name;
this->type = tem.type;
this->lay = tem.lay;
this->bdraw = tem.bdraw;
this->pointArry.assign(tem.pointArry.begin(), tem.pointArry.end());
this->ChannelArry.assign(tem.ChannelArry.begin(), tem.ChannelArry.end());
}
};
struct AandEParam
{
bool bEnable; // 是否启用
bool bOk; // 好品条件
float area; // 面积
float area_max; // 面积上限
float energy; // 能量
float hj; // 灰阶
float length; // 长度
float breadth; // 宽度
int num; // 数量
float dis; // 距离
float density; // 密度
AandEParam()
{
bOk = false;
bEnable = false;
area = -1;
area_max = -1;
energy = -1;
hj = -1;
length = -1;
breadth = -1;
num = -1;
dis = -1;
density = -1;
}
void print(std::string str)
{
printf("%s bEnable %d bOk %d area %f area_max %f energy %f hj %f length %f breadth %f num %d dis %f density %f \n", str.c_str(), bEnable, bOk, area, area_max, energy, hj, length, breadth, num, dis, density);
}
void copy(AandEParam tem)
{
this->bEnable = tem.bEnable;
this->bOk = tem.bOk;
this->area = tem.area;
this->area_max = tem.area_max;
this->energy = tem.energy;
this->hj = tem.hj;
this->length = tem.length;
this->breadth = tem.breadth;
this->num = tem.num;
this->dis = tem.dis;
this->density = tem.density;
}
};
// 区域的检测参数
struct CheckConfig_Regions_Param
{
std::vector<AandEParam> paramArr;
std::string param_name;
int useNum; // 使用个数
CheckConfig_Regions_Param()
{
paramArr.clear();
paramArr.shrink_to_fit();
useNum = 0;
param_name = "";
}
void addParam(AandEParam param)
{
paramArr.push_back(param);
useNum++;
}
};
// 不同缺陷类型参数
struct CheckConfig_Regions_type
{
std::vector<CheckConfig_Regions_Param> checkConfig_Regions_Param;
};
// 区域相关参数
struct RegionConfigST
{
bool buse; // 是否使用
RegionBasicInfo basicInfo; // 基础信息
CheckConfig_Regions_type checkConfig_Regions_type[ANALYSIS_TYPE_COUNT];
RegionConfigST()
{
buse = false;
} /* data */
};
bool compareBylay(const RegionConfigST &a, const RegionConfigST &b);
// 检测参数层级关系
// 1、区域
// 2、 检测项目
// 3、 参数 阈值
// 阈值参数系数
struct THRESHOLD_RATIO
{
float farea;
float fenergy;
bool bEnable;
THRESHOLD_RATIO()
{
farea = 1;
fenergy = 1;
bEnable = false;
;
}
void copy(THRESHOLD_RATIO tem)
{
this->farea = tem.farea;
this->fenergy = tem.fenergy;
this->bEnable = tem.bEnable;
}
void printfInfo(std::string str)
{
printf("%s bEnable %d farea %f fenergy %f \n", str.c_str(), bEnable, farea, fenergy);
}
};
// 区域无关的基本参数
struct BasicConfig
{
std::string strCamearName;
int image_widht;
int Image_height;
int width_min; // 20231122xls-add
int width_max;
int height_min;
int height_max; // 20231122xls-add
bool bDrawShieldRoi; // 绘制屏蔽区域
bool bShield_ZF; // 屏蔽字符区域,不检测
bool bDrawPreRoi; // 绘制弱化区域
float fUP_IOU;
bool bCal_ImageScale; // 是否自动计算成像精度
float Product_Size_Width_mm; // 产品尺寸 宽度 mm
float Product_Size_Height_mm; // 产品尺寸 高度 mm
float fImage_Scale_x; // 成像精度
float fImage_Scale_y; // 成像精度
std::string strCamName; //
float density_R_mm; // 密度计算半径 像素
BasicConfig()
{
Image_height = 0;
image_widht = 0;
width_min = 0; // 20231122xls-add
width_max = 999999;
height_min = 0;
height_max = 999999;
bDrawShieldRoi = false;
bShield_ZF = false;
bDrawPreRoi = false;
fUP_IOU = 0.9;
bCal_ImageScale = false;
Product_Size_Width_mm = 100;
Product_Size_Height_mm = 1000;
fImage_Scale_x = 0.03;
fImage_Scale_y = 0.03;
density_R_mm = 5;
strCamName = "";
strCamearName = EMPTY_CONFIG_NAME;
}
void copy(BasicConfig tem)
{
this->image_widht = tem.image_widht;
this->Image_height = tem.Image_height;
this->width_min = tem.width_min; // 20231122xls-add
this->width_max = tem.width_max;
this->height_min = tem.height_min;
this->height_max = tem.height_max;
this->bDrawShieldRoi = tem.bDrawShieldRoi;
this->bShield_ZF = tem.bShield_ZF;
this->fUP_IOU = tem.fUP_IOU;
this->bDrawPreRoi = tem.bDrawPreRoi;
this->strCamName = tem.strCamName;
this->bCal_ImageScale = tem.bCal_ImageScale;
this->Product_Size_Width_mm = tem.Product_Size_Width_mm;
this->Product_Size_Height_mm = tem.Product_Size_Height_mm;
this->fImage_Scale_x = tem.fImage_Scale_x;
this->fImage_Scale_y = tem.fImage_Scale_y;
this->density_R_mm = tem.density_R_mm;
this->strCamearName = tem.strCamearName;
}
void print(std::string str = "")
{
printf("============================↓↓↓↓↓↓%s↓↓ %s ↓↓↓↓↓=========================\n", str.c_str(), strCamearName.c_str());
printf("bCal_ImageScale %d Product_Size_Width =%f Product_Size_Height =%f \n", bCal_ImageScale, Product_Size_Width_mm, Product_Size_Height_mm);
printf("fImage_Scale_x =%f fImage_Scale_y=%f \n", fImage_Scale_x, fImage_Scale_y);
// printf("height_min =%d height_max=%d \n", height_min, height_max);
printf("bDrawShieldRoi %d bShield_ZF %d DrawPreRoi %d fUP_IOU %f density_R_mm %f\n", bDrawShieldRoi, bShield_ZF, bDrawPreRoi, fUP_IOU, density_R_mm);
printf("============================↑↑↑↑↑↑%s↑↑↑↑↑↑=========================\n", str.c_str());
}
};
struct NodeBasicConfig
{
float calss_conf; // 分类阈值参数,低于这个阈值的不处理,
float calss_area; // 分类阈值参数,低于这个阈值的不处理,
int img_width;
int img_height;
NodeBasicConfig()
{
calss_conf = 0.5;
calss_area = 1.0;
}
void copy(NodeBasicConfig tem)
{
this->calss_conf = tem.calss_conf;
this->calss_area = tem.calss_area;
}
void print(std::string str = "")
{
printf("============================↓↓↓↓↓↓%s↓↓↓↓↓↓↓=========================\n", str.c_str());
printf("img_width %d img_height %d alss_conf %f calss_area %f \n", img_width, img_height, calss_conf, calss_area);
printf("============================↑↑↑↑↑↑%s↑↑↑↑↑↑=========================\n", str.c_str());
}
};
// 多节点
struct CommonConfigNodeST
{
NodeBasicConfig nodebasicConfog;
std::vector<RegionConfigST> regionConfigArr;
cv::Mat mask;
// cv::Mat SheildMask[IMG_CHANNEL_Count];
void copy(CommonConfigNodeST tem)
{
this->regionConfigArr.assign(tem.regionConfigArr.begin(), tem.regionConfigArr.end());
this->nodebasicConfog.copy(tem.nodebasicConfog);
if (!tem.mask.empty())
{
this->mask = tem.mask.clone();
}
// for (int i = 0; i < IMG_CHANNEL_Count; i++)
// {
// if (!tem.SheildMask[i].empty())
// {
// this->SheildMask[i] = tem.SheildMask[i].clone();
// }
// }
}
void InitSheildMask() {
// for (int i = 0; i < IMG_CHANNEL_Count; i++)
// {
// if (!SheildMask[i].empty())
// {
// SheildMask[i].release();
// }
// }
};
void ToSheildMaskImg()
{
// printf("ToSheildMaskImg img_height %d, img_width %d\n", nodebasicConfog.img_height, nodebasicConfog.img_width);
// if (nodebasicConfog.img_width <= 0 || nodebasicConfog.img_height <= 0)
// {
// return; /* code */
// }
// InitSheildMask();
// printf("regionConfigArr.size() %d \n", regionConfigArr.size());
// std::sort(regionConfigArr.begin(), regionConfigArr.end(), compareBylay);
// for (int i = 0; i < regionConfigArr.size(); i++)
// {
// printf("mask %d / %d type =%d \n", i, regionConfigArr.size(), regionConfigArr.at(i).basicInfo.type);
// if (regionConfigArr.at(i).basicInfo.type == 1)
// {
// for (int ic = 0; ic < regionConfigArr.at(i).basicInfo.ChannelArry.size(); ic++)
// {
// std::string strChannel = regionConfigArr.at(i).basicInfo.ChannelArry.at(ic);
// int idx = -1;
// for (int pc = 0; pc < IMG_CHANNEL_Count; pc++)
// {
// if (IMG_CHANNEL_NAME[pc] == strChannel)
// {
// idx = pc;
// }
// }
// printf("%d -- %s idx %d\n", ic, strChannel.c_str(), idx);
// if (idx >= 0)
// {
// if (SheildMask[idx].empty())
// {
// SheildMask[idx] = cv::Mat(nodebasicConfog.img_height, nodebasicConfog.img_width, CV_8U, cv::Scalar(0));
// }
// cv::fillPoly(SheildMask[idx], regionConfigArr.at(i).basicInfo.pointArry, cv::Scalar(255));
// // cv::imwrite(std::to_string(idx)+"_"+strChannel+".png",SheildMask[idx]);
// }
// }
// }
// }
}
void ToMaskImg()
{
printf("nodebasicConfog.img_height %d, nodebasicConfog.img_width %d\n", nodebasicConfog.img_height, nodebasicConfog.img_width);
if (nodebasicConfog.img_width <= 0 || nodebasicConfog.img_height <= 0)
{
return; /* code */
}
mask = cv::Mat(nodebasicConfog.img_height, nodebasicConfog.img_width, CV_8U, cv::Scalar(0));
std::sort(regionConfigArr.begin(), regionConfigArr.end(), compareBylay);
for (int i = 0; i < regionConfigArr.size(); i++)
{
// 只绘制检测区域
if (regionConfigArr.at(i).basicInfo.type != 0)
{
continue;
}
// printf("*-*-*-*- %d \n", regionConfigArr.at(i).basicInfo.lay);
int nv = MASK_IMG_STEP * i + MASK_IMG_STARTVALUE;
if (nv < 0 || nv > 255)
{
nv = 255;
}
cv::fillPoly(mask, regionConfigArr.at(i).basicInfo.pointArry, cv::Scalar(nv));
// {
// std::vector<cv::Point> src_pointArry; // 区域点
// float src_scale_x = SRCIMG_WIDTH * 1.0f / CHECKIMG_WIDTH;
// float src_scale_y = SRCIMG_HEIGHT * 1.0f / CHECKIMG_HEIGHT;
// for (int j = 0; j < regionConfigArr.at(i).basicInfo.pointArry.size(); j++)
// {
// cv::Point temp;
// temp.x = src_scale_x * regionConfigArr.at(i).basicInfo.pointArry.at(j).x;
// temp.y = src_scale_y * regionConfigArr.at(i).basicInfo.pointArry.at(j).y;
// src_pointArry.push_back(temp);
// // printf("--- %d %d **--- %d %d\n",temp.x,temp.y, regionConfigArr.at(i).basicInfo.pointArry.at(j).x, regionConfigArr.at(i).basicInfo.pointArry.at(j).y);
// }
// cv::fillConvexPoly(Src_mask, src_pointArry, cv::Scalar(nv));
// }
}
}
};
// 和图片相关的参数
struct CommonCheckConfigST
{
BasicConfig baseConfig;
// 节点参数数据集
std::vector<CommonConfigNodeST> nodeConfigArr;
CommonCheckConfigST()
{
nodeConfigArr.clear();
nodeConfigArr.shrink_to_fit();
}
void copy(CommonCheckConfigST tem)
{
this->nodeConfigArr.assign(tem.nodeConfigArr.begin(), tem.nodeConfigArr.end());
this->baseConfig.copy(tem.baseConfig);
}
};
// 基础检测
struct Function_Base_Det
{
bool bOpen; // 是否开启
std::string strAIMode; // 模型名称
std::vector<std::string> DetQXList; // 检测缺陷list
Function_Base_Det()
{
Init();
}
void Init()
{
bOpen = false;
strAIMode = "";
DetQXList.clear();
DetQXList.shrink_to_fit();
}
void copy(Function_Base_Det tem)
{
this->bOpen = tem.bOpen;
this->strAIMode = tem.strAIMode;
this->DetQXList.assign(tem.DetQXList.begin(), tem.DetQXList.end());
}
void print(std::string str)
{
printf("%s>>bOpen %d strAIMode %s ", str.c_str(), bOpen, strAIMode.c_str());
for (int i = 0; i < DetQXList.size(); i++)
{
printf("%s ", DetQXList.at(i).c_str());
}
printf(" \n");
}
std::string GetInfo(std::string str)
{
char buffer[128];
sprintf(buffer, "%s>>bOpen:%d AIMode:%s ", str.c_str(), bOpen, strAIMode.c_str());
std::string str123 = buffer;
for (int i = 0; i < DetQXList.size(); i++)
{
str123 += DetQXList.at(i) + ";";
}
str123 += "\n";
return str123;
}
};
// 只生成Blob不进行分析
struct Function_OnlyBLob
{
bool bOpen; // 是否开启
Function_OnlyBLob()
{
Init();
}
void Init()
{
bOpen = false;
}
void copy(Function_OnlyBLob tem)
{
this->bOpen = tem.bOpen;
}
void print(std::string str)
{
printf("%s>>bOpen %d\n", str.c_str(), bOpen);
}
std::string GetInfo(std::string str)
{
char buffer[64];
sprintf(buffer, "%s>>bOpen %d\n", str.c_str(), bOpen);
std::string str123 = buffer;
return str123;
}
};
// 大缺陷检测参数
struct Function_BigQX
{
bool bOpen; // 是否开启
float Single_Area; // 单个缺陷的面积
int Single_HJ; // 单个缺陷的灰机
float Single_Len; // 单个缺陷的长度
int Sum_blob_Num; // 总面积统计 blob数量
float Sum_Area; // 总面积统计 面积参数
Function_BigQX()
{
Init();
}
void Init()
{
bOpen = false;
Single_Area = 80;
Single_HJ = 60;
Single_Len = 5;
Sum_blob_Num = 5;
Sum_Area = 100;
}
void copy(Function_BigQX tem)
{
this->bOpen = tem.bOpen;
this->Single_Area = tem.Single_Area;
this->Single_HJ = tem.Single_HJ;
this->Single_Len = tem.Single_Len;
this->Sum_blob_Num = tem.Sum_blob_Num;
this->Sum_Area = tem.Sum_Area;
}
void print(std::string str)
{
printf("%s>>bOpen %d single area %f hj %d len %f sum blob num %d area %f\n", str.c_str(),
bOpen, Single_Area, Single_HJ, Single_Len, Sum_blob_Num, Sum_Area);
}
std::string GetInfo(std::string str)
{
char buffer[128];
sprintf(buffer, "%s>>bOpen %d single area %f hj %d len %f sum blob num %d area %f\n", str.c_str(),
bOpen, Single_Area, Single_HJ, Single_Len, Sum_blob_Num, Sum_Area);
std::string str123 = buffer;
return str123;
}
};
// 屏蔽区域参数
struct Function_ShieldRegion
{
bool bOpen; // 是否开启
bool bDraw; // 是否绘制
cv::Mat shieldMask; // 屏蔽区域图片
std::vector<cv::Point> pointArry1; // 区域点
std::vector<cv::Point> pointArry2; // 区域点
std::vector<cv::Point> pointArry3; // 区域点
std::vector<cv::Point> pointArry4; // 区域点
std::vector<cv::Point> pointArry5; // 区域点
Function_ShieldRegion()
{
Init();
}
void Init()
{
bOpen = false;
bDraw = true;
pointArry1.clear();
pointArry1.shrink_to_fit();
pointArry2.clear();
pointArry2.shrink_to_fit();
pointArry3.clear();
pointArry3.shrink_to_fit();
pointArry4.clear();
pointArry4.shrink_to_fit();
pointArry5.clear();
pointArry5.shrink_to_fit();
if (!shieldMask.empty())
{
shieldMask.release();
}
}
void copy(Function_ShieldRegion tem)
{
this->bOpen = tem.bOpen;
this->bDraw = tem.bDraw;
this->shieldMask = tem.shieldMask.clone();
this->pointArry1.assign(tem.pointArry1.begin(), tem.pointArry1.end());
this->pointArry2.assign(tem.pointArry2.begin(), tem.pointArry2.end());
this->pointArry3.assign(tem.pointArry3.begin(), tem.pointArry3.end());
this->pointArry4.assign(tem.pointArry4.begin(), tem.pointArry4.end());
this->pointArry5.assign(tem.pointArry5.begin(), tem.pointArry5.end());
}
void ToMaskImg(int img_W, int img_H)
{
if (img_W > 0 && img_H > 0)
{
if (!shieldMask.empty())
{
shieldMask.release();
}
if (!bOpen)
{
return;
}
shieldMask = cv::Mat(img_H, img_W, CV_8U, cv::Scalar(0));
if (pointArry1.size() > 0)
{
cv::fillPoly(shieldMask, pointArry1, cv::Scalar(255));
}
if (pointArry2.size() > 0)
{
cv::fillPoly(shieldMask, pointArry2, cv::Scalar(255));
}
if (pointArry3.size() > 0)
{
cv::fillPoly(shieldMask, pointArry3, cv::Scalar(255));
}
if (pointArry4.size() > 0)
{
cv::fillPoly(shieldMask, pointArry4, cv::Scalar(255));
}
if (pointArry5.size() > 0)
{
cv::fillPoly(shieldMask, pointArry5, cv::Scalar(255));
}
}
}
void print(std::string str)
{
printf("%s>>bOpen %d bDraw %d maskimg empty %d\n", str.c_str(),
bOpen, bDraw, shieldMask.empty());
}
std::string GetInfo(std::string str)
{
char buffer[128];
sprintf(buffer, "%s>>bOpen %d bDraw %d maskimg empty %d\n", str.c_str(),
bOpen, bDraw, shieldMask.empty());
std::string str123 = buffer;
return str123;
}
};
// 检测roi区域参数
struct Function_EdgeROI
{
bool bOpen; // 是否开启
bool Use_DrawROI; // 使用绘制ROI
bool Use_DetEdge; // 使用边缘检测
bool Use_AIEdge; // 使用AI检测
bool AI_Fail_UseDraw; // 如果AI 失败使用绘制;
int threshold_value; // 二值化值
int AI_Erode_Size; // AI 检测 腐蚀的半径。
cv::Mat EdgeMask; // 边缘区域图片
std::vector<cv::Point> pointArry1; // 区域点
Function_EdgeROI()
{
Init();
}
void Init()
{
bOpen = false;
Use_DrawROI = false;
Use_DetEdge = true;
Use_AIEdge = false;
AI_Fail_UseDraw = false;
threshold_value = 11;
AI_Erode_Size = 7;
pointArry1.clear();
pointArry1.shrink_to_fit();
if (!EdgeMask.empty())
{
EdgeMask.release();
}
}
void copy(Function_EdgeROI tem)
{
this->bOpen = tem.bOpen;
this->Use_DrawROI = tem.Use_DrawROI;
this->Use_DetEdge = tem.Use_DetEdge;
this->Use_AIEdge = tem.Use_AIEdge;
this->AI_Fail_UseDraw = tem.AI_Fail_UseDraw;
this->threshold_value = tem.threshold_value;
this->AI_Erode_Size = tem.AI_Erode_Size;
this->EdgeMask = tem.EdgeMask.clone();
this->pointArry1.assign(tem.pointArry1.begin(), tem.pointArry1.end());
}
void ToMaskImg(int img_W, int img_H)
{
if (img_W > 0 && img_H > 0)
{
if (!EdgeMask.empty())
{
EdgeMask.release();
}
if (!bOpen)
{
return;
}
// if (!Use_DrawROI)
// {
// return;
// }
EdgeMask = cv::Mat(img_H, img_W, CV_8U, cv::Scalar(0));
if (pointArry1.size() > 0)
{
cv::fillPoly(EdgeMask, pointArry1, cv::Scalar(255));
}
else
{
printf("pointArry1 == 0 \n\n\n");
}
}
}
void print(std::string str)
{
printf("%s>>bOpen %d Use_DrawROI %d Use_DetEdge %d Use_AIEdge %d AI_Fail_UseDraw %d threshold_value %d AI_Erode_Size %d EdgeMask empty %d\n", str.c_str(),
bOpen, Use_DrawROI, Use_DetEdge, Use_AIEdge, AI_Fail_UseDraw, threshold_value, AI_Erode_Size, EdgeMask.empty());
}
std::string GetInfo(std::string str)
{
char buffer[256];
sprintf(buffer, "%s>>bOpen %d Use_DrawROI %d Use_DetEdge %d Use_AIEdge %d AI_Fail_UseDraw %d threshold_value %d AI_Erode_Size %d EdgeMask empty %d\n", str.c_str(),
bOpen, Use_DrawROI, Use_DetEdge, Use_AIEdge, AI_Fail_UseDraw, threshold_value, AI_Erode_Size, EdgeMask.empty());
std::string str123 = buffer;
return str123;
}
};
// 图片对齐功能
struct Function_Image_Align
{
enum RunType
{
type_Use, // 使用
type_Test, // 仅测试
};
bool bOpen; // 是否开启
bool bDraw; // 是否绘制
float fscore; // 定位分数
RunType runType; // 运行模式
cv::Rect search_Roi; // 搜索区域
cv::Rect feature_Roi; // 特征区域
cv::Mat feature_Mask; // 特征mask
cv::Rect Crop_Roi; // 产品裁切区域
std::vector<cv::Point> pointArry1; // 特征区域点
Function_Image_Align()
{
Init();
}
void Init()
{
bOpen = false;
bDraw = false;
fscore = 0.9;
search_Roi = cv::Rect(0, 0, 0, 0);
feature_Roi = cv::Rect(0, 0, 0, 0);
Crop_Roi = cv::Rect(0, 0, 0, 0);
pointArry1.clear();
pointArry1.shrink_to_fit();
if (!feature_Mask.empty())
{
feature_Mask.release();
}
runType = type_Use;
}
// 将枚举值转换为字符串
std::string colorToString(RunType c)
{
switch (c)
{
case type_Use:
return "Use";
case type_Test:
return "Test";
default:
return "Use";
}
}
void copy(Function_Image_Align tem)
{
this->bOpen = tem.bOpen;
this->bDraw = tem.bDraw;
this->fscore = tem.fscore;
this->search_Roi = tem.search_Roi;
this->feature_Roi = tem.feature_Roi;
this->Crop_Roi = tem.Crop_Roi;
this->feature_Mask = tem.feature_Mask.clone();
this->pointArry1.assign(tem.pointArry1.begin(), tem.pointArry1.end());
this->runType = tem.runType;
}
void ToMaskImg(int img_W, int img_H)
{
if (img_W > 0 && img_H > 0)
{
if (!feature_Mask.empty())
{
feature_Mask.release();
}
if (!bOpen)
{
return;
}
// cv::Rect boundingRect = cv::boundingRect(pointArry1);
// feature_Roi = boundingRect;
// for (int i = 0; i < pointArry1.size(); i++)
// {
// pointArry1[i].x -= boundingRect.x;
// pointArry1[i].y -= boundingRect.y;
// }
cv::Mat tem_feature_Mask = cv::Mat(img_H, img_W, CV_8U, cv::Scalar(0));
if (pointArry1.size() > 0)
{
cv::fillPoly(tem_feature_Mask, pointArry1, cv::Scalar(255));
}
else
{
printf("pointArry1 == 0 \n\n\n");
}
feature_Mask = tem_feature_Mask(feature_Roi).clone();
}
}
void print(std::string str)
{
printf("%s>>bOpen %d bDraw %d fscore %f feature_Mask empty %d run type = %s\n", str.c_str(),
bOpen, bDraw, fscore, feature_Mask.empty(), colorToString(runType).c_str());
}
std::string GetInfo(std::string str)
{
char buffer[128];
sprintf(buffer, "%s>>bOpen %d bDraw %d fscore %f feature_Mask empty %d run type = %s\n", str.c_str(),
bOpen, bDraw, fscore, feature_Mask.empty(), colorToString(runType).c_str());
std::string str123 = buffer;
return str123;
}
};
// 检测功能
struct CheckFunction
{
Function_Base_Det f_BaseDet; // 基础检测
Function_OnlyBLob f_OnlyBLob; // 只获取blob ,不进行分析
Function_BigQX f_Big_QX;
Function_ShieldRegion f_ShieldRegion;
Function_EdgeROI f_EdgeROI;
Function_Image_Align f_Image_Align; // 图片特征对齐
CheckFunction()
{
Init();
}
void Init()
{
f_BaseDet.Init();
f_OnlyBLob.Init();
f_Big_QX.Init();
f_ShieldRegion.Init();
f_EdgeROI.Init();
f_Image_Align.Init();
}
void copy(CheckFunction tem)
{
this->f_BaseDet.copy(tem.f_BaseDet);
this->f_OnlyBLob.copy(tem.f_OnlyBLob);
this->f_Big_QX.copy(tem.f_Big_QX);
this->f_ShieldRegion.copy(tem.f_ShieldRegion);
this->f_EdgeROI.copy(tem.f_EdgeROI);
this->f_Image_Align.copy(tem.f_Image_Align);
}
void print(std::string str)
{
printf("%s>>\n", str.c_str());
f_BaseDet.print("BaseDet");
f_OnlyBLob.print("OnlyBLob");
f_Big_QX.print("Big_QX");
f_ShieldRegion.print("ShieldRegion");
f_EdgeROI.print("EdgeROI");
f_Image_Align.print("Image_Align");
}
std::string GetInfo(std::string str)
{
std::string str123 = str + ":\n";
str123 += f_BaseDet.GetInfo("BaseDet");
str123 += f_OnlyBLob.GetInfo("f_OnlyBLob");
str123 += f_Big_QX.GetInfo("Big_QX");
str123 += f_ShieldRegion.GetInfo("ShieldRegion");
str123 += f_EdgeROI.GetInfo("EdgeROI");
str123 += f_Image_Align.GetInfo("Image_Align");
return str123;
}
};
// 单通道检测功能
struct ChannelCheckFunction
{
std::string strChannelName;
CheckFunction function; // 使用UP画面的缺陷进行过滤
ChannelCheckFunction()
{
Init();
}
void Init()
{
strChannelName = "";
function.Init();
}
void copy(ChannelCheckFunction tem)
{
this->strChannelName = tem.strChannelName;
this->function.copy(tem.function);
}
void print(std::string str)
{
printf("%s>> %s\n", str.c_str(), strChannelName.c_str());
function.print("function");
}
std::string GetInfo(std::string str)
{
std::string str123 = "";
str123 += strChannelName + ":\n";
str123 += function.GetInfo("function");
// str123 += "\n";
return str123;
}
};
// 基础检测功能 mark
struct Base_Function_MarkLine
{
bool bOpen; // 是否开启
bool bDraw; // 是否绘制
bool badapt_region; // 是否自适应区域
cv::Rect productROI;
std::vector<cv::Point> region;
cv::Point mark_local_1;
cv::Point mark_local_2;
Base_Function_MarkLine()
{
Init();
}
void Init()
{
bOpen = false;
bDraw = false;
badapt_region = false;
mark_local_1 = cv::Point(0, 0);
mark_local_2 = cv::Point(0, 0);
productROI = cv::Rect(0, 0, 0, 0);
region.clear();
}
void copy(Base_Function_MarkLine tem)
{
this->bOpen = tem.bOpen;
this->region.assign(tem.region.begin(), tem.region.end());
this->productROI = tem.productROI;
this->bDraw = tem.bDraw;
this->badapt_region = tem.badapt_region;
this->mark_local_1 = tem.mark_local_1;
this->mark_local_2 = tem.mark_local_2;
}
void print(std::string str)
{
printf("%s>>bOpen %d bDraw %d badapt_region %d mark1 [%d %d] mark2 [%d %d] \n", str.c_str(),
bOpen, bDraw, badapt_region,mark_local_1.x, mark_local_1.y, mark_local_2.x, mark_local_2.y);
}
std::string GetInfo(std::string str)
{
char buffer[256];
sprintf(buffer, "%s>>bOpen %d bDraw %d badapt_region %d mark1 [%d %d] mark2 [%d %d] \n", str.c_str(),
bOpen, bDraw, badapt_region,mark_local_1.x, mark_local_1.y, mark_local_2.x, mark_local_2.y);
std::string str123 = buffer;
return str123;
}
};
// 基础检测功能 存图设置
struct Base_Function_SaveImg
{
bool bOpen; // 是否开启
bool bSaveMarkImg; // mark 存图
bool bSaveClsImg; // 分类 存图
bool bSaveAlginImg; // 分类 存图
Base_Function_SaveImg()
{
Init();
}
void Init()
{
bOpen = false;
bSaveMarkImg = false;
bSaveClsImg = false;
bSaveAlginImg = false;
}
void copy(Base_Function_SaveImg tem)
{
this->bOpen = tem.bOpen;
this->bSaveMarkImg = tem.bSaveMarkImg;
this->bSaveClsImg = tem.bSaveClsImg;
this->bSaveAlginImg = tem.bSaveAlginImg;
}
void print(std::string str)
{
printf("%s>>bOpen %d bSaveMarkImg %d bSaveClsImg %d bSaveAlginImg %d \n", str.c_str(),
bOpen, bSaveMarkImg, bSaveClsImg, bSaveAlginImg);
}
std::string GetInfo(std::string str)
{
char buffer[256];
sprintf(buffer, "%s>>bOpen %d bSaveMarkImg %d bSaveClsImg %d bSaveAlginImg %d \n", str.c_str(),
bOpen, bSaveMarkImg, bSaveClsImg, bSaveAlginImg);
std::string str123 = buffer;
return str123;
}
};
// 大缺陷 NG
struct Big_NG
{
bool bOpen; // 是否开启
float fArea;
std::string strname;
Big_NG()
{
Init();
}
void Init()
{
bOpen = false;
fArea = 1;
strname = "";
}
void copy(Big_NG tem)
{
this->bOpen = tem.bOpen;
this->fArea = tem.fArea;
this->strname = tem.strname;
}
void print(std::string str)
{
printf("%s>>bOpen %d strname %s fArea %f \n", str.c_str(),
bOpen, strname.c_str(), fArea);
}
std::string GetInfo(std::string str)
{
char buffer[256];
sprintf(buffer, "%s>>bOpen %d strname %s fArea %f \n", str.c_str(),
bOpen, strname.c_str(), fArea);
std::string str123 = buffer;
return str123;
}
};
// 基础检测功能 大缺陷 NG
struct Base_Function_BigNG
{
bool bOpen; // 是否开启
bool usPreResult;
Big_NG qx[CONFIG_QX_NAME_count];
Base_Function_BigNG()
{
Init();
}
void Init()
{
bOpen = false;
usPreResult = true;
for (int i = 0; i < CONFIG_QX_NAME_count; i++)
{
qx[i].Init();
}
}
void copy(Base_Function_BigNG tem)
{
this->bOpen = tem.bOpen;
for (int i = 0; i < CONFIG_QX_NAME_count; i++)
{
this->qx[i].copy(tem.qx[i]);
}
}
void print(std::string str)
{
printf("%s>>bOpen %d \n", str.c_str(),
bOpen);
for (int i = 0; i < CONFIG_QX_NAME_count; i++)
{
printf("%s \n", qx[i].GetInfo("").c_str());
}
}
std::string GetInfo(std::string str)
{
char buffer[256];
sprintf(buffer, "%s>>bOpen %d \n", str.c_str(),
bOpen);
std::string str123 = buffer;
for (int i = 0; i < CONFIG_QX_NAME_count; i++)
{
str123 += qx[i].GetInfo("");
}
return str123;
}
};
// 基础检测功能 CELL AOI 边缘缺陷检测
struct Base_Function_Edge_Det
{
bool bOpen; // 是否开启
int Search_threshold; // 搜索边缘阈值
int Det_threshold; // 缺陷检测阈值
int Det_Range; // 检测范围
int QX_Widht_min; // 缺陷宽度-最小
int QX_Widht_max;
int QX_Height_min;
int QX_Height_max;
bool queJiao_LU_Open;
bool queJiao_RU_Open;
bool queJiao_LD_Open;
bool queJiao_RD_Open;
int queJiao_width;
int queJiao_height;
bool bDrawRoi;
cv::Rect draw_ROI;
std::vector<cv::Point> region;
bool bDrawResult; // 是否绘制结果
Base_Function_Edge_Det()
{
Init();
}
void Init()
{
bOpen = false;
Search_threshold = 30;
Det_threshold = 30;
Det_Range = 100;
QX_Widht_min = 10;
QX_Widht_max = 100;
QX_Height_min = 10;
QX_Height_max = 100;
queJiao_LU_Open = false;
queJiao_RU_Open = false;
queJiao_LD_Open = false;
queJiao_RD_Open = false;
queJiao_width = 50;
queJiao_height = 50;
bDrawRoi = false;
draw_ROI = cv::Rect(0, 0, 0, 0);
region.clear();
region.erase(region.begin(), region.end());
bDrawResult = false;
}
void copy(Base_Function_Edge_Det tem)
{
this->bOpen = tem.bOpen;
this->Search_threshold = tem.Search_threshold;
this->Det_threshold = tem.Det_threshold;
this->Det_Range = tem.Det_Range;
this->QX_Widht_min = tem.QX_Widht_min;
this->QX_Widht_max = tem.QX_Widht_max;
this->QX_Height_min = tem.QX_Height_min;
this->QX_Height_max = tem.QX_Height_max;
this->queJiao_LU_Open = tem.queJiao_LU_Open;
this->queJiao_RU_Open = tem.queJiao_RU_Open;
this->queJiao_LD_Open = tem.queJiao_LD_Open;
this->queJiao_RD_Open = tem.queJiao_RD_Open;
this->queJiao_width = tem.queJiao_width;
this->queJiao_height = tem.queJiao_height;
this->region.assign(tem.region.begin(), tem.region.end());
this->draw_ROI = tem.draw_ROI;
this->bDrawRoi = tem.bDrawRoi;
this->bDrawResult = tem.bDrawResult;
}
void print(std::string str)
{
printf("%s>>bOpen %d Search_threshold %d Det_threshold %d Det_Range %d QX_Widht [%d %d] QX_Height [%d %d]\n", str.c_str(),
bOpen, Search_threshold, Det_threshold, Det_Range, QX_Widht_min, QX_Widht_max, QX_Height_min, QX_Height_max);
}
std::string GetInfo(std::string str)
{
char buffer[256];
sprintf(buffer, "%s>>bOpen %d Search_threshold %d Det_threshold %d Det_Range %d QX_Widht [%d %d] QX_Height [%d %d]\n", str.c_str(),
bOpen, Search_threshold, Det_threshold, Det_Range, QX_Widht_min, QX_Widht_max, QX_Height_min, QX_Height_max);
std::string str123 = buffer;
return str123;
}
};
// 支架检测
struct Base_Function_Support_Det
{
bool bOpen; // 是否开启
std::vector<cv::Point> supportRegion;
cv::RotatedRect supportRect;
float x_offset;
float y_offset;
float r_offset;
std::vector<cv::Point> handleRegion;
cv::RotatedRect handleRect;
Base_Function_Support_Det()
{
Init();
}
void Init()
{
bOpen = false;
supportRegion.clear();
supportRect = cv::RotatedRect();
x_offset = 0;
y_offset = 0;
r_offset = 0;
handleRegion.clear();
handleRect = cv::RotatedRect();
}
void copy(Base_Function_Support_Det tem)
{
this->bOpen = tem.bOpen;
this->supportRegion.assign(tem.supportRegion.begin(), tem.supportRegion.end());
this->supportRect = tem.supportRect;
this->x_offset = tem.x_offset;
this->y_offset = tem.y_offset;
this->r_offset = tem.r_offset;
this->handleRegion.assign(tem.handleRegion.begin(), tem.handleRegion.end());
this->handleRect = tem.handleRect;
}
void print(std::string str)
{
printf("%s>>bOpen %d x_offset %f y_offset %f r_offset %f\n", str.c_str(),
bOpen, x_offset, y_offset, r_offset);
}
std::string GetInfo(std::string str)
{
char buffer[256];
sprintf(buffer, "%s>>bOpen %d x_offset %f y_offset %f r_offset %f\n", str.c_str(),
bOpen, x_offset, y_offset, r_offset);
std::string str123 = buffer;
return str123;
}
};
// 基础检测功能
struct BaseCheckFunction
{
Base_Function_MarkLine markLine;
Base_Function_Edge_Det edgeDet;
Base_Function_SaveImg saveImg;
Base_Function_BigNG bigNG;
Base_Function_Support_Det supportDet;
BaseCheckFunction()
{
Init();
}
void Init()
{
markLine.Init();
edgeDet.Init();
saveImg.Init();
bigNG.Init();
supportDet.Init();
}
void copy(BaseCheckFunction tem)
{
this->markLine.copy(tem.markLine);
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)
{
printf("******* %s *********\n", str.c_str());
markLine.print("markLine");
edgeDet.print("edgeDet");
saveImg.print("saveImg");
bigNG.print("bigNG");
supportDet.print("supportDet");
}
std::string GetInfo(std::string str)
{
std::string str123 = "";
str123 += markLine.GetInfo("markLine");
str123 += edgeDet.GetInfo("edgeDet");
str123 += saveImg.GetInfo("saveImg");
str123 += bigNG.GetInfo("bigNG");
str123 += supportDet.GetInfo("supportDet");
// str123 += "\n";
return str123;
}
};
// 所有通道检测功能
struct ALLChannelCheckFunction
{
std::vector<ChannelCheckFunction> channelFunctionArr; // 所有通道的参数。
ALLChannelCheckFunction()
{
Init();
}
void Init()
{
channelFunctionArr.clear();
channelFunctionArr.shrink_to_fit();
}
void copy(ALLChannelCheckFunction tem)
{
this->channelFunctionArr.assign(tem.channelFunctionArr.begin(), tem.channelFunctionArr.end());
}
void print(std::string str)
{
printf("%s===========================\n", str.c_str());
for (int i = 0; i < channelFunctionArr.size(); i++)
{
channelFunctionArr.at(i).print("");
}
printf("%s===========================\n", str.c_str());
}
};
// 和相机相关的分析参数
struct AnalysisyConfigST
{
std::string strSkuName;
CommonCheckConfigST commonCheckConfig; // 和图片相关的参数
ALLChannelCheckFunction checkFunction; // 每个通道的检测功能
BaseCheckFunction baseFunction; // 检测检测的function
AnalysisyConfigST()
{
strSkuName = "";
}
void copy(AnalysisyConfigST tem)
{
this->strSkuName = tem.strSkuName;
this->commonCheckConfig.copy(tem.commonCheckConfig);
this->checkFunction.copy(tem.checkFunction);
this->baseFunction.copy(tem.baseFunction);
}
void print(std::string str)
{
printf("%s=============AnalysisyConfigST==============\n", str.c_str());
checkFunction.print("checkFunction");
baseFunction.print("baseFunction");
printf("%s============AnalysisyConfigST===============\n", str.c_str());
}
};
// 金佰利 图片亮度值 参数 后来添加的
struct ImgBrightnessROIConfig
{
bool bcheck;
cv::Rect imageBrightnessROI; // 图像亮度检测区域
int minthreshold; // 最小灰度阈值
int maxthreshold; // 最大灰度阈值
int alarmSheet; // 检测张数
ImgBrightnessROIConfig()
{
bcheck = false;
imageBrightnessROI = cv::Rect(0, 0, 0, 0);
minthreshold = 0;
maxthreshold = 0;
alarmSheet = 0;
}
void copy(ImgBrightnessROIConfig tem)
{
this->bcheck = tem.bcheck;
this->imageBrightnessROI = tem.imageBrightnessROI;
this->maxthreshold = tem.maxthreshold;
this->minthreshold = tem.minthreshold;
this->alarmSheet = tem.alarmSheet;
}
};
// 预处理图片参数信息
struct PreDealImgConfig
{
// 图片预处理:
// 1cut到指定大小
// 2、bresize = true, 缩放到模型输入图片尺寸大小
// 3、bInAI_ImgFflip 输入模型的图片是否要 水平翻转
// 4、bOutAI_ImgFflip 模型输出的图片是否要 水平翻转
cv::Rect cutRoi; // 图片裁剪区域信息
bool bresize; // 是否要resize 到模型输入图尺寸大小
bool bInAI_ImgFflip; // 模型输入的图片是否翻转
bool bOutAI_ImgFflip; // 模型输出的图片是否翻转
PreDealImgConfig()
{
cutRoi.x = 0;
cutRoi.y = 0;
cutRoi.width = 0;
cutRoi.height = 0;
bInAI_ImgFflip = false;
bOutAI_ImgFflip = false;
bresize = false;
}
void copy(PreDealImgConfig tem)
{
this->cutRoi.x = tem.cutRoi.x;
this->cutRoi.y = tem.cutRoi.y;
this->cutRoi.width = tem.cutRoi.width;
this->cutRoi.height = tem.cutRoi.height;
this->bInAI_ImgFflip = tem.bInAI_ImgFflip;
this->bOutAI_ImgFflip = tem.bOutAI_ImgFflip;
this->bresize = tem.bresize;
}
};
// 检测基本参数,包括基本信息,和深度学习模型路径参数
struct CheckConfigST
{
ImageInfo Srcimg_in;
ImageInfo resultimg_out;
PreDealImgConfig preDealImgConfig;
CAM_CONFIGINFO_ camConfig;
CheckConfigST()
{
}
void copy(CheckConfigST tem)
{
this->preDealImgConfig.copy(tem.preDealImgConfig);
this->Srcimg_in.copy(tem.Srcimg_in);
this->resultimg_out.copy(tem.resultimg_out);
this->camConfig.copy(tem.camConfig);
}
};
struct BLobResult
{
int nresult; // 最后的结果
cv::Rect roi; // 位置
int AI_qx_type; // 缺陷类型,
int area; // Blob- 面积
int energy; // Blob-能量
float JudgArea; // Blob- 调整后的面积 平方毫米
float len; // Blob- 长度
int maxValue; // Blob- 最大亮度
float grayDis; // Blob- 灰阶
float density; // Blob- 密度
BLobResult()
{
Init();
}
void Init()
{
nresult = 0; // 最后的结果
roi = {0, 0, 0, 0}; // 位置
AI_qx_type = 0; // 缺陷类型,
area = 0; // Blob- 面积
energy = 0; // Blob-能量
JudgArea = 0; // Blob- 调整后的面积 平方毫米
len = 0; // Blob- 长度
maxValue = 0; // Blob- 最大亮度
grayDis = 0; // Blob- 灰阶
density = 0; // Blob- 密度
}
};
// 检测结果
struct DetResultST
{
std::vector<BLobResult> BLobResultList;
DetResultST()
{
Init();
}
void Init()
{
BLobResultList.erase(BLobResultList.begin(), BLobResultList.end());
BLobResultList.clear();
}
void copy(DetResultST tem)
{
this->BLobResultList.assign(tem.BLobResultList.begin(), tem.BLobResultList.end());
}
};
#endif //_CORELOGICFACTORY_HPP_