feat 优化-f批量测试

dev_lsy
liusiyang 3 weeks ago
parent 9f8d85871d
commit e37e1848bd

@ -5,6 +5,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <algorithm>
#include "CheckUtil.hpp"
std::string ExtractFileNameWithoutExtension(const std::string &strImgPath)
{
@ -101,6 +102,7 @@ deal::deal()
m_nCurUseCPUIDX = 0;
m_nSaveDetprocessImg = 0;
m_nPushImgCount = 0;
m_nResultRecvCount = 0;
m_DetResult.Init();
for (int i = 0; i < READ_IMG_THREAD_NUM; i++)
{
@ -814,6 +816,8 @@ void deal::ResultThread(int id)
{
strlog += "/result";
}
// 确保日志目录存在(否则 writeLog 报 Failed to open file)
_sysmkdirs_1(strlog.substr(0, strlog.find_last_of('/')));
writeLog(strlog, m_DetResult.strlist);
mutex_DetResult_.unlock();
@ -861,6 +865,7 @@ void deal::GetDealResultToQueu()
{
mutex_Result_list.lock();
m_Result_list.push(checkResult);
m_nResultRecvCount++;
mutex_Result_list.unlock();
}
else
@ -903,6 +908,30 @@ bool deal::ReadSystemConfig(const std::string &strPath)
}
int deal::GetDetImageInfo(std::string strProductID, std::string strSearchImg, std::vector<JC_IMAGE_INFO_> &jcImageInfoList)
{
// -f 批量跑新格式: 产品目录下 input 子目录, 只取 _src 原图
// (如 1M10121544R3B2_t_face_bright_src.jpg, 从图片名解析产品ID和相机名)
if (fs::is_directory(strSearchImg + "/input"))
{
jcImageInfoList.erase(jcImageInfoList.begin(), jcImageInfoList.end());
std::vector<cv::String> srcImgPaths;
cv::glob(strSearchImg + "/input/*.jpg", srcImgPaths, false);
for (int idx = 0; idx < srcImgPaths.size(); idx++)
{
JC_IMAGE_INFO_ tem;
int re = GetImgInfo_BACKPLATE_SRC(srcImgPaths.at(idx), &tem);
if (re != 0)
{
continue;
}
if (tem.strProductID == "")
{
tem.strProductID = strProductID;
}
jcImageInfoList.push_back(tem);
}
return 0;
}
// 1、获取图片路径
std::vector<cv::String> img_paths;
std::string strs1 = strSearchImg + "/*.jpg";
@ -1000,6 +1029,63 @@ int deal::GetImgInfo_POL_ET_PNG(std::string strImgPath, JC_IMAGE_INFO_ *pImageIn
}
return 0;
}
// -f 批量跑新格式: 解析图片名组装产品信息
// 图片名示例: 1M10121544R3B2_t_face_bright_src.jpg
// 产品ID: 第一个 '_' 之前的部分 (1M10121544R3B2)
// 相机名: 直接匹配文件名中的相机名(t_face_bright / t_face_dark), 只处理后缀为 _src 的原图
// 通道名: 统一用 t_face
int deal::GetImgInfo_BACKPLATE_SRC(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo)
{
if (pImageInfo == NULL)
{
return 1;
}
std::string strName = ExtractFileNameWithoutExtension(strImgPath);
// 只处理后缀为 _src 的原图, 跳过 _roi 等其它图
const std::string strSrcSuffix = "_src";
if (strName.size() <= strSrcSuffix.size() ||
strName.compare(strName.size() - strSrcSuffix.size(), strSrcSuffix.size(), strSrcSuffix) != 0)
{
return 1;
}
// 直接匹配文件名中的相机名(t_face_bright / t_face_dark)
std::string strCamName = "";
if (strName.find("t_face_bright") != std::string::npos)
{
strCamName = "t_face_bright";
}
else if (strName.find("t_face_dark") != std::string::npos)
{
strCamName = "t_face_dark";
}
if (strCamName == "")
{
printf("GetImgInfo_BACKPLATE_SRC: no camera match, skip %s\n", strImgPath.c_str());
return 1;
}
// 产品ID = 文件名第一个 '_' 之前的部分
std::string strProductID = strName;
size_t nPos = strName.find('_');
if (nPos != std::string::npos)
{
strProductID = strName.substr(0, nPos);
}
pImageInfo->strProductID = strProductID;
pImageInfo->strCamID = strCamName;
pImageInfo->strchannelName = "t_face"; // 通道名统一用 t_face
pImageInfo->strName = strName;
pImageInfo->strPath = strImgPath;
printf("strImgPath %s strName %s strProductID %s strCam %s strChannel %s\n",
strImgPath.c_str(), strName.c_str(), strProductID.c_str(), strCamName.c_str(), pImageInfo->strchannelName.c_str());
return 0;
}
int deal::InsertDetResult(ReadImgInfo tem)
{
std::lock_guard<std::mutex> lock(mtx_List[Mutex_Type_DetResult]);
@ -1203,6 +1289,36 @@ int deal::DetImg()
// getchar();
m_nSystemCheckType = CHECK_TYPE_OFFLING;
StartThread(THREAD_RUN_ALL);
// -8 循环执行:保持常驻,重复处理同一批产品
if (runConfig.bLoop)
{
while (true)
{
usleep(1000 * 1000);
}
}
// -f 批量(不加 -8 只执行一次):等待全部产品处理完成后退出
// DealImg 线程处理完一批后会清空 m_product_ID_List 并等待结果队列清空
while (true)
{
usleep(200 * 1000);
size_t nResultSize = 0;
{
std::lock_guard<std::mutex> lock(mutex_Result_list);
nResultSize = m_Result_list.size();
}
if (m_product_ID_List.empty() && nResultSize <= 0)
{
break;
}
}
// 留时间给结果线程把最后一组结果写完
usleep(2 * 1000 * 1000);
printf(">>> -f batch complete, exit \n");
fflush(NULL);
_exit(0);
return 0;
}
int deal::ReJson_product(std::vector<Json_Det_Path> &jsonList, std::string strProductName)
@ -1552,6 +1668,55 @@ int deal::LoadProductID(std::string strImgPath)
m_product_ID_List.erase(m_product_ID_List.begin(), m_product_ID_List.end());
std::vector<cv::String> img_paths;
// -f 批量跑新格式适配(参考 data/img/test-2 结构):
// <filePath>/<产品ID>_<时间戳>/input/<产品ID>_<相机名>_<位置>_src.jpg
// 也支持直接传入单个产品目录或产品目录下的 input 目录
{
std::string strPath = strImgPath;
while (!strPath.empty() && strPath[strPath.size() - 1] == '/')
{
strPath.erase(strPath.size() - 1);
}
fs::path rootPath(strPath);
if (!strPath.empty() && fs::is_directory(rootPath))
{
// 兼容直接传入 input 目录: 使用其上一级产品目录
if (rootPath.filename() == "input" && rootPath.has_parent_path())
{
rootPath = rootPath.parent_path();
}
std::vector<std::string> productDirList;
if (fs::is_directory(rootPath / "input"))
{
// 直接传入单个产品目录
productDirList.push_back(rootPath.string());
}
else
{
// 批量根目录: 含 input 子目录的子目录视为一个产品
for (const auto &entry : fs::directory_iterator(rootPath))
{
if (entry.is_directory() && fs::is_directory(entry.path() / "input"))
{
productDirList.push_back(entry.path().string());
}
}
}
if (!productDirList.empty())
{
std::sort(productDirList.begin(), productDirList.end());
for (const auto &strProductDir : productDirList)
{
m_product_ID_List.push_back(strProductDir);
std::cout << "new format product dir: " << strProductDir << std::endl;
}
return 0;
}
}
}
// tif 格式
{
std::string str_bmp = strImgPath + "/*.jpg";
@ -1600,6 +1765,11 @@ int deal::LoadProductID(std::string strImgPath)
}
}
if (m_product_ID_List.empty())
{
printf("warning: no product dir/image found under %s\n", strImgPath.c_str());
}
return 0;
}
int deal::DelImg_Cell_ET()
@ -1650,6 +1820,13 @@ int deal::Det_OneProduct_Cell_ET(std::string strProductName, int Idx)
{
std::string strProductID = GetFileName(strProductName);
// -f 批量跑新格式: 产品目录名为 <产品ID>_<时间戳>(如 1M10121544R3B2_20261012.151444.066219)
// 取第一个 '_' 之前的部分作为产品ID; 旧格式目录名本身即产品ID(无 '_')不受影响
size_t nProductIDPos = strProductID.find('_');
if (nProductIDPos != std::string::npos)
{
strProductID = strProductID.substr(0, nProductIDPos);
}
// 获取图片路径
std::vector<JC_IMAGE_INFO_> detImgInfoList;
@ -1739,6 +1916,33 @@ int deal::Det_OneProduct_Cell_ET(std::string strProductName, int Idx)
}
}
// -f 批量逐个产品处理:等待本产品的检测结果全部返回后,再处理下一个产品,
// 避免多个产品同时积压在检测队列中(内存/检测器压力过大导致卡死)
if (AllImgNum > 0)
{
int nWaitCnt = 0;
while (true)
{
int nRecv = 0;
int nPush = 0;
{
std::lock_guard<std::mutex> lock(mutex_Result_list);
nRecv = m_nResultRecvCount;
nPush = m_nPushImgCount;
}
if (nRecv >= nPush)
{
break;
}
if (nWaitCnt % 250 == 0)
{
printf(">>> waiting %s check result %d/%d ...\n", strProductID.c_str(), nRecv, nPush);
}
nWaitCnt++;
usleep(20 * 1000);
}
}
m_DetResult.one_result_list.push_back(tem_one);
m_DetResult.det_num_all++;
// if (m_DetResult.det_num_all == 1)

