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.

334 lines
11 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.

/*
* @Author: your name
* @Date: 2022-04-20 15:49:50
* @LastEditTime: 2025-09-17 19:49:41
* @LastEditors: xiewenji 527774126@qq.com
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
*/
#ifndef ImgCheckAnalysisy_H_
#define ImgCheckAnalysisy_H_
#include <iostream>
#include <stdio.h>
#include <sys/time.h>
#include <opencv2/opencv.hpp>
#include <condition_variable>
#include <mutex>
#include <vector>
#include <thread>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "BlobBase.h"
#include "ImgCheckBase.h"
#include "ImageDetBase.h"
#include "ImgCheckConfig.h"
#include "CheckErrorCodeDefine.hpp"
#include "CheckConfigDefine.h"
#include "ConfigBase.h"
#include "ImageDetConfig.h"
#include "OtherDetect.h"
#include "Define_Error.h"
#include "Pin_QX_Det.h"
#include "AI_Edge_Algin.h"
#include "AI_Factory.h"
#include "ImageAllResult.h"
#include "Task.h"
using namespace std;
using namespace cv;
enum AT_THRESHOLD_TYPE_
{
AT_THRESHOLD_TYPE_NULL,
AT_THRESHOLD_TYPE_READY,
AT_THRESHOLD_TYPE_BUSY,
AT_THRESHOLD_TYPE_COMPLETE,
};
// 全局静态变量, 记录图像灰度值异常累计数量
static int g_nImgBrightnessErrorCount = 0;
class ImgCheckAnalysisy : public ImgCheckBase
{
public:
ImgCheckAnalysisy();
~ImgCheckAnalysisy();
// 初始化参数 pconfig 参数指针 返回:0 成功 其他异常
int RunStart(void *pconfig1);
// 设置检测数据,并开启检测 返回:0 成AT_THRESHOLD_TYPE_READY功 其他异常
int SetDataRun_SharePtr(std::shared_ptr<ImageAllResult> p);
// 获取结果信息 返回:0 成功 其他异常
int GetCheckReuslt(std::shared_ptr<ImageDetResult> &pResult);
int CheckImg(std::shared_ptr<ImageDetconfig> p, std::shared_ptr<ImageDetResult> &pResult);
int ReJsonResul(std::shared_ptr<ImageDetconfig> p, std::shared_ptr<ImageDetResult> &pResult);
// 获取检测库 状态信息 返回:CHECK_THREAD_RUN_STATUS
int GetStatus();
// 更新参数 pconfig 参数指针,nConfigType 需要更新的参数类型 返回:0 成功 其他异常
int UpdateConfig(void *pconfig, int nConfigType);
std::string GetVersion();
std::string GetErrorInfo();
int creatsavedir();
// 设置模板信息(模板外接矩形 + 模板内边缘矩形 + 模板 pin blob 轮廓点集)
void SetTplInfo(const cv::RotatedRect &outerRect,
const cv::RotatedRect &innerRect,
const std::vector<std::vector<cv::Point>> &pinContours);
private:
// 加载运行参数
int LoadRunConfig(void *p);
// 加载分析参数
int LoadCheckConfig(void *p);
/// @brief 初始化并且启动程序
/// @return
int InitRun(int nId);
/// @brief 开启检测
/// @return
int StartCheck();
/// @brief 设置空闲
/// @return
int SetIDLE();
private:
// 开启线程
int StartThread(int nId);
// 停止线程
int StopThread();
// 退出系统
int ExitSystem();
// 初始化模型
int InitModel();
cv::Scalar calc_blob_info_withstats(cv::Mat &img, const cv::Mat &mask, cv::Rect &stats, cv::Size k_size = cv::Size(5, 5), int expand = 10, double threshold = 0.7);
// 检测
int CheckRun();
int AI_Edge(const cv::Mat &img, cv::RotatedRect &outerRoi, cv::RotatedRect &innerRoi);
// 计算产品尺寸
int CalProductSize();
// 图片预处理
int ImgPreDet();
// 图像模糊度(清晰度)检测: 在 AI 检测之前执行, 返回 1 表示图像模糊(判 NG), 0 正常
int BlurCheck(const cv::Mat &img);
// 设置新的检测参数
int SetNewConfig();
ChannelCheckFunction *GetChannelFuntion(std::string strChannelName); // 获得 通道的检测功能
private:
// 图片处理线程
std::shared_ptr<std::thread> ptr_thread_Run;
int Run(int nId); // 运行;
// 图片处理线程
std::shared_ptr<std::thread> ptr_thread_AI;
int set_cpu_id(const std::vector<int> &cpu_set_vec);
// 计算BLob 其他一些属性值。
int CalBlob_Other();
// 分类
int GetClassImg(const cv::Mat &img, cv::Mat &AIdetImg, cv::Rect qx_roi, int detwidth, int detheight);
// 计算缺陷长度
vector<float> Cal_QXLen(cv::Mat qx_maskImg, int qx_type, float fsc_x, float fsc_y);
// 获取检测结果blob,用于后续分析。
int GetCheckResultBLob();
// 获得所有blob
int GetALLBlob();
// 对AI mask图片进行 结果处理
int AIMaskDet();
// 轮廓处理
int Contours();
// 检测初始化
int CheckImgInit();
// 参数 核对
int ConfigCheck(cv::Mat img);
// 多线程方式处理
int AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg);
// 缺陷分类
int AI_QX_Class_Thread();
// 多线程 任务运行管理器
int ThreadTask(int nId); // 运行;
// resize 图片
int ResizeImg();
// AI 推理任务函数
void TaskFun_AIDet(std::shared_ptr<TaskInfo> task);
// 缺陷分类任务函数
void TaskFun_QxClass(std::shared_ptr<TaskInfo> task);
// 更新 检测区域
int Update_DetRoiList();
// 临时绘制结果
int DrawResult_Step_1();
// 参数缺陷类型转 结果参数类型
int AIClassTypeToConfigType(int nAIQXType);
// 更新成像精度
int UpdateImgageScale();
// 边缘缺陷检测
int Pin_Qx_Det(const cv::Mat &img);
// 当前 Pin 检测方案是否为"直接分析"(参数 pinDet.Det_Method == "line_fitting")
bool IsDirectPinMethod() const;
// 当前 Pin 检测方案是否为"Pin 投影矩阵"(参数 pinDet.Det_Method == "Pin_Matrix")
bool IsPinMatrixMethod() const;
// 新方案: 不做模板对比, 只分析检测Pin: 自动分两排(考虑旋转) -> 拟合直线判偏移 + 相邻间距判缺失
int Pin_Direct_Check();
// Pin_Matrix 方案: 用当前帧 Pin 拟合投影矩阵(上下两排分别计算相似变换), 把模板 Pin 投影到当前检测图坐标系
int ComputePinProjectionMats();
// Pin_Matrix 方案: 过滤当前帧上明显的误检 pin blob(按模板 pin 的包围盒尺寸)
int FilterCurPinBlobsByTplSize();
// 把blob 汇总成 检测结果。
int BLobToDetResult();
// 获取指定 残点(blob) 是由哪个(哪些)检测模型检出的
std::string GetBlobModelName(const cv::Rect &roi);
// 计算 当前图 -> 模板图 / 模板图 -> 当前图 的仿射矩阵(基准矩形可为内定位/外定位)
// 注意: 不再对原图做 warpAffine, 只做坐标变换
int CalAffineMats(const cv::RotatedRect &tplRefRect, const cv::RotatedRect &curRefRect);
// 把模板 Pin 轮廓(pinImg 裁剪坐标系)反变换到当前检测图(detImg)坐标系
int TransformTplPinContoursToCur();
std::shared_ptr<AIFactory> AI_Factory;
private:
int m_nErrorCode; // 错误代码
bool m_bInitSucc; // 初始化状态
bool m_bExit; // 是否退出检测
int m_nThreadIdx; // 线程序号 //相机处理的顺序号,该序号 程序运行就已经固定
std::shared_ptr<AIMulThreadRunBase> runner;
// 所有的检测结果
std::shared_ptr<ImageAllResult> m_pImageAllResult;
std::shared_ptr<DetLog> m_pdetlog;
std::shared_ptr<One_Image_CheckResult_> m_pDetResult; // 检测结果 后续主要对pDetResult 继续分析
std::shared_ptr<shareImage> DetImgInfo_shareP;
// 检测结果
std::shared_ptr<CheckResult> m_CheckResult_shareP;
// 检测参数模块
ConfigBase *m_pConfig;
bool m_bupdateconfig;
int m_nConfigIdx;
// 线程运行的一些参数
RunInfoST m_RunConfig;
float m_fImgage_Scale_X;
float m_fImgage_Scale_Y;
// 分析参数
AnalysisyConfigST m_AnalysisyConfig;
ChannelCheckFunction *m_pFuntion;
BaseCheckFunction *m_pbaseCheckFunction; // 基础检测
CommonConfigNodeST *m_pCommonAnalysisyConfig;
BasicConfig *m_pBasicConfig;
RegionConfigST *m_pRegionAnalysisyParam; // 分析参数
int m_QxInParamListIdx[CONFIG_QX_NAME_count];
cv::Rect m_outer_roi;
cv::Rect m_inner_roi;
cv::Rect m_Crop_Roi_paramImg; // 裁切在参数模板图上的 位置。
std::string m_strCurDetChannel; // 当前处理的图片通道
// // 检测控制参数
// CheckControlConfigSt *m_pcheckControlConfig;
int m_nRun_Status; // 运行状态:空闲,运行中,异常,。。。。。
int m_nCheckResultErrorCode;
Detect_ROI_Config m_DetRoiList; // 检测区域roi List
ERROR_DOTS_BLOBS blobs;
OtherDet_Config m_OtherDet_Config;
AI_Edge_Algin m_pAI_Edge_Algin;
// 边缘定位结果
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<cv::Rect> SmallRoiList;
std::string m_strRootPath_KK_cls;
std::string m_strSavePath_cls;
std::string m_strLastDate;
ImageStorage *m_pImageStorage;
// AI 推理的所有结果, 可能会返回去。需要临时存储。
std::queue<std::shared_ptr<AIMulThreadRunBase::AITask>> m_AIMaskImgBLobQueue;
std::mutex mtx_AIMaskImgBLobQueue;
Task m_task;
std::shared_ptr<TaskInfo> m_AItask;
std::shared_ptr<TaskInfo> m_Classtask; // 缺陷分类任务
// AI mask 在这一列是否有 缺陷残点,用以 加速 blob 分析。
unsigned char *m_ImgBlobHFlagData;
// 原始区域数据
Rect m_old_productROI = Rect(0, 0, 0, 0);
std::vector<cv::Point> m_old_cur_edgeDet_region;
std::vector<cv::Point> m_old_cur_markLine_region;
cv::Point m_old_cur_markLine_mark1;
cv::Point m_old_cur_markLine_mark2;
std::vector<RegionConfigST> m_old_cur_regionConfigArr;
// 模板信息
cv::RotatedRect m_tplOuterRect; // 模板外接矩形
cv::RotatedRect m_outer_rroi;
cv::RotatedRect m_inner_rroi;
cv::RotatedRect m_tplInnerRect; // 模板内边缘矩形
std::vector<std::vector<cv::Point>> m_tplPinContours; // 模板 pin blob 轮廓点集(pinImg 裁剪坐标系)
std::vector<std::vector<cv::Point>> m_tplPinContoursCur; // 模板 pin 轮廓(反变换到当前检测图坐标系)
std::vector<std::vector<cv::Point>> m_curPinContours; // 当前 pin blob 轮廓点集
cv::Mat m_affine_cur2tpl; // 当前图 -> 模板图
cv::Mat m_affine_tpl2cur; // 模板图 -> 当前图
bool m_bAffineValid = false; // 仿射矩阵是否有效
std::vector<std::pair<cv::Point2f, cv::Point2f>> m_pinFitLines; // 新方案: 两排Pin拟合直线段(当前检测图坐标系, 两端点)
std::vector<cv::Point2f> m_pinMissMarks; // 新方案: 缺失Pin位置(相邻Pin中心连线中点)
};
#endif