update 优化存图路径

dev_lsy
liusiyang 1 week ago
parent 8701839e58
commit 4e95e93a91

@ -57,6 +57,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);

@ -21,6 +21,7 @@
#include <thread> #include <thread>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <fcntl.h>
#include "snowflake.hpp" #include "snowflake.hpp"
int _sysmkdir_2(const std::string &dir) int _sysmkdir_2(const std::string &dir)
@ -69,8 +70,10 @@ std::string CheckUtil::getCurrentDate()
// 将 tv_sec 转换为 time_t 类型,代表自1970年1月1日起的秒数 // 将 tv_sec 转换为 time_t 类型,代表自1970年1月1日起的秒数
time_t raw_time = tv.tv_sec; time_t raw_time = tv.tv_sec;
// 使用 localtime 将 time_t 转换为 tm 结构体 // 使用 localtime_r 转换为 tm 结构体。
struct tm *time_info = localtime(&raw_time); // 注意:localtime() 返回共享的静态缓冲区,多线程并发调用会互相覆盖(tm 内容串数据)。
struct tm time_buf;
struct tm *time_info = localtime_r(&raw_time, &time_buf);
// 使用字符串流格式化为 "YYYY-MM-DD" // 使用字符串流格式化为 "YYYY-MM-DD"
std::ostringstream oss; std::ostringstream oss;
@ -80,13 +83,34 @@ 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;
gettimeofday(&tv, NULL); // 获取当前时间 gettimeofday(&tv, NULL); // 获取当前时间
time_t raw_time = tv.tv_sec; time_t raw_time = tv.tv_sec;
struct tm *time_info = localtime(&raw_time); // 使用 localtime_r(线程安全);localtime() 的静态缓冲会被其它线程并发覆盖
struct tm time_buf;
struct tm *time_info = localtime_r(&raw_time, &time_buf);
int millisec = tv.tv_usec / 1000; // 微秒转毫秒 int millisec = tv.tv_usec / 1000; // 微秒转毫秒
@ -120,6 +144,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)

@ -3366,8 +3366,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();
std::shared_ptr<AIModel_Base> pAIDet; std::shared_ptr<AIModel_Base> pAIDet;
// printf("=====>>>>AI_Detect_Thread m_strCurDetChannel %s \n", m_strCurDetChannel.c_str()); // printf("=====>>>>AI_Detect_Thread m_strCurDetChannel %s \n", m_strCurDetChannel.c_str());
bool bUseDarkModel = false; bool bUseDarkModel = false;
@ -3477,10 +3475,10 @@ int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg)
if (m_pbaseCheckFunction->saveImg.bSaveAIDetImg && !ResultImg.empty()) if (m_pbaseCheckFunction->saveImg.bSaveAIDetImg && !ResultImg.empty())
{ {
std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + DetImgInfo_shareP->strImgProductID + "/"; std::string strDatePre = CheckUtil::getCurrentDateYMD();
CheckUtil::CreateDir(strSaveDir); std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + DetImgInfo_shareP->strImgProductID + "/BM/";
std::string strSavePath_in = strSaveDir + cur_time_s + "_" + strCameraName + "_in.png"; std::string strSavePath_in = CheckUtil::GetUniqueImgPath(strSaveDir, strDatePre, strCameraName, "_in.png");
std::string strSavePath_out = strSaveDir + cur_time_s + "_" + strCameraName + "_out.png"; std::string strSavePath_out = CheckUtil::GetUniqueImgPath(strSaveDir, strDatePre, strCameraName, "_out.png");
CheckUtil::SaveImgAsync(strSavePath_in, m_CheckResult_shareP->cutSrcimg); CheckUtil::SaveImgAsync(strSavePath_in, m_CheckResult_shareP->cutSrcimg);
CheckUtil::SaveImgAsync(strSavePath_out, ResultImg); CheckUtil::SaveImgAsync(strSavePath_out, ResultImg);
} }
@ -4305,10 +4303,9 @@ int ImgCheckAnalysisy::CheckTagByBigMask(const cv::Mat &img, const cv::Mat &bigm
if (m_pbaseCheckFunction->saveImg.bSaveBQDetImg) if (m_pbaseCheckFunction->saveImg.bSaveBQDetImg)
{ {
std::string cur_time_s = CheckUtil::getCurTimeHMS(); std::string strDatePre = CheckUtil::getCurrentDateYMD();
std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + DetImgInfo_shareP->strImgProductID + "/"; std::string strSaveDir = "/home/aidlux/BOE/AI_Detect/" + DetImgInfo_shareP->strImgProductID + "/BM/";
CheckUtil::CreateDir(strSaveDir); std::string strSavePath_out = CheckUtil::GetUniqueImgPath(strSaveDir, strDatePre, DetImgInfo_shareP->strCameraName, "_BQ_out.png");
std::string strSavePath_out = strSaveDir + cur_time_s + "_" + DetImgInfo_shareP->strCameraName + "_BQ_out.png";
CheckUtil::SaveImgAsync(strSavePath_out, mask); CheckUtil::SaveImgAsync(strSavePath_out, mask);
} }

Loading…
Cancel
Save