@ -551,6 +551,9 @@ private:
int GetImgInfo_POL_ET_PNG(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo);
// -f 批量跑新格式: 解析 <产品ID>_<相机名>_<位置>_src.jpg 图片名组装产品信息(相机名 t_face_bright/t_face_dark, 通道名统一 t_face)
int GetImgInfo_BACKPLATE_SRC(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo);
// 功能测试
int Det_Funtion_Test();
// 边缘测试
@ -649,6 +652,7 @@ public:
int m_nSaveDetprocessImg;
int m_nPushImgCount; // 送检图片总数(拆分后)
int m_nResultRecvCount; // 已收到检测结果总数(-f 逐个产品处理:等当前产品结果返回后再跑下一个)
cv::Rect m_CutRoi;
Det_File_Result_Info m_DetResult;

@ -85,6 +85,8 @@ int main(int argc, char *argv[])
cout << "*** 5、./test_JBL_Check -falign filepath num : 批量测试定位算法,num 至多处理张数,结果:/home/aidlux/BOE/Align" << endl;
cout << "*** 6、./test_JBL_Check -rjson filepath: 单张复测,filepath xx/xx/3A3K380001B1DK_20240408_152157_Main_0_2_L255" << endl;
cout << "*** 6、./test_JBL_Check -rjsonall filepath: 一套图复测,filepath xx/xx/" << endl;
cout << "*** 7、./test_BACKPLATE -8: 循环执行程序(常驻),不加 -8 只执行一次" << endl;
cout << "*** 8、./test_BACKPLATE -f filepath: 批量执行 filepath 下的套图(新格式: <产品ID>_<时间戳>/input/<产品ID>_<相机名>_xxx_src.jpg, 相机名 t_face_bright/t_face_dark, 通道名统一 t_face)" << endl;
cout << "******************************************************" << endl;
return 0;

Loading…
Cancel
Save