update 初步完成流程梳理

main
liusiyang 3 weeks ago
parent 0fbfccf161
commit 04246a9598

@ -156,7 +156,7 @@ public:
std::shared_ptr<AIModel_Base> Defect; std::shared_ptr<AIModel_Base> Defect;
std::shared_ptr<AIModel_Base> Class; std::shared_ptr<AIModel_Base> Class;
std::shared_ptr<AIModel_Base> Pin_Loc; std::shared_ptr<AIModel_Base> Tag_Loc;
std::shared_ptr<AIModel_Base> Align_Outer; std::shared_ptr<AIModel_Base> Align_Outer;
std::shared_ptr<AIModel_Base> Align_Inner; std::shared_ptr<AIModel_Base> Align_Inner;

@ -42,7 +42,7 @@ int AIFactory::InitALLAIModle(GPU_Config gupconfig)
Defect = AIModel_Base::GetInstance(); Defect = AIModel_Base::GetInstance();
AIModel_Base::AIModelRun_Config edge_config; AIModel_Base::AIModelRun_Config edge_config;
edge_config.gpuconfig.copy(gupconfig); edge_config.gpuconfig.copy(gupconfig);
edge_config.strPath = "/home/aidlux/BOE/UseModel_ZB/Defect.engine"; edge_config.strPath = "/home/aidlux/BOE/UseModel_ZB/BM/DefectLight.engine";
edge_config.strName = "CA_Det"; edge_config.strName = "CA_Det";
edge_config.inputType = AIModel_Base::Input_CHW; edge_config.inputType = AIModel_Base::Input_CHW;
edge_config.Stream_num = 2; edge_config.Stream_num = 2;
@ -59,23 +59,23 @@ int AIFactory::InitALLAIModle(GPU_Config gupconfig)
jbl_config.IsClass = true; jbl_config.IsClass = true;
Class->Init(jbl_config); Class->Init(jbl_config);
} }
if (!Pin_Loc) if (!Tag_Loc)
{ {
Pin_Loc = AIModel_Base::GetInstance(); Tag_Loc = AIModel_Base::GetInstance();
AIModel_Base::AIModelRun_Config edge_config; AIModel_Base::AIModelRun_Config edge_config;
edge_config.gpuconfig.copy(gupconfig); edge_config.gpuconfig.copy(gupconfig);
edge_config.strPath = "/home/aidlux/BOE/UseModel_ZB/PinLoc.engine"; edge_config.strPath = "/home/aidlux/BOE/UseModel_ZB/BM/BadLabel.engine";
edge_config.strName = "TA_Det"; edge_config.strName = "TA_Det";
edge_config.inputType = AIModel_Base::Input_CHW; edge_config.inputType = AIModel_Base::Input_CHW;
edge_config.Stream_num = 2; edge_config.Stream_num = 2;
Pin_Loc->Init(edge_config); Tag_Loc->Init(edge_config);
} }
if (!Align_Outer) if (!Align_Outer)
{ {
Align_Outer = AIModel_Base::GetInstance(); Align_Outer = AIModel_Base::GetInstance();
AIModel_Base::AIModelRun_Config edge_config; AIModel_Base::AIModelRun_Config edge_config;
edge_config.gpuconfig.copy(gupconfig); edge_config.gpuconfig.copy(gupconfig);
edge_config.strPath = "/home/aidlux/BOE/UseModel_ZB/AlignOuter.engine"; edge_config.strPath = "/home/aidlux/BOE/UseModel_ZB/BM/ProductLoc.engine";
edge_config.strName = "Align"; edge_config.strName = "Align";
edge_config.inputType = AIModel_Base::Input_CHW; edge_config.inputType = AIModel_Base::Input_CHW;
Align_Outer->Init(edge_config); Align_Outer->Init(edge_config);
@ -85,7 +85,7 @@ int AIFactory::InitALLAIModle(GPU_Config gupconfig)
Align_Inner = AIModel_Base::GetInstance(); Align_Inner = AIModel_Base::GetInstance();
AIModel_Base::AIModelRun_Config edge_config; AIModel_Base::AIModelRun_Config edge_config;
edge_config.gpuconfig.copy(gupconfig); edge_config.gpuconfig.copy(gupconfig);
edge_config.strPath = "/home/aidlux/BOE/UseModel_ZB/AlignInner.engine"; edge_config.strPath = "/home/aidlux/BOE/UseModel_ZB/BM/ClampLoc.engine";
edge_config.strName = "Mark"; edge_config.strName = "Mark";
edge_config.inputType = AIModel_Base::Input_CHW; edge_config.inputType = AIModel_Base::Input_CHW;
Align_Inner->Init(edge_config); Align_Inner->Init(edge_config);

@ -63,7 +63,9 @@ file(GLOB SRC_LISTS
${PROJECT_SOURCE_DIR}/AIEngineModule/src/*.cu ${PROJECT_SOURCE_DIR}/AIEngineModule/src/*.cu
) )
add_library(TY_Check SHARED ${SRC_LISTS}) add_library(TY_Check SHARED ${SRC_LISTS})
set_target_properties(TY_Check PROPERTIES
OUTPUT_NAME "ZB_BACKPLATE"
)
target_link_libraries(TY_Check target_link_libraries(TY_Check
nvinfer nvinfer
Config Config

@ -70,9 +70,6 @@ public:
// 获取模板外接矩形 // 获取模板外接矩形
const cv::RotatedRect &GetTplOuterRect() const { return m_tplOuterRect; } const cv::RotatedRect &GetTplOuterRect() const { return m_tplOuterRect; }
// 获取模板 pin blob 轮廓点集
const std::vector<std::vector<cv::Point>> &GetTplPinContours() const { return m_tplPinContours; }
private: private:
// 加载运行参数 // 加载运行参数
int LoadRunConfig(void *p); int LoadRunConfig(void *p);
@ -183,8 +180,6 @@ private:
// 模板信息 // 模板信息
cv::RotatedRect m_tplOuterRect; // 模板外接矩形 cv::RotatedRect m_tplOuterRect; // 模板外接矩形
std::vector<std::vector<cv::Point>> m_tplPinContours; // 模板 pin blob 轮廓点集
}; };
#endif #endif

@ -134,8 +134,7 @@ public:
int StartCheck(std::shared_ptr<CameraResult> pCamera_Check_Result); int StartCheck(std::shared_ptr<CameraResult> pCamera_Check_Result);
// 设置模板信息并转发给各个检测核心 // 设置模板信息并转发给各个检测核心
void SetTplInfo(const cv::RotatedRect &outerRect, void SetTplInfo(const cv::RotatedRect &outerRect);
const std::vector<std::vector<cv::Point>> &pinContours);
private: private:
// 开启线程 // 开启线程

@ -31,7 +31,6 @@
#include "ImageDetConfig.h" #include "ImageDetConfig.h"
#include "OtherDetect.h" #include "OtherDetect.h"
#include "Define_Error.h" #include "Define_Error.h"
#include "Pin_QX_Det.h"
#include "AI_Edge_Algin.h" #include "AI_Edge_Algin.h"
#include "AI_Factory.h" #include "AI_Factory.h"
#include "ImageAllResult.h" #include "ImageAllResult.h"
@ -80,9 +79,8 @@ public:
int creatsavedir(); int creatsavedir();
// 设置模板信息(模板外接矩形 + 模板 pin blob 轮廓点集) // 设置模板信息(模板外接矩形 + 模板 Tag blob 轮廓点集)
void SetTplInfo(const cv::RotatedRect &outerRect, void SetTplInfo(const cv::RotatedRect &outerRect);
const std::vector<std::vector<cv::Point>> &pinContours);
private: private:
// 加载运行参数 // 加载运行参数
@ -192,8 +190,6 @@ private:
// 更新成像精度 // 更新成像精度
int UpdateImgageScale(); int UpdateImgageScale();
// 边缘缺陷检测
int Pin_Qx_Det(const cv::Mat &img);
// 把blob 汇总成 检测结果。 // 把blob 汇总成 检测结果。
int BLobToDetResult(); int BLobToDetResult();
@ -259,9 +255,6 @@ private:
AI_Edge_Algin m_pAI_Edge_Algin; AI_Edge_Algin m_pAI_Edge_Algin;
// 边缘定位结果 // 边缘定位结果
std::shared_ptr<AI_Edge_Algin::Edge_AI_Result> m_pEdge_Align_Result; std::shared_ptr<AI_Edge_Algin::Edge_AI_Result> m_pEdge_Align_Result;
Pin_QX_Det m_Pin_QX_Det;
Pin_QX_Det::DetConfigResult m_Edge_DetConfig;
std::vector<QXImageResult> m_Draw_qxImageResult; // 缺陷小图结果 std::vector<QXImageResult> m_Draw_qxImageResult; // 缺陷小图结果
std::vector<cv::Rect> SmallRoiList; std::vector<cv::Rect> SmallRoiList;
@ -296,8 +289,6 @@ private:
cv::RotatedRect m_tplOuterRect; // 模板外接矩形 cv::RotatedRect m_tplOuterRect; // 模板外接矩形
cv::RotatedRect m_outer_rroi; cv::RotatedRect m_outer_rroi;
cv::RotatedRect m_inner_rroi; cv::RotatedRect m_inner_rroi;
std::vector<std::vector<cv::Point>> m_tplPinContours; // 模板 pin blob 轮廓点集
std::vector<std::vector<cv::Point>> m_curPinContours; // 当前 pin blob 轮廓点集
}; };
#endif #endif

@ -1,98 +0,0 @@
/*
* @Author: xiewenji 527774126@qq.com
* @Date: 2025-08-04 21:26:32
* @LastEditors: xiewenji 527774126@qq.com
* @LastEditTime: 2025-08-13 16:05:08
* @FilePath: /BOE_ZB_PLATE/AlgorithmModule/include/Pin_QX_Det.h
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/*
* @Author: xiewenji 527774126@qq.com
* @Date: 2025-08-04 21:26:32
* @LastEditors: xiewenji 527774126@qq.com
* @LastEditTime: 2025-08-04 21:29:05
* @FilePath: /BOE_ZB_PLATE/AlgorithmModule/include/Pin_QX_Det.h
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/*
//实现对部分缺陷 需要进行 数量 和距离上分析的
*/
#ifndef Pin_QX_Det_H_
#define Pin_QX_Det_H_
#include <opencv2/opencv.hpp>
#include <opencv2/opencv.hpp>
#include "CheckUtil.hpp"
#include "OtherDetBaseDefine.h"
#include "CheckErrorCodeDefine.hpp"
#include "ImageDetConfig.h"
#include "CheckConfigDefine.h"
#include "ImageStorage.h"
#include "AI_Factory.h"
#include "DetLog.h"
using namespace std;
using namespace cv;
// Pin脚缺陷检测
class Pin_QX_Det
{
public:
struct QX_Result
{
cv::Rect roi_src;
int area_pixel;
QX_Result()
{
roi_src = cv::Rect(0, 0, 0, 0);
area_pixel = 0;
}
};
struct Det_ROI_Config
{
cv::Rect roi;
std::vector<cv::Point> plist;
};
// 检测参数和结果
struct DetConfigResult
{
BaseCheckFunction *pBaseCheckFunction;
std::string strChannel;
bool bSaveResultImg;
DetConfigResult()
{
Init();
}
void Init()
{
pBaseCheckFunction = NULL;
strChannel = "";
bSaveResultImg = false;
}
};
public:
Pin_QX_Det(std::shared_ptr<DetLog>& log_ref);
~Pin_QX_Det();
int GetPinMask(const cv::Mat &img, DetConfigResult *pDetConfig, Mat &mask);
private:
int InitModel_Pin();
private:
bool m_bInitSucc; // 是否初始化成功
std::shared_ptr<DetLog>& m_pdetlog;
bool m_bshowimg;
cv::Mat showimg;
std::shared_ptr<AIFactory> AI_Factory;
private:
/* data */
};
#endif

@ -387,7 +387,7 @@ int AI_Edge_Algin::Get_Edge(int AIModel_type, const cv::Mat &img, DetConfig *pDe
} }
} }
if (m_pDetConfig->bSaveResultImg) // if (m_pDetConfig->bSaveResultImg)
{ {
cv::imwrite(strChannel +"_edge_"+ to_string(AIModel_type) +"_in.png", detImg); cv::imwrite(strChannel +"_edge_"+ to_string(AIModel_type) +"_in.png", detImg);
cv::imwrite(strChannel +"_edge_"+ to_string(AIModel_type) +"_out_mask.png", mask); cv::imwrite(strChannel +"_edge_"+ to_string(AIModel_type) +"_out_mask.png", mask);

@ -195,20 +195,20 @@ int ALLImgCheckAnalysisy::RunStart(void *pconfig1)
m_nErrorCode = re; m_nErrorCode = re;
return m_nErrorCode; return m_nErrorCode;
} }
re = InitTemplateMask(); // re = InitTemplateMask();
if (CHECK_OK != re) // if (CHECK_OK != re)
{ // {
m_nErrorCode = re; // m_nErrorCode = re;
return m_nErrorCode; // return m_nErrorCode;
} // }
// 把模板信息下发到各个相机检测实例 // 把模板信息下发到各个相机检测实例
for (auto &item : m_pCameraCheckAnalysisyList) // for (auto &item : m_pCameraCheckAnalysisyList)
{ // {
if (item.second) // if (item.second)
{ // {
item.second->SetTplInfo(m_tplOuterRect, m_tplPinContours); // item.second->SetTplInfo(m_tplOuterRect, m_tplTagContours);
} // }
} // }
m_nErrorCode = CHECK_OK; m_nErrorCode = CHECK_OK;
printf(">>>> ALLImgCheckAnalysisy Start Succ \n"); printf(">>>> ALLImgCheckAnalysisy Start Succ \n");
@ -339,7 +339,7 @@ int ALLImgCheckAnalysisy::InitAIFactory()
int ALLImgCheckAnalysisy::InitTemplateMask() int ALLImgCheckAnalysisy::InitTemplateMask()
{ {
std::shared_ptr<AIFactory> AI_Factory = AIFactory::GetInstance(); std::shared_ptr<AIFactory> AI_Factory = AIFactory::GetInstance();
if (!AI_Factory || !AI_Factory->Align_Outer || !AI_Factory->Pin_Loc) if (!AI_Factory || !AI_Factory->Align_Outer || !AI_Factory->Tag_Loc)
{ {
return -1; return -1;
} }
@ -412,59 +412,29 @@ int ALLImgCheckAnalysisy::InitTemplateMask()
} }
tplOuterRect = cv::minAreaRect(srcContour); tplOuterRect = cv::minAreaRect(srcContour);
// 模板Pinmask通过模型Pin_Loc得到 // 模板Tagmask通过模型Tag_Loc得到
Mat tplPinMask; // 模板mask Mat tplTagMask; // 模板mask
std::shared_ptr<AIModel_Base> pBackPlate_Pin; std::shared_ptr<AIModel_Base> pBackPlate_Tag;
pBackPlate_Pin = AI_Factory->Pin_Loc; pBackPlate_Tag = AI_Factory->Tag_Loc;
sz.width = pBackPlate_Pin->input_0.width; sz.width = pBackPlate_Tag->input_0.width;
sz.height = pBackPlate_Pin->input_0.height; sz.height = pBackPlate_Tag->input_0.height;
cv::Mat pinImg = tplImg(tplOuterRect.boundingRect()).clone(); // 裁剪模板图像为外接矩形区域 cv::Mat TagImg = tplImg(tplOuterRect.boundingRect()).clone(); // 裁剪模板图像为外接矩形区域
cout << "imgSize: " << tplImg.size() << ", " << "pinImgSize: " << pinImg.size() << ", " << "szSize: " << sz << endl; cout << "imgSize: " << tplImg.size() << ", " << "TagImgSize: " << TagImg.size() << ", " << "szSize: " << sz << endl;
cv::resize(pinImg, detImg, sz); cv::resize(TagImg, detImg, sz);
if (detImg.channels() != 1) if (detImg.channels() != 1)
{ {
cv::cvtColor(detImg, detImg, cv::COLOR_RGB2GRAY); cv::cvtColor(detImg, detImg, cv::COLOR_RGB2GRAY);
} }
re = pBackPlate_Pin->AIDet(detImg, tplPinMask); re = pBackPlate_Tag->AIDet(detImg, tplTagMask);
if (re != 0) if (re != 0)
{ {
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "AI_Pin ", "AICheck_Pin----error %d ", re); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "AI_Tag ", "AICheck_Tag----error %d ", re);
int re123 = 100 + re; int re123 = 100 + re;
return re123; return re123;
} }
// 统计tplPinMask的blob边缘点并绘制到tplImg上
vector<vector<Point>> pin_contours;
vector<Vec4i> hierarchy;
cv::findContours(tplPinMask, pin_contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
// mask 尺寸 -> 裁剪图(pinImg) 尺寸 的缩放比例
const float pin_scale_x = (tplPinMask.cols > 0) ? static_cast<float>(pinImg.cols) / tplPinMask.cols : 0.0f;
const float pin_scale_y = (tplPinMask.rows > 0) ? static_cast<float>(pinImg.rows) / tplPinMask.rows : 0.0f;
// 将轮廓点从 mask 坐标系 映射回 tplImg 坐标系
m_tplPinContours.clear();
m_tplPinContours.reserve(pin_contours.size());
for (size_t i = 0; i < pin_contours.size(); i++)
{
std::vector<cv::Point> mapped;
mapped.reserve(pin_contours[i].size());
for (const auto &pt : pin_contours[i])
{
mapped.emplace_back(cvRound(pt.x * pin_scale_x),
cvRound(pt.y * pin_scale_y));
}
m_tplPinContours.push_back(mapped);
}
// 保存模板外接矩形
m_tplOuterRect = tplOuterRect;
// 绘制到 tplImg 上
{
Mat showImg = pinImg.clone();
cv::drawContours(pinImg, m_tplPinContours, -1, Scalar(0, 255, 0), 2);
cv::imwrite("/home/aidlux/BOE/ZB_PLATE/Tpl/tpl_pin_contours.png", pinImg);
}
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "---Init Tpl---" , "end"); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "---Init Tpl---" , "end");
return 0; return 0;

