update 优化存图路径

dev_lsy
liusiyang 1 week ago
parent 7a5c913f2f
commit 1d5c6d7c8d

@ -33,6 +33,10 @@ public:
static std::string getCurTimeHMS(); static std::string getCurTimeHMS();
static std::string Op_float2String(float nvalue); static std::string Op_float2String(float nvalue);
static int64_t getSnowId(); 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(cv::Rect roi, int img_w, int img_h);
static bool JudgRect_SZ(cv::Rect roi, int w, int 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 compareIgnoreCase(const std::string &str1, const std::string &str2);

@ -386,10 +386,11 @@ int AI_Edge_Algin::Get_Edge(int AIModel_type, const cv::Mat &img, DetConfig *pDe
if (pDetConfig->pBaseCheckFunction->saveImg.bSaveAlginImg) if (pDetConfig->pBaseCheckFunction->saveImg.bSaveAlginImg)
{ {
std::string cur_time_s = CheckUtil::getCurTimeHMS(); // 前缀用日期(年月日): 同一产品当天的所有图前缀一致; 文件已存在时在日期后追加序号, 不覆盖旧图
std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + pDetConfig->strProductID + "/"; std::string strDatePre = CheckUtil::getCurrentDateYMD();
CheckUtil::CreateDir(strSaveDir); std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + pDetConfig->strProductID + "/KK/";
std::string strSavePath_out = strSaveDir + cur_time_s + "_" + pDetConfig->strChannel + "_" + std::to_string(AIModel_type) + "_Align_out.png"; std::string strName = pDetConfig->strChannel + "_" + std::to_string(AIModel_type) + "_Align_out";
std::string strSavePath_out = CheckUtil::GetUniqueImgPath(strSaveDir, strDatePre, strName, ".png");
CheckUtil::SaveImgAsync(strSavePath_out, mask); CheckUtil::SaveImgAsync(strSavePath_out, mask);
} }

@ -691,7 +691,7 @@ int ALLImgCheckAnalysisy::PushInImg_New(std::shared_ptr<shareImage> p)
// 对传入图片做一步判断,如果高大于宽,则顺时针旋转90° // 对传入图片做一步判断,如果高大于宽,则顺时针旋转90°
if (p->Det_Mode != DET_MODE_ReJson) if (p->Det_Mode != DET_MODE_ReJson)
{ {
if (!p->img.empty() && p->img.rows > p->img.cols) if (!p->img.empty())
{ {
cv::Mat imgRot; cv::Mat imgRot;
cv::rotate(p->img, imgRot, cv::ROTATE_90_CLOCKWISE); cv::rotate(p->img, imgRot, cv::ROTATE_90_CLOCKWISE);
@ -700,7 +700,7 @@ int ALLImgCheckAnalysisy::PushInImg_New(std::shared_ptr<shareImage> p)
p->img.cols, p->img.rows, imgRot.cols, imgRot.rows); p->img.cols, p->img.rows, imgRot.cols, imgRot.rows);
p->img = imgRot; p->img = imgRot;
} }
if (!p->img_B.empty() && p->img_B.rows > p->img_B.cols) if (!p->img_B.empty())
{ {
cv::Mat imgBRot; cv::Mat imgBRot;
cv::rotate(p->img_B, imgBRot, cv::ROTATE_90_CLOCKWISE); cv::rotate(p->img_B, imgBRot, cv::ROTATE_90_CLOCKWISE);

@ -19,6 +19,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <fstream> #include <fstream>
#include <thread> #include <thread>
#include <fcntl.h>
#include "snowflake.hpp" #include "snowflake.hpp"
int _sysmkdir_2(const std::string &dir) int _sysmkdir_2(const std::string &dir)
@ -80,6 +81,25 @@ std::string CheckUtil::getCurrentDate()
return oss.str(); // 返回日期字符串 return oss.str(); // 返回日期字符串
} }
std::string CheckUtil::getCurrentDateYMD()
{
struct timeval tv;
gettimeofday(&tv, NULL);
time_t raw_time = tv.tv_sec;
// localtime_r 为线程安全版本
struct tm time_buf;
struct tm *time_info = localtime_r(&raw_time, &time_buf);
// 固定 8 位 "YYYYMMDD", 便于文件名检索与排序
std::ostringstream oss;
oss << std::setfill('0')
<< std::setw(4) << (time_info->tm_year + 1900)
<< std::setw(2) << (time_info->tm_mon + 1)
<< std::setw(2) << time_info->tm_mday;
return oss.str();
}
std::string CheckUtil::getCurTimeHMS() std::string CheckUtil::getCurTimeHMS()
{ {
struct timeval tv; struct timeval tv;
@ -122,6 +142,40 @@ int64_t CheckUtil::getSnowId()
return 0; return 0;
} }
std::string CheckUtil::GetUniqueImgPath(const std::string &strDir, const std::string &strPrefix, const std::string &strName, const std::string &strExt)
{
if (strDir.empty())
{
return strDir + strPrefix + strName + strExt;
}
// 目录不存在时 O_CREAT 会失败, 先建目录(已存在时内部无副作用)
CreateDir(strDir);
// 去重序号插在前缀之后: <年月日>[_序号]_<通道>_<用途>.png
// 同一产品的每个 strName 每轮只会写一次, 所以各文件序号天然同步:
// 第 1 轮 -> <年月日>_<名称>.png、第 2 轮 -> <年月日>_1_<名称>.png、第 3 轮 -> <年月日>_2_<名称>.png ...
const std::string strHead = strPrefix.empty() ? std::string("") : (strPrefix + "_");
for (int i = 0; i < 100000; i++)
{
std::string strPath = strDir + strHead + (i == 0 ? std::string("") : std::to_string(i) + "_") + strName + strExt;
// O_EXCL: 文件不存在才能创建成功, 即是"原子占位", 并发安全
int fd = ::open(strPath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0644);
if (fd >= 0)
{
::close(fd);
return strPath;
}
if (errno != EEXIST)
{
// 非"已存在"类错误(权限/路径等)不再重试, 直接返回让 imwrite 把错误暴露出来
printf("create img file[%s] error: %d %s\n", strPath.c_str(), errno, strerror(errno));
return strPath;
}
}
// 序号用尽的兜底(实际不会发生)
return strDir + strHead + std::to_string(CheckUtil::getcurTime()) + "_" + strName + strExt;
}
bool CheckUtil::JudgRect(cv::Rect roi, int img_w, int img_h) bool CheckUtil::JudgRect(cv::Rect roi, int img_w, int img_h)
{ {
if (img_w <= 0 || img_h <= 0) if (img_w <= 0 || img_h <= 0)

@ -1830,7 +1830,6 @@ int ImgCheckAnalysisy::ConfigCheck(cv::Mat img)
int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg) int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg)
{ {
std::string cur_time_s = CheckUtil::getCurTimeHMS();
// 依次使用多个检测模型,各模型输出 mask 取并集作为最终 outmask; // 依次使用多个检测模型,各模型输出 mask 取并集作为最终 outmask;
// Defect_QueXi 模型是否参与合并由基础参数 Merge_QueXi 开关控制 // Defect_QueXi 模型是否参与合并由基础参数 Merge_QueXi 开关控制
std::vector<std::shared_ptr<AIModel_Base>> pAIDetList; std::vector<std::shared_ptr<AIModel_Base>> pAIDetList;
@ -1960,9 +1959,11 @@ int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg)
// 目录结构:/home/aidlux/BOE/ZB_SOCKET/AI_Detect/<模型名称>/<产品ID>/ // 目录结构:/home/aidlux/BOE/ZB_SOCKET/AI_Detect/<模型名称>/<产品ID>/
if (m_pbaseCheckFunction->saveImg.bSaveAIDetImg && !modelMaskFull.empty()) if (m_pbaseCheckFunction->saveImg.bSaveAIDetImg && !modelMaskFull.empty())
{ {
std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + DetImgInfo_shareP->strImgProductID + "/"; // 前缀用日期(年月日): 同一产品当天的所有图前缀一致; 文件已存在时在日期后追加序号, 不覆盖旧图
CheckUtil::CreateDir(strSaveDir); std::string strDatePre = CheckUtil::getCurrentDateYMD();
std::string strSavePath_out = strSaveDir + cur_time_s + "_" + m_strCurDetChannel + "_" + strModelName + "_out.png"; std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + DetImgInfo_shareP->strImgProductID + "/KK/";
std::string strName = m_strCurDetChannel + "_" + strModelName + "_out";
std::string strSavePath_out = CheckUtil::GetUniqueImgPath(strSaveDir, strDatePre, strName, ".png");
CheckUtil::SaveImgAsync(strSavePath_out, modelMaskFull); CheckUtil::SaveImgAsync(strSavePath_out, modelMaskFull);
} }
@ -2020,9 +2021,11 @@ int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg)
if (m_pbaseCheckFunction->saveImg.bSaveAIDetImg ) if (m_pbaseCheckFunction->saveImg.bSaveAIDetImg )
{ {
std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + DetImgInfo_shareP->strImgProductID + "/"; // 前缀用日期(年月日): 同一产品当天的所有图前缀一致; 文件已存在时在日期后追加序号, 不覆盖旧图
CheckUtil::CreateDir(strSaveDir); std::string strDatePre = CheckUtil::getCurrentDateYMD();
std::string strSavePath_in = strSaveDir + cur_time_s + "_" + m_strCurDetChannel + "_in.png"; std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + DetImgInfo_shareP->strImgProductID + "/KK/";
std::string strName = m_strCurDetChannel + "_in";
std::string strSavePath_in = CheckUtil::GetUniqueImgPath(strSaveDir, strDatePre, strName, ".png");
CheckUtil::SaveImgAsync(strSavePath_in, m_CheckResult_shareP->cutSrcimg); CheckUtil::SaveImgAsync(strSavePath_in, m_CheckResult_shareP->cutSrcimg);
} }
// 临时存图 // 临时存图

@ -49,10 +49,11 @@ int Pin_QX_Det::GetPinMask(const cv::Mat &img, DetConfigResult *pDetConfig, Mat
// 输入图存未做通道转化(灰度化)之前的图; 文件名首位用产品ID // 输入图存未做通道转化(灰度化)之前的图; 文件名首位用产品ID
if (pDetConfig->pBaseCheckFunction != NULL && pDetConfig->pBaseCheckFunction->saveImg.bSavePinImg) if (pDetConfig->pBaseCheckFunction != NULL && pDetConfig->pBaseCheckFunction->saveImg.bSavePinImg)
{ {
std::string cur_time_s = CheckUtil::getCurTimeHMS(); // 前缀用日期(年月日): 同一产品当天的所有图前缀一致; 文件已存在时在日期后追加序号, 不覆盖旧图
std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + pDetConfig->strProductID + "/"; std::string strDatePre = CheckUtil::getCurrentDateYMD();
CheckUtil::CreateDir(strSaveDir); std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + pDetConfig->strProductID + "/KK/";
std::string strSavePath_out = strSaveDir + cur_time_s + "_" + pDetConfig->strChannel + "_pin_out.png"; std::string strName = pDetConfig->strChannel + "_pin_out";
std::string strSavePath_out = CheckUtil::GetUniqueImgPath(strSaveDir, strDatePre, strName, ".png");
CheckUtil::SaveImgAsync(strSavePath_out, mask); CheckUtil::SaveImgAsync(strSavePath_out, mask);
} }

Loading…
Cancel
Save