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.

138 lines
4.1 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.

#ifndef _TCSCHECK_H
#define _TCSCHECK_H
#include <thread>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <sys/stat.h> // 必需mkdir 函数声明
#include <sys/types.h> // 可选:通常被 sys/stat.h 包含,但建议显式包含
#include "TcsConfig.h"
#include <opencv2/opencv.hpp>
struct CHECK_PARAM{
int nAreaLowFilter; // low filter of the product area
int nDiscardTop; //Discard top edge width of the effective area
int nDiscardBottom; //Discard bottom edge width of the effective area
int nDiscardLeft; //Discard left edge width of the effective area
int nDiscardRight; //Discard right edge width of the effective area
float fZoomRatio; // scaling ratio of the source image
int nFilterLow; // low threshold of the filter
int nFilterHigh; // high threshold of the filter
int nBlockSize; // the size of the block
int nAreaFilter; // blob filter for drawing, only draw blob with area >= nAreaFilter
int nCountFilter; // blob filter for counting, Only the first nCountFilters with areas arranged from largest to smallest
};
/*
长宽比 >= 3 ?
├─ 是 → SCRATCH (划伤)
└─ 否(紧凑形状):
├─ area < 大块阈值 → POINT (点型,不论黑白)
└─ area >= 大块阈值:
├─ greyDiff < 0 → DIRTY (黑色大块脏污)
└─ greyDiff > 0 → FADING_SPOTS (白色大块淡斑)
*/
enum DEFECT_TYPE_DEFINE{
DEFECT_TYPE_OK = 0,
DEFECT_TYPE_POINT = 1,
DEFECT_TYPE_SCRATCH = 2, // white line
DEFECT_TYPE_DIRTY = 3,
DEFECT_TYPE_FADING_SPOTS = 4
};
inline const std::string DEFECT_TYPE_CODE[5] = {
"P0000",
"MA505",
"MA506",
"MA504",
"P0003"
};
inline const std::string DEFECT_TYPE_DESC[5] = {
"OK",
"硬质颗粒",
"划伤",
"脏污",
"淡斑"
};
struct DEFECT_INFO{
int nDefectType;
int nDefectArea;
int nDefectX;
int nDefectY;
int nDefectWidth;
int nDefectHeight;
double dGreyDiff; // 灰阶差blob均值 - 所属局部块均值
std::string strDefectCode;
std::string strDefectDesc;
};
class CTcsCheck{
public:
int m_nInitStart;
int m_bSystemExit;
CHECK_PARAM m_cpCfg;
int m_nInitEnd;
pthread_mutex_t m_mutex;
std::vector<cv::String> m_fileList;
std::vector<DEFECT_INFO> m_vecDefectInfo;
CTcsCheck();
~CTcsCheck();
void SetCheckDir(std::string dirIn,std::string dirOut);
void SetChecConfig(CHECK_PARAM* cp);
void ProcessImages(bool bDrawResult);
// ========== 独立检测/分类接口 ==========
// 传统检测,输出残点二值图 0=成功, -1=无产品/输入为空
int TraditionalDetect(const cv::Mat& img, cv::Rect detRoi, cv::Mat& blobImg);
// 传统分类,结果写入 m_vecDefectInfo
int TraditionalClassify(const cv::Mat& blobImg);
private:
std::string m_strDirIn;
std::string m_strDirOut;
cv::Mat m_matLoad;
cv::Mat m_matBlob;
cv::Mat m_matBlur; // 模糊图,供 TraditionalClassify 使用
cv::Mat m_matDraw;
cv::Size m_sizeImage;
std::string m_strCurFile;
bool CreateDirectories(std::string path, mode_t mode = 0755) ;
void LoadImages();
std::string GetFileName(const std::string& path) const;
cv::Rect GetBoundingRect(cv::Mat matBinary);
cv::Rect GetCropArea(cv::Rect rtValid);
cv::Mat AdaptiveBinary(cv::Mat matBlur);
void Process(bool bDraw = false);
// 纯分类:对二值图做连通域分析+缺陷分类,结果写入 m_vecDefectInfo
void ClassifyBlobs(const cv::Mat& blurCrop, const cv::Mat& imgBlob);
// 纯绘制:基于 m_vecDefectInfo 绘制缺陷标注
cv::Mat DrawBlobInfoImage(const cv::Mat& imgCrop, const cv::Mat& imgBlob);
void DetectWithAdaptiveBinary(bool bDraw = false);
void DetectWithAdaptiveBinaryOptimized(bool bDraw = false);
void DetectWithDoH(bool bDraw = false, double dSigma = 1.0 ,int nThreshold = 50);
void DetectWithLoG(bool bDraw = false, double dSigma = 1.0, int nThreshold = 50);
};
#endif