|
|
|
|
|
|
|
|
#ifndef _ImageDetConfig_HPP_
|
|
|
#define _ImageDetConfig_HPP_
|
|
|
|
|
|
#include <string>
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
#include "ImgCheckConfig.h"
|
|
|
#include "CheckErrorCodeDefine.hpp"
|
|
|
#include "DetLog.h"
|
|
|
|
|
|
class QX_Merge_Analysis;
|
|
|
#define QX_SAMLLIMG_WIDTH 160
|
|
|
#define QX_SAMLLIMG_HEIGHT 160
|
|
|
|
|
|
enum QX_Stauts
|
|
|
{
|
|
|
QX_Stauts_Analysis,
|
|
|
QX_Stauts_OK,
|
|
|
QX_Stauts_YS,
|
|
|
QX_Stauts_Draw,
|
|
|
};
|
|
|
// 缺陷结果信息
|
|
|
struct QX_ERROR_INFO_
|
|
|
{
|
|
|
|
|
|
int Idx;
|
|
|
int result;
|
|
|
std::string result_name;
|
|
|
cv::Rect roi;
|
|
|
int area;
|
|
|
int energy;
|
|
|
float JudgArea;
|
|
|
float JudgArea_second;
|
|
|
float flen;
|
|
|
int nconfig_qx_type;
|
|
|
std::string qx_name;
|
|
|
int maxValue;
|
|
|
int whiteOrBlack;
|
|
|
float grayDis;
|
|
|
float fUpIou;
|
|
|
float density; // Blob- 密度
|
|
|
std::vector<std::string> detLogList; // 检测日志
|
|
|
std::shared_ptr<DetLog> detlog;
|
|
|
std::vector<int> detRegionidxList; // 对应检测区域的 idx.
|
|
|
|
|
|
QX_Stauts qx_status;
|
|
|
QX_ERROR_INFO_()
|
|
|
{
|
|
|
Init();
|
|
|
}
|
|
|
~QX_ERROR_INFO_()
|
|
|
{
|
|
|
}
|
|
|
void Init()
|
|
|
{
|
|
|
whiteOrBlack = 0;
|
|
|
Idx = 0;
|
|
|
area = 0;
|
|
|
energy = 0;
|
|
|
JudgArea = 0;
|
|
|
JudgArea_second = 0;
|
|
|
flen = 0;
|
|
|
nconfig_qx_type = 0;
|
|
|
qx_name = "";
|
|
|
maxValue = 0;
|
|
|
grayDis = 0;
|
|
|
fUpIou = 0;
|
|
|
result = 0;
|
|
|
result_name = "OK";
|
|
|
density = 0;
|
|
|
cv::Rect roi = cv::Rect(0, 0, 0, 0);
|
|
|
detLogList.erase(detLogList.begin(), detLogList.end());
|
|
|
detLogList.clear();
|
|
|
detRegionidxList.clear();
|
|
|
detlog = std::make_shared<DetLog>();
|
|
|
qx_status = QX_Stauts_Analysis;
|
|
|
}
|
|
|
void print(std::string str = "")
|
|
|
{
|
|
|
std::cout << str << ": "
|
|
|
<< "Idx: " << Idx
|
|
|
<< ", Result: " << result << " " << result_name
|
|
|
<< ", ROI: (" << roi.x << ", " << roi.y << ", " << roi.width << ", " << roi.height << ")"
|
|
|
<< ", Area: " << area
|
|
|
<< ", Energy: " << energy
|
|
|
<< ", JudgArea: " << JudgArea
|
|
|
<< ", JudgArea second: " << JudgArea_second
|
|
|
<< ", density: " << density
|
|
|
<< ", Flen: " << flen
|
|
|
<< ", nconfig_qx_type: " << nconfig_qx_type
|
|
|
<< ", QX Name: " << qx_name
|
|
|
<< ", Max Value: " << maxValue
|
|
|
<< ", Gray Dis: " << grayDis
|
|
|
<< ", fUpIou: " << fUpIou
|
|
|
<< ", whiteOrBlack: " << whiteOrBlack
|
|
|
<< std::endl;
|
|
|
}
|
|
|
};
|
|
|
struct One_Image_CheckResult_
|
|
|
{
|
|
|
|
|
|
cv::Rect CutRoi; // 当前检测图片 对应的裁切区域
|
|
|
cv::Rect Param_CropRoi; // 参数模版 对应的裁切区域
|
|
|
std::shared_ptr<std::vector<QX_ERROR_INFO_>> pQx_ErrorList; // 缺陷错误信息
|
|
|
|
|
|
void print(std::string str = "")
|
|
|
{
|
|
|
std::cout << str << ": "
|
|
|
<< " CutRoi: (" << CutRoi.x << ", " << CutRoi.y << ", " << CutRoi.width << ", " << CutRoi.height << ")"
|
|
|
<< std::endl;
|
|
|
|
|
|
std::cout << str << ": "
|
|
|
<< " Param_CropRoi: (" << Param_CropRoi.x << ", " << Param_CropRoi.y << ", " << Param_CropRoi.width << ", " << Param_CropRoi.height << ")"
|
|
|
<< std::endl;
|
|
|
|
|
|
for (int i = 0; i < pQx_ErrorList->size(); i++)
|
|
|
{
|
|
|
pQx_ErrorList->at(i).print(std::to_string(i));
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
// 定位结果
|
|
|
struct Align_Result
|
|
|
{
|
|
|
bool bDet; // 检测状态 true 成功,false 失败。
|
|
|
bool bUse; // 是否要使用。
|
|
|
bool bDraw; // 是否绘制
|
|
|
|
|
|
cv::Point bestMatch;
|
|
|
int offt_x; // 偏移值
|
|
|
int offt_y; // 偏移值
|
|
|
float fCropROI_Scale_ParmToDet_X; // 裁剪区域的缩放
|
|
|
float fCropROI_Scale_ParmToDet_Y; // 裁剪区域的缩放
|
|
|
|
|
|
std::vector<cv::Point> feature_PointList_DetImg; // 特征区域点 检查图上的特征点
|
|
|
cv::Rect Crop_Roi_DetImg; // 检测图片上的 裁切区域
|
|
|
cv::Rect Crop_Roi_ParmImg; // 参数图片上的 裁切区域
|
|
|
|
|
|
Align_Result()
|
|
|
{
|
|
|
Init();
|
|
|
}
|
|
|
void Init()
|
|
|
{
|
|
|
bDet = false;
|
|
|
bUse = false;
|
|
|
offt_x = 0;
|
|
|
offt_y = 0;
|
|
|
bestMatch = cv::Point(0, 0);
|
|
|
fCropROI_Scale_ParmToDet_X = 1;
|
|
|
fCropROI_Scale_ParmToDet_Y = 1;
|
|
|
feature_PointList_DetImg.clear();
|
|
|
Crop_Roi_DetImg = cv::Rect(0, 0, 0, 0);
|
|
|
Crop_Roi_ParmImg = cv::Rect(0, 0, 0, 0);
|
|
|
bDraw = false;
|
|
|
}
|
|
|
void copy(Align_Result tem)
|
|
|
{
|
|
|
this->bDet = tem.bDet;
|
|
|
this->bUse = tem.bUse;
|
|
|
this->offt_x = tem.offt_x;
|
|
|
this->offt_y = tem.offt_y;
|
|
|
this->fCropROI_Scale_ParmToDet_X = tem.fCropROI_Scale_ParmToDet_X;
|
|
|
this->fCropROI_Scale_ParmToDet_Y = tem.fCropROI_Scale_ParmToDet_Y;
|
|
|
this->bDraw = tem.bDraw;
|
|
|
this->bestMatch = tem.bestMatch;
|
|
|
this->Crop_Roi_DetImg = tem.Crop_Roi_DetImg;
|
|
|
this->Crop_Roi_ParmImg = tem.Crop_Roi_ParmImg;
|
|
|
this->feature_PointList_DetImg.assign(tem.feature_PointList_DetImg.begin(), tem.feature_PointList_DetImg.end());
|
|
|
}
|
|
|
// 从检测图的原始图片 映射到 参数的原始图
|
|
|
cv::Point Det_srcToParm_src_Point(cv::Point &p)
|
|
|
{
|
|
|
cv::Point dst_p;
|
|
|
dst_p.x = (p.x - offt_x) / fCropROI_Scale_ParmToDet_X;
|
|
|
dst_p.y = (p.y - offt_y) / fCropROI_Scale_ParmToDet_Y;
|
|
|
return dst_p;
|
|
|
}
|
|
|
cv::Rect Det_srcToParm_src_Rect(cv::Rect &roi)
|
|
|
{
|
|
|
cv::Rect dst_roi;
|
|
|
cv::Point src_pl = cv::Point(roi.x, roi.y);
|
|
|
cv::Point src_rb = cv::Point(roi.x + roi.width, roi.y + roi.height);
|
|
|
cv::Point p_lt = Det_srcToParm_src_Point(src_pl);
|
|
|
cv::Point p_rb = Det_srcToParm_src_Point(src_rb);
|
|
|
dst_roi.x = p_lt.x;
|
|
|
dst_roi.y = p_lt.y;
|
|
|
dst_roi.width = p_rb.x - p_lt.x;
|
|
|
dst_roi.height = p_rb.y - p_lt.y;
|
|
|
|
|
|
return dst_roi;
|
|
|
}
|
|
|
// 参数的原始图 映射到 检测图的原始图片
|
|
|
cv::Point Parm_srcToDet_src_Point(cv::Point &p)
|
|
|
{
|
|
|
cv::Point dst_p;
|
|
|
dst_p.x = p.x * fCropROI_Scale_ParmToDet_X + offt_x;
|
|
|
dst_p.y = p.y * fCropROI_Scale_ParmToDet_Y + offt_y;
|
|
|
return dst_p;
|
|
|
}
|
|
|
cv::Rect Parm_srcToDet_src_Rect(cv::Rect &roi)
|
|
|
{
|
|
|
cv::Rect dst_roi;
|
|
|
cv::Point src_pl = cv::Point(roi.x, roi.y);
|
|
|
cv::Point src_rb = cv::Point(roi.x + roi.width, roi.y + roi.height);
|
|
|
cv::Point p_lt = Parm_srcToDet_src_Point(src_pl);
|
|
|
cv::Point p_rb = Parm_srcToDet_src_Point(src_rb);
|
|
|
dst_roi.x = p_lt.x;
|
|
|
dst_roi.y = p_lt.y;
|
|
|
dst_roi.width = p_rb.x - p_lt.x;
|
|
|
dst_roi.height = p_rb.y - p_lt.y;
|
|
|
|
|
|
return dst_roi;
|
|
|
}
|
|
|
// 参数图片上的点 对应到 检测裁切后上的点
|
|
|
cv::Point Parm_srcToDet_Crop_Point(cv::Point &p)
|
|
|
{
|
|
|
cv::Point dst_p = Parm_srcToDet_src_Point(p);
|
|
|
dst_p.x -= Crop_Roi_DetImg.x;
|
|
|
dst_p.y -= Crop_Roi_DetImg.y;
|
|
|
return dst_p;
|
|
|
}
|
|
|
// 参数图片上的点 对应到 检测裁切后上的点
|
|
|
cv::Rect Parm_srcToDet_Crop_Rect(cv::Rect &roi)
|
|
|
{
|
|
|
cv::Rect dst_roi;
|
|
|
cv::Point src_pl = cv::Point(roi.x, roi.y);
|
|
|
cv::Point src_rb = cv::Point(roi.x + roi.width, roi.y + roi.height);
|
|
|
cv::Point p_lt = Parm_srcToDet_Crop_Point(src_pl);
|
|
|
cv::Point p_rb = Parm_srcToDet_Crop_Point(src_rb);
|
|
|
dst_roi.x = p_lt.x;
|
|
|
dst_roi.y = p_lt.y;
|
|
|
dst_roi.width = p_rb.x - p_lt.x;
|
|
|
dst_roi.height = p_rb.y - p_lt.y;
|
|
|
|
|
|
return dst_roi;
|
|
|
}
|
|
|
void CalOfftScal()
|
|
|
{
|
|
|
cv::Point src_pl = cv::Point(Crop_Roi_DetImg.x, Crop_Roi_DetImg.y);
|
|
|
cv::Point src_rb = cv::Point(Crop_Roi_DetImg.x + Crop_Roi_DetImg.width, Crop_Roi_DetImg.y + Crop_Roi_DetImg.height);
|
|
|
|
|
|
cv::Point param_pl = cv::Point(Crop_Roi_ParmImg.x, Crop_Roi_ParmImg.y);
|
|
|
cv::Point param_rb = cv::Point(Crop_Roi_ParmImg.x + Crop_Roi_ParmImg.width, Crop_Roi_ParmImg.y + Crop_Roi_ParmImg.height);
|
|
|
|
|
|
int a_x_1 = src_pl.x;
|
|
|
int a_x_2 = src_rb.x;
|
|
|
|
|
|
int b_x_1 = param_pl.x;
|
|
|
int b_x_2 = param_rb.x;
|
|
|
|
|
|
int diff_a_x = a_x_1 - a_x_2;
|
|
|
int diff_b_x = b_x_1 - b_x_2;
|
|
|
float fscale_x = 1;
|
|
|
if (diff_b_x != 0)
|
|
|
{
|
|
|
fscale_x = diff_a_x * 1.0f / diff_b_x;
|
|
|
}
|
|
|
int ofx = a_x_1 - fscale_x * b_x_1;
|
|
|
|
|
|
// printf("a_x_1 %d a_x_2 %d\n", a_x_1, a_x_2);
|
|
|
// printf("b_x_1 %d b_x_2 %d\n", b_x_1, b_x_2);
|
|
|
// printf("fscale_x %f ofx %d \n", fscale_x, ofx);
|
|
|
|
|
|
int a_y_1 = src_pl.y;
|
|
|
int a_y_2 = src_rb.y;
|
|
|
|
|
|
int b_y_1 = param_pl.y;
|
|
|
int b_y_2 = param_rb.y;
|
|
|
|
|
|
int diff_a_y = a_y_1 - a_y_2;
|
|
|
int diff_b_y = b_y_1 - b_y_2;
|
|
|
float fscale_y = 1;
|
|
|
if (diff_b_y != 0)
|
|
|
{
|
|
|
fscale_y = diff_a_y * 1.0f / diff_b_y;
|
|
|
}
|
|
|
int ofy = a_y_1 - fscale_y * b_y_1;
|
|
|
|
|
|
// printf("a_y_1 %d a_y_2 %d\n", a_y_1, a_y_2);
|
|
|
// printf("b_y_1 %d b_y_2 %d\n", b_y_1, b_y_2);
|
|
|
// printf("fscale_y %f ofy %d \n", fscale_y, ofy);
|
|
|
|
|
|
offt_x = ofx;
|
|
|
offt_y = ofy;
|
|
|
fCropROI_Scale_ParmToDet_X = fscale_x;
|
|
|
fCropROI_Scale_ParmToDet_Y = fscale_y;
|
|
|
}
|
|
|
void print()
|
|
|
{
|
|
|
printf("scale x %f y %f ,offt x %d y %d\n", fCropROI_Scale_ParmToDet_X, fCropROI_Scale_ParmToDet_Y, offt_x, offt_y);
|
|
|
}
|
|
|
};
|
|
|
// 边缘检测结果
|
|
|
struct EdgeDetResult
|
|
|
{
|
|
|
int nresult;
|
|
|
cv::Rect cutRoi;
|
|
|
cv::Mat shieldMask; // 在 屏蔽mask图片
|
|
|
cv::Mat shieldMask_Src; // 在原图上的屏蔽mask图片
|
|
|
cv::Mat edge_cutMask; // 边缘 图片 在裁切后的图片
|
|
|
std::shared_ptr<std::vector<cv::Rect>> pEdgeDet_roiList; // 边缘检测的区域
|
|
|
Align_Result m_align_Result;
|
|
|
|
|
|
int ninstruct;
|
|
|
EdgeDetResult()
|
|
|
{
|
|
|
nresult = -1;
|
|
|
cutRoi = cv::Rect(0, 0, 0, 0);
|
|
|
m_align_Result.Init();
|
|
|
ninstruct = 0;
|
|
|
pEdgeDet_roiList = std::make_shared<std::vector<cv::Rect>>();
|
|
|
}
|
|
|
};
|
|
|
// 产品相关的 基础检测结果
|
|
|
struct ProductBaseResult
|
|
|
{
|
|
|
std::string strproductName = ""; // 产品 ID
|
|
|
int nCamera_Num = 0;
|
|
|
std::shared_ptr<DetLog> detlog;
|
|
|
std::shared_ptr<QX_Merge_Analysis> pQX_Merge_Analysis;
|
|
|
// ProductBaseResult()
|
|
|
// {
|
|
|
// pQX_Merge_Analysis = QX_Merge_Analysis::GetInstance();
|
|
|
// pQX_Merge_Analysis->InitData();
|
|
|
// }
|
|
|
};
|
|
|
// 相机相关的 基础检测结果
|
|
|
struct MakeLine_Result
|
|
|
{
|
|
|
int nresult = 1;
|
|
|
cv::Rect markLine_Roi_X = cv::Rect(0, 0, 0, 0);
|
|
|
cv::Rect markLine_Roi_Y = cv::Rect(0, 0, 0, 0);
|
|
|
};
|
|
|
struct ZF_Result
|
|
|
{
|
|
|
int nresult = 1;
|
|
|
bool bShield_ZF = false; // 是否屏蔽字符
|
|
|
std::vector<cv::Rect> pZF_roiList; // 字符的区域
|
|
|
std::vector<cv::Point> ZF_centerPoint; // 字符的中心点位置
|
|
|
};
|
|
|
struct CameraBaseResult
|
|
|
{
|
|
|
enum ImageDet_Status
|
|
|
{
|
|
|
ImageDet_Status_None = 0,
|
|
|
ImageDet_Status_NoDet = 1,
|
|
|
ImageDet_Status_DetComplete = 2,
|
|
|
};
|
|
|
std::string strCameraName = ""; // 相机结果 ID
|
|
|
std::shared_ptr<EdgeDetResult> pEdgeDetResult; // 边缘检测结果
|
|
|
std::shared_ptr<MakeLine_Result> pMarkLineResult; // MarkLine检测结果
|
|
|
std::shared_ptr<ZF_Result> pZF_Result; // zf 检测结果
|
|
|
|
|
|
ImageDet_Status UpImg_Status = ImageDet_Status_None; // Up 画面
|
|
|
ImageDet_Status DPImg_Status = ImageDet_Status_None; // DP 画面
|
|
|
|
|
|
cv::Mat DP_MaskImg; // DP 画面 mask图片
|
|
|
cv::Mat UP_MaskImg; // UP 画面 mask图片
|
|
|
};
|
|
|
struct ImageDetconfig
|
|
|
{
|
|
|
cv::Mat ShieldMaskImg; // 屏蔽mask
|
|
|
cv::Mat UpMaskImg; // Up 画面 mask图片
|
|
|
cv::Mat DPMaskImg;
|
|
|
cv::Mat edge_maskImg;
|
|
|
bool bUseUpMaskImg;
|
|
|
std::shared_ptr<std::vector<cv::Rect>> pZF_roiList; // 字符的区域
|
|
|
|
|
|
std::shared_ptr<shareImage> pBaseImgCheckConfig;
|
|
|
Align_Result alignResult; // 定位结果
|
|
|
ImageDetconfig()
|
|
|
{
|
|
|
Init();
|
|
|
}
|
|
|
~ImageDetconfig()
|
|
|
{
|
|
|
}
|
|
|
void Init()
|
|
|
{
|
|
|
bUseUpMaskImg = false;
|
|
|
if (!ShieldMaskImg.empty())
|
|
|
{
|
|
|
ShieldMaskImg.release();
|
|
|
}
|
|
|
if (!UpMaskImg.empty())
|
|
|
{
|
|
|
UpMaskImg.release();
|
|
|
}
|
|
|
if (!DPMaskImg.empty())
|
|
|
{
|
|
|
DPMaskImg.release();
|
|
|
}
|
|
|
if (!edge_maskImg.empty())
|
|
|
{
|
|
|
edge_maskImg.release();
|
|
|
}
|
|
|
alignResult.Init();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
struct ImageDetResult
|
|
|
{
|
|
|
bool bShield_ZF; // 是否要屏蔽字符区域
|
|
|
bool bUseUpImg; // 是否要使用 up img 进行过滤
|
|
|
cv::Mat AI_maskImg;
|
|
|
int Yx_result; // 异显检测状态
|
|
|
float fUP_IOU; // UP 画面 使用的 iou
|
|
|
std::shared_ptr<std::vector<cv::Rect>> pZF_roiList; // 字符的区域
|
|
|
std::shared_ptr<One_Image_CheckResult_> pOneImgDetResult; // 单图检测结果
|
|
|
std::shared_ptr<CheckResult> pBaseImgCheckResult;
|
|
|
ImageDetResult()
|
|
|
{
|
|
|
Init();
|
|
|
}
|
|
|
~ImageDetResult()
|
|
|
{
|
|
|
}
|
|
|
void Init()
|
|
|
{
|
|
|
bShield_ZF = false;
|
|
|
if (!AI_maskImg.empty())
|
|
|
{
|
|
|
AI_maskImg.release();
|
|
|
}
|
|
|
Yx_result = 0;
|
|
|
fUP_IOU = 0;
|
|
|
bUseUpImg = false;
|
|
|
}
|
|
|
};
|
|
|
#endif //_CORELOGICFACTORY_HPP_
|