@ -602,15 +602,14 @@ int CameraCheckAnalysisy::Init(std::string strcameraName)
return 0; return 0;
} }
void CameraCheckAnalysisy::SetTplInfo(const cv::RotatedRect &outerRect, void CameraCheckAnalysisy::SetTplInfo(const cv::RotatedRect &outerRect)
const std::vector<std::vector<cv::Point>> &pinContours)
{ {
for (int i = 0; i < IMGCHECKANALYSISY_NUM; i++) for (int i = 0; i < IMGCHECKANALYSISY_NUM; i++)
{ {
auto *p = static_cast<ImgCheckAnalysisy *>(m_pImgCheckAnalysisy[i]); auto *p = static_cast<ImgCheckAnalysisy *>(m_pImgCheckAnalysisy[i]);
if (p) if (p)
{ {
p->SetTplInfo(outerRect, pinContours); p->SetTplInfo(outerRect);
} }
} }
} }

@ -20,7 +20,6 @@ static bool compareContourAreas(const vector<Point> &contour1, const vector<Poin
} }
ImgCheckAnalysisy::ImgCheckAnalysisy() ImgCheckAnalysisy::ImgCheckAnalysisy()
: m_pAI_Edge_Algin(m_pdetlog) : m_pAI_Edge_Algin(m_pdetlog)
, m_Pin_QX_Det(m_pdetlog)
{ {
m_nErrorCode = CHECK_OK; m_nErrorCode = CHECK_OK;
@ -210,11 +209,9 @@ int ImgCheckAnalysisy::creatsavedir()
return 0; return 0;
} }
void ImgCheckAnalysisy::SetTplInfo(const cv::RotatedRect &outerRect, void ImgCheckAnalysisy::SetTplInfo(const cv::RotatedRect &outerRect)
const std::vector<std::vector<cv::Point>> &pinContours)
{ {
m_tplOuterRect = outerRect; m_tplOuterRect = outerRect;
m_tplPinContours = pinContours;
} }
int ImgCheckAnalysisy::LoadRunConfig(void *p) int ImgCheckAnalysisy::LoadRunConfig(void *p)
@ -469,53 +466,14 @@ int ImgCheckAnalysisy::CheckRun()
long time_edge_e = CheckUtil::getcurTime(); long time_edge_e = CheckUtil::getcurTime();
m_pdetlog->AddCheckstr(PrintLevel_0, "2、pre detect", "-------------------------AI_Edge------------succ---time %ld----\n", time_edge_e - time_edge_s); m_pdetlog->AddCheckstr(PrintLevel_0, "2、pre detect", "-------------------------AI_Edge------------succ---time %ld----\n", time_edge_e - time_edge_s);
// 计算内外边缘夹角
float aouter = CheckUtil::getLongAxisAngle(m_outer_rroi);
float ainner = CheckUtil::getLongAxisAngle(m_inner_rroi);
float diff_align = std::fabs(aouter - ainner);
diff_align = std::fmod(diff_align, 180.0f); // 模 180 度
// 两条直线的夹角取锐角min(diff, 180 - diff)
if (diff_align > 90.0f)
{
diff_align = 180.0f - diff_align;
}
// 如果diff_align大于10则添加到缺陷列表
if (diff_align > 10.0f)
{
QX_ERROR_INFO_ alignErr;
alignErr.Idx = static_cast<int>(m_pDetResult->pQx_ErrorList->size());
// roi 用整张检测图区域detImg 坐标系)
cv::Rect tplRect = m_tplOuterRect.boundingRect();
alignErr.roi = cv::Rect(0, 0, tplRect.width, tplRect.height);
alignErr.area = alignErr.roi.width * alignErr.roi.height;
alignErr.JudgArea = alignErr.area * m_fImgage_Scale_X * m_fImgage_Scale_Y;
alignErr.flen = tplRect.width * m_fImgage_Scale_X;
alignErr.fbreadth = tplRect.height * m_fImgage_Scale_Y;
alignErr.nconfig_qx_type = CONFIG_QX_NAME_cell_zangwu;
alignErr.qx_name = CONFIG_QX_NAME_Names[CONFIG_QX_NAME_cell_zangwu];
alignErr.grayDis = diff_align; // 记录内外边缘夹角(度)
alignErr.detRegionidxList.push_back(0);
alignErr.detlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Align Check",
"outer-inner angle diff %.2f deg", diff_align);
m_pDetResult->pQx_ErrorList->push_back(alignErr);
m_pdetlog->AddCheckstr(PrintLevel_0, "Align Check", "angle diff %.2f deg > 10", diff_align);
}
/*投影对齐模板*/ /*投影对齐模板*/
Adapt_Config(m_tplOuterRect, m_outer_rroi, m_CheckResult_shareP->in_shareImage->img); // Adapt_Config(m_tplOuterRect, m_outer_rroi, m_CheckResult_shareP->in_shareImage->img);
m_outer_roi = m_tplOuterRect.boundingRect(); m_outer_roi = m_outer_rroi.boundingRect();
m_Crop_Roi_paramImg = m_outer_roi; m_Crop_Roi_paramImg = m_outer_roi;
m_pImageAllResult->pDetResult->CutRoi = m_outer_roi; m_pImageAllResult->pDetResult->CutRoi = m_outer_roi;
m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg; m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg;
long time_calan_e = CheckUtil::getcurTime(); long time_calan_e = CheckUtil::getcurTime();
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect", "-------------------------CalAndAffine------------succ---time %ld----\n", time_calan_e - time_edge_s); m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect", "-------------------------Adapt_Config------------succ---time %ld----\n", time_calan_e - time_edge_s);
/*生成 检测的图片*/ /*生成 检测的图片*/
cv::Mat image; cv::Mat image;
@ -536,18 +494,18 @@ int ImgCheckAnalysisy::CheckRun()
ImgPreDet(); ImgPreDet();
/*更新检测区域*/ /*更新检测区域*/
// Update_DetRoiList(); Update_DetRoiList();
m_pdetlog->AddCheckstr(PrintLevel_0, "3、pre detect", "-------------------------pre Det--------------- \n"); m_pdetlog->AddCheckstr(PrintLevel_0, "3、pre detect", "-------------------------pre Det--------------- \n");
/*实现PIN脚检测*/ /* 检测支架偏移 */
{ // 分析m_inner_rroi
long t41 = CheckUtil::getcurTime();
int reedge1111 = Pin_Qx_Det(m_pImageAllResult->detImg); /* Tag检测 */
long t42 = CheckUtil::getcurTime();
m_pdetlog->AddCheckstr(PrintLevel_0, "4、detect", "-------------------------1、Pin_Qx_Det--------%ld-------\n", t42 - t41);
}
m_CheckResult_shareP->nresult = 0; m_CheckResult_shareP->nresult = 0;
/*把临时可以绘制的结果都绘制出来。*/ /*把临时可以绘制的结果都绘制出来。*/
@ -1730,27 +1688,6 @@ int ImgCheckAnalysisy::DrawResult_Step_1()
float fs_resize_x = m_pImageAllResult->resultImg.cols * 1.0f / m_pImageAllResult->detImg.cols; float fs_resize_x = m_pImageAllResult->resultImg.cols * 1.0f / m_pImageAllResult->detImg.cols;
float fs_resize_y = m_pImageAllResult->resultImg.rows * 1.0f / m_pImageAllResult->detImg.rows; float fs_resize_y = m_pImageAllResult->resultImg.rows * 1.0f / m_pImageAllResult->detImg.rows;
// 绘制模板 pin 轮廓(绿色)与当前 pin 轮廓(红色)
for (const auto &contour : m_tplPinContours)
{
std::vector<cv::Point> draw_pts;
draw_pts.reserve(contour.size());
for (const auto &pt : contour)
{
draw_pts.emplace_back(cvRound(pt.x * fs_resize_x), cvRound(pt.y * fs_resize_y));
}
cv::polylines(m_CheckResult_shareP->resultimg, draw_pts, true, cv::Scalar(255, 255, 0), 1);
}
for (const auto &contour : m_curPinContours)
{
std::vector<cv::Point> draw_pts;
draw_pts.reserve(contour.size());
for (const auto &pt : contour)
{
draw_pts.emplace_back(cvRound(pt.x * fs_resize_x), cvRound(pt.y * fs_resize_y));
}
cv::polylines(m_CheckResult_shareP->resultimg, draw_pts, true, cv::Scalar(255, 0, 255), 1);
}
// 绘制m_inner_rroi蓝色 // 绘制m_inner_rroi蓝色
{ {
@ -1862,173 +1799,6 @@ int ImgCheckAnalysisy::UpdateImgageScale()
return 0; return 0;
} }
int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img)
{
m_Edge_DetConfig.Init();
m_Edge_DetConfig.strChannel = m_strCurDetChannel;
m_Edge_DetConfig.pBaseCheckFunction = m_pbaseCheckFunction;
m_Edge_DetConfig.bSaveResultImg = false;
if (DetImgInfo_shareP->bsaveProcessImg)
{
m_Edge_DetConfig.bSaveResultImg = true;
}
// m_pbaseCheckFunction->print("Pin_Qx_Det");
Mat pin_mask;
int re = m_Pin_QX_Det.GetPinMask(img, &m_Edge_DetConfig, pin_mask);
// 统计tplPinMask的blob边缘点并绘制到tplImg上
vector<vector<Point>> pin_contours;
vector<Vec4i> hierarchy;
cv::findContours(pin_mask, pin_contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
//缩放比例
const float pin_scale_x = (pin_mask.cols > 0) ? static_cast<float>(img.cols) / pin_mask.cols : 0.0f;
const float pin_scale_y = (pin_mask.rows > 0) ? static_cast<float>(img.rows) / pin_mask.rows : 0.0f;
// 将轮廓点从 mask 坐标系 映射回 tplImg 坐标系
m_curPinContours.clear();
m_curPinContours.reserve(pin_contours.size());
for (size_t i = 0; i < pin_contours.size(); i++)
{
std::vector<cv::Point> mapped;
mapped.reserve(pin_contours[i].size());
for (const auto &pt : pin_contours[i])
{
mapped.emplace_back(cvRound(pt.x * pin_scale_x),
cvRound(pt.y * pin_scale_y));
}
m_curPinContours.push_back(mapped);
}
// 根据模板Pin和当前Pin轮廓进行对比判断当前有无缺失和偏移
{
// 计算轮廓中心点(外接矩形中心)
auto getCenter = [](const std::vector<cv::Point> &contour) -> cv::Point2f
{
cv::Rect r = cv::boundingRect(contour);
return cv::Point2f(r.x + r.width * 0.5f, r.y + r.height * 0.5f);
};
const int nTpl = static_cast<int>(m_tplPinContours.size());
const int nCur = static_cast<int>(m_curPinContours.size());
if (nTpl > 0)
{
// 1、统计模板 pin 中心与平均最小边长,用于自适应阈值
std::vector<cv::Point2f> tplCenters(nTpl);
double sumMinDim = 0.0;
for (int i = 0; i < nTpl; i++)
{
tplCenters[i] = getCenter(m_tplPinContours[i]);
cv::Rect r = cv::boundingRect(m_tplPinContours[i]);
sumMinDim += (r.width < r.height) ? r.width : r.height;
}
const float avgMinDim = static_cast<float>(sumMinDim / nTpl);
// 偏移阈值约 1/4 个 pin 尺寸,缺失阈值约 3/4 个 pin 尺寸
float offsetTh = avgMinDim * 0.5f;
if (offsetTh < 3.0f)
{
offsetTh = 3.0f;
}
float missTh = avgMinDim * 0.75f;
if (missTh < offsetTh + 1.0f)
{
missTh = offsetTh + 1.0f;
}
// 2、当前 pin 中心
std::vector<cv::Point2f> curCenters(nCur);
for (int i = 0; i < nCur; i++)
{
curCenters[i] = getCenter(m_curPinContours[i]);
}
std::vector<bool> curUsed(nCur, false);
// 上报缺失/偏移缺陷(缺陷类型可按需调整)
auto reportPinError = [&](int pinIdx, const cv::Point2f &tplCenter, const std::string &reason)
{
QX_ERROR_INFO_ pinErr;
pinErr.Idx = static_cast<int>(m_pDetResult->pQx_ErrorList->size());
cv::Rect r = cv::boundingRect(m_tplPinContours[pinIdx]);
pinErr.roi = r;
pinErr.area = static_cast<int>(cv::contourArea(m_tplPinContours[pinIdx]));
pinErr.JudgArea = pinErr.area * m_fImgage_Scale_X * m_fImgage_Scale_Y;
int longSide = (r.width > r.height) ? r.width : r.height;
int shortSide = (r.width < r.height) ? r.width : r.height;
pinErr.flen = longSide * m_fImgage_Scale_X;
pinErr.fbreadth = shortSide * m_fImgage_Scale_Y;
pinErr.nconfig_qx_type = CONFIG_QX_NAME_cell_ymhs;
pinErr.qx_name = CONFIG_QX_NAME_Names[CONFIG_QX_NAME_cell_ymhs];
pinErr.detRegionidxList.push_back(0);
pinErr.detlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Pin Check",
"pin %d center(%d,%d) %s",
pinIdx, static_cast<int>(tplCenter.x), static_cast<int>(tplCenter.y),
reason.c_str());
m_pDetResult->pQx_ErrorList->push_back(pinErr);
};
int nMiss = 0;
int nOffset = 0;
// 3、逐个模板 pin 找最近且未被占用的当前 pin
for (int i = 0; i < nTpl; i++)
{
int bestIdx = -1;
double bestDist = 1e12;
for (int j = 0; j < nCur; j++)
{
if (curUsed[j])
{
continue;
}
float dx = tplCenters[i].x - curCenters[j].x;
float dy = tplCenters[i].y - curCenters[j].y;
double d = std::sqrt(static_cast<double>(dx) * dx + static_cast<double>(dy) * dy);
if (d < bestDist)
{
bestDist = d;
bestIdx = j;
}
}
// 无候选或距离过远 -> 缺失
if (bestIdx < 0 || bestDist > missTh)
{
nMiss++;
reportPinError(i, tplCenters[i], "miss");
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "pin %d MISS", i);
continue;
}
curUsed[bestIdx] = true;
// 距离超出偏移阈值 -> 偏移
if (bestDist > offsetTh)
{
nOffset++;
char buf[64];
snprintf(buf, sizeof(buf), "offset %.1fpx", bestDist);
reportPinError(i, tplCenters[i], buf);
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "pin %d OFFSET %.1fpx", i, bestDist);
}
}
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "tpl %d cur %d miss %d offset %d", nTpl, nCur, nMiss, nOffset);
}
}
if (m_Edge_DetConfig.bSaveResultImg)
{
Mat showimg;
cv::cvtColor(img, showimg, cv::COLOR_GRAY2BGR);
cv::drawContours(showimg, m_curPinContours, -1, cv::Scalar(0, 0, 255), 1);
cv::drawContours(showimg, m_tplPinContours, -1, cv::Scalar(0, 255, 0), 1);
imwrite("pin_contours.png", showimg);
}
return 0;
}
int ImgCheckAnalysisy::BLobToDetResult() int ImgCheckAnalysisy::BLobToDetResult()
{ {

@ -1,49 +0,0 @@
#include "Pin_QX_Det.h"
#include "CheckUtil.hpp"
#include <numeric>
#include <random>
#include "CheckErrorCodeDefine.hpp"
Pin_QX_Det::Pin_QX_Det(std::shared_ptr<DetLog> &log_ref)
: m_pdetlog(log_ref)
{
std::string m_strSavePath;
AI_Factory = AIFactory::GetInstance();
}
Pin_QX_Det::~Pin_QX_Det()
{
}
int Pin_QX_Det::GetPinMask(const cv::Mat &img, DetConfigResult *pDetConfig, Mat &mask)
{
std::shared_ptr<AIModel_Base> pBackPlate_Pin;
pBackPlate_Pin = AI_Factory->Pin_Loc;
cv::Size sz;
sz.width = pBackPlate_Pin->input_0.width;
sz.height = pBackPlate_Pin->input_0.height;
cv::Mat detImg;
cout<< pDetConfig->strChannel << ": " << "---Pin---";
cout << "imgSize: " << img.size() << ", " << "detImgSize: " << detImg.size() << ", " << "szSize: " << sz << endl;
cv::resize(img, detImg, sz);
int re = 0;
if (detImg.channels() != 1)
{
cv::cvtColor(detImg, detImg, cv::COLOR_RGB2GRAY);
}
re = pBackPlate_Pin->AIDet(detImg, mask);
if (re != 0)
{
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AI_Pin ", "AICheck_Pin----error %d ", re);
int re123 = 100 + re;
return re123;
}
if (pDetConfig->bSaveResultImg)
{
cv::imwrite(pDetConfig->strChannel +"_pin_" +"in.png", detImg);
cv::imwrite(pDetConfig->strChannel +"_pin_" +"out_mask.png", mask);
}
}

@ -212,24 +212,26 @@ std::string Extract_ALL::Extract_Channel_Name(std::string strPath, int userflag)
} }
int Extract_ALL::Read_Image_List(std::string strPath, std::string strproduct) int Extract_ALL::Read_Image_List(std::string strPath, std::string strproduct)
{ {
std::string strSearchImgPath = strPath + "/*.bmp"; std::vector<std::string> vecExt = {".bmp", ".png", ".jpg", ".jpeg", ".tif", ".tiff"};
Read_Camera_Product_Image(strSearchImgPath, 0, strproduct); for (size_t i = 0; i < vecExt.size(); i++)
{
// strSearchImgPath = strPath + "/*.png"; std::string strSearchImgPath = strPath + "/*" + vecExt[i];
// Read_Camera_Product_Image(strSearchImgPath, 1); Read_Camera_Product_Image(strSearchImgPath, 0, strproduct);
}
return 0; return 0;
} }
int Extract_ALL::Read_Image_List(std::string strPath_left, std::string strPath_right, std::string strproduct) int Extract_ALL::Read_Image_List(std::string strPath_left, std::string strPath_right, std::string strproduct)
{ {
std::string strSearchImgPath = strPath_left + "/*.bmp"; std::vector<std::string> vecExt = {".bmp", ".png", ".jpg", ".jpeg", ".tif", ".tiff"};
Read_Camera_Product_Image(strSearchImgPath, 0, strproduct); for (size_t i = 0; i < vecExt.size(); i++)
strSearchImgPath = strPath_right + "/*.bmp"; {
Read_Camera_Product_Image(strSearchImgPath, 0, strproduct); std::string strSearchImgPath = strPath_left + "/*" + vecExt[i];
Read_Camera_Product_Image(strSearchImgPath, 0, strproduct);
// strSearchImgPath = strPath + "/*.png"; strSearchImgPath = strPath_right + "/*" + vecExt[i];
// Read_Camera_Product_Image(strSearchImgPath, 1); Read_Camera_Product_Image(strSearchImgPath, 0, strproduct);
}
return 0; return 0;
} }

Loading…
Cancel
Save