/* * @Descripttion: * @version: * @Author: sueRimn * @Date: 2022-04-28 10:41:42 * @LastEditors: xiewenji 527774126@qq.com * @LastEditTime: 2025-08-03 21:32:02 */ /* * FileName:CoreLogicFactory.hpp * Version:V1.0 * Description: * Created On:Mon Sep 10 11:13:13 UTC 2018 * Modified date: * Author:Sky */ #ifndef _CheckUtil_HPP_ #define _CheckUtil_HPP_ #include #include #include #include #include #include #include #include using namespace std; // 掩膜主体(圆角矩形)外的凸起区域(如把手)的描述 struct Mask_Protrusion_ { int nCorner; // 就近角(产品主轴坐标系):0 左上 1 右上 2 左下 3 右下 cv::Rect roi; // 凸起外接矩形(输入图坐标系,已裁剪到图像范围内) cv::Point2f ptCenter; // 凸起质心(输入图坐标系) float fAngle; // 边缘倾角(度,日志排查用) float fLen; // 凸起外接矩形长边(像素) float fDepth; // 凸起相对主体直边的最大伸出深度(像素) float fArea; // 凸起面积(掩膜像素数) float fFillRatio; // 凸起外接矩形内掩膜像素占比 Mask_Protrusion_() { nCorner = 0; ptCenter = cv::Point2f(0.0f, 0.0f); fAngle = 0.0f; fLen = 0.0f; fDepth = 0.0f; fArea = 0.0f; fFillRatio = 0.0f; } }; class CheckUtil { public: static long getcurTime(); static std::string getCurrentDate(); static std::string getCurTimeHMS(); static std::string Op_float2String(float nvalue); static int64_t getSnowId(); // 当前日期(年月日, 8 位纯数字), 形如 "20261029", 便于存图文件名检索/排序 static std::string getCurrentDateYMD(); // 生成不重名的存图完整路径 = strDir + strPrefix + [ "_序号" ] + "_" + strName + strExt static std::string GetUniqueImgPath(const std::string &strDir, const std::string &strPrefix, const std::string &strName, const std::string &strExt); static bool JudgRect(cv::Rect roi, int img_w, int img_h); static bool JudgRect_SZ(cv::Rect roi, int w, int h); static bool compareIgnoreCase(const std::string &str1, const std::string &str2); static bool RoiInImg(cv::Rect roi, cv::Mat img); static int printROI(cv::Rect roi, std::string str = ""); static float CalIoU(cv::Rect rect1, cv::Rect rect2); static float CalIoU_t(cv::Rect rect1, cv::Rect rect2); static int CheckRect(cv::Rect &roi, int img_w, int img_h); static int SizeRect(cv::Rect &roi, int img_w, int img_h, int addw, int addh); static int CalHj(const cv::Mat &img, const cv::Mat &mask,int b_value); static int CalHj(const cv::Mat &img, const cv::Mat &mask,const cv::Mat &backgroundimg); static int CalHjWeighted(const cv::Mat &img, const cv::Mat &mask, int b_value, float power = 2.0f); // 计算平均灰度 static float CalImgBrightness(cv::Mat imgRoi); // 计算角度 static float Cal2PointAngle(cv::Point p_left, cv::Point p_right); // 获取 RotatedRect 长轴的方向角(归一化到 [0, 180) 度) static float getLongAxisAngle(const cv::RotatedRect rect); // 排序RotatedRect的四个顶点 static std::vector sort_vertices(cv::RotatedRect rrect); // 找图片的最大外轮廓 static std::vector getLargestContourROI(const cv::Mat &binaryImg, bool &found); // 从外轮廓掩膜(outer定位mask)中分离凸起区域(如把手): // 主体是圆角矩形、把手基本出现在四角附近:逐行/逐列扫描掩膜边界,为每条边缘搜索带内点数最多的直线; // 掩膜中超出四条边缘(超过容差带)的像素按连通域切分成凸起区域(含就近角/质心/面积/深度/填充率)。 // binMask:掩膜(非零为前景,兼容 0/1 与 0/255);protrusions:输出的凸起列表(按面积从大到小) // 可调参数(应对实际情况): // nMinDepth:凸起最小深度(输入图像素;<=0 时按掩膜短边/150 自动取值,下限 6) // 调大:只报明显外凸的把手,浅把手会漏检,可压住边缘毛刺/噪声; // 调小:浅凸起与噪声都易报出(误报变多)。mask 由模型输出放大而来时直边带量化台阶 // (台阶高≈量化步长),建议取 2 个量化步长左右(调用方见 CheckHandleByBigMask)。 // nMinArea:凸起最小面积(输入图像素²;<=0 时按 nMinDepth² 自动取值) // 调大:小碎块被过滤,把手很小或被遮挡一部分时可能漏检; // 调小:碎块残留为候选的几率变大(仍会被 nMinDepth 再过滤一遍)。 // nEdgeMargin:边缘外扩量(输入图像素;<=0 时自动取“最小深度的一半”) // 把四条边缘线整体向外推该距离后再判凸起,等效于把凸起区域相应减小: // 调大:边缘顺边毛刺/线条偏差被吞掉,凸起区域更小更干净;过大时浅把手漏检; // 调小:更灵敏,但边缘毛刺容易连进凸起区域。 // 边缘拟合的细节参数(带宽容差/斜率上限)见 FitEdgeLine 注释。 // pBodyQuad:可选输出,拟合出的主体四边形(左上/右上/右下/左下,输入图坐标),仅 -s 存图观察用 // 返回:0 成功、1 掩膜为空、2 无有效前景 static int GetMaskProtrusions(const cv::Mat &binMask, std::vector &protrusions, int nMinDepth = 0, int nMinArea = 0, std::vector *pBodyQuad = NULL, int nEdgeMargin = 0); static std::string GetRectString(cv::Rect rect); //创建目录 static int CreateDir(const std::string &dir); // 异步存图 static int SaveImgAsync(const std::string &path, const cv::Mat &img); // 点的距离是否过小 static bool bcalDis(cv::Point p1, cv::Point p2, int disT); static double calDis(cv::Point p1, cv::Point p2); static void PrintRect(cv::Rect roi, std::string str = ""); static int cutSmallImg(cv::Mat img, std::vector &samllRoiList, cv::Rect config_roi, int config_SmallImg_Width, int config_SmallImg_Height, int config_MinOverlap_Width, int config_MinOverlap_Height); static cv::Point2f transformPoint(const cv::Point2f &point, const cv::Mat &transform_matrix); // 依目标图像通道数返回可用的绘制颜色: // 1 通道(灰度) -> 统一白色,保证可见 // 4 通道(BGRA) -> 补 alpha = 255 // 3 通道 -> 原样返回 static inline cv::Scalar GetDrawColor(const cv::Mat &img, const cv::Scalar &color) { if (img.channels() == 1) { return cv::Scalar(255); } if (img.channels() == 4) { return cv::Scalar(color[0], color[1], color[2], 255); } return color; } }; // 无参数重载:直接返回原字符串,避免 -Wformat-security 警告 static inline std::string str_Format(const std::string &format) { return format; } template static std::string str_Format(const std::string &format, Args... args) { auto size_buf = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; std::unique_ptr buf(new (std::nothrow) char[size_buf]); if (!buf) return std::string(""); std::snprintf(buf.get(), size_buf, format.c_str(), args...); return std::string(buf.get(), buf.get() + size_buf - 1); } #endif //_CORELOGICFACTORY_HPP_