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.

2083 lines
61 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.

#include "deal.h"
#include "json/json.h"
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <algorithm>
#include "CheckUtil.hpp"
std::string ExtractFileNameWithoutExtension(const std::string &strImgPath)
{
// 查找最后一个斜杠 '/' 或 '\' 的位置
size_t lastSlashPos = strImgPath.find_last_of("/\\");
// 如果没有找到斜杠,默认整个字符串是文件名
std::string fileName = (lastSlashPos == std::string::npos)
? strImgPath
: strImgPath.substr(lastSlashPos + 1);
// 查找最后一个点 '.' 的位置
size_t lastDotPos = fileName.find_last_of('.');
// 如果没有找到点号,或者点号在第一个字符的位置,则返回完整文件名
if (lastDotPos == std::string::npos || lastDotPos == 0)
{
return fileName;
}
// 返回去掉扩展名的部分
return fileName.substr(0, lastDotPos);
}
std::string GetFileName(const std::string &strImgPath)
{
// 查找最后一个斜杠 '/' 或 '\' 的位置
size_t lastSlashPos = strImgPath.find_last_of("/\\");
// 如果没有找到斜杠,默认整个字符串是文件名
std::string fileName = (lastSlashPos == std::string::npos)
? strImgPath
: strImgPath.substr(lastSlashPos + 1);
// 查找最后一个点 '.' 的位置
return fileName;
}
int _sysmkdir_1(const std::string &dir)
{
int ret = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret && errno == EEXIST)
{
// printf("dir[%s] already exist.\n", dir.c_str());
}
else if (ret)
{
printf("create dir[%s] error: %d %s\n", dir.c_str(), ret, strerror(errno));
return -1;
}
else
{
printf("create dir[%s] success.\n", dir.c_str());
}
return 0;
}
std::string __getParentDir_1(const std::string &dir)
{
std::string pdir = dir;
if (pdir.length() < 1 || (pdir[0] != '/'))
{
return "";
}
while (pdir.length() > 1 && (pdir[pdir.length() - 1] == '/'))
pdir = pdir.substr(0, pdir.length() - 1);
pdir = pdir.substr(0, pdir.find_last_of('/'));
return pdir;
}
int _sysmkdirs_1(const std::string &dir)
{
int ret = 0;
if (dir.empty())
return -1;
std::string pdir;
if ((ret = _sysmkdir_1(dir)) == -1)
{
pdir = __getParentDir_1(dir);
if ((ret = _sysmkdirs_1(pdir)) == 0)
{
ret = _sysmkdirs_1(dir);
}
}
return ret;
}
long getcurTime()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return ((long)tv.tv_sec) * 1000 + ((long)tv.tv_usec) / 1000;
}
deal::deal()
{
nLastCheckAnalysisyThreadIdx = 0;
m_nCamIdx = 0;
m_nCurUseCPUIDX = 0;
m_nSaveDetprocessImg = 0;
m_DetResult.Init();
for (int i = 0; i < READ_IMG_THREAD_NUM; i++)
{
m_nReadStausList[i] = ReadImg_Status_IDE;
}
m_nreadImg_Stop = false;
m_strCurDate = "";
m_nReadThread_type = READ_THREAD_TYPE_NULL;
for (int i = 0; i < Status_Type_Count; i++)
{
m_DetStatusList[i] = Thread_Status_IDE;
}
m_nTestNum = 9999999;
m_pALLImgCheckAnalysisy = NULL;
}
deal::~deal()
{
}
int deal::start()
{
std::string strdate = CheckUtil::getCurrentDate();
printf("===== %s\n", strdate.c_str());
int re = Init();
// getchar();
// 配置系统运行的cup核数。
if (re != 0)
{
return 1;
}
if (runConfig.run_Type == Process_Run_ReJson)
{
ReJson_ALL();
return 0;
}
else
{
DetImg();
}
return 0;
}
int deal::Init()
{
InitCPUIDX();
// 读取系统配置文件
int re = ReadSystemConfig(FILE_SYSTEM_RUN_CONFIG);
if (re == false)
{
printf("ReadSystemConfig error\n");
return 1;
}
// 加载 检测 的通道 图片名称
std::string strchannlePath = m_system_param.config_Root_Path + "surface_list.json";
m_image_ReadChannel.ReadJsonConfig(strchannlePath);
// getchar();
// getchar();
// 初始化参数模块
InitConfig();
printf("\n\n\n\n\n\n\n\n\n\n\n**********************************************************LoadCheckImgConfig\n");
// 载入参数
re = LoadCheckImgConfig();
if (re != 0)
{
printf("read config error\n");
return 2;
}
printf("\n\n**********************************************************InitCheckAnalysisy\n");
// 初始化检测库
InitCheckAnalysisy();
printf("\n\n\n\n\n\n\n\n\n\n\n**********************************************************Check\n");
return 0;
}
int deal::LoadCheckImgConfig()
{
int re = LoadAnalysisConfig();
if (re != 0)
{
return re;
}
// re = LoadCheckConfig();
// if (re != 0)
// {
// return re;
// }
return 0;
}
int deal::InitCheckAnalysisy()
{
int re = 0;
int m_nMAX_GPU_NUM = MAX_GPU_NUM;
if (m_nMAX_GPU_NUM <= 0)
{
printf(">>>>error GPU error %d \n", m_nMAX_GPU_NUM);
return 2;
}
int startidx = m_CPUInfo[THREAD_CPU_CheckSo].startIdx;
int cpunum = m_CPUInfo[THREAD_CPU_CheckSo].num;
m_RunConfig.nCpu_start_Idx = startidx;
m_RunConfig.nCpu_num = cpunum;
m_pALLImgCheckAnalysisy = ALLImgCheckBase::GetInstance();
re = m_pALLImgCheckAnalysisy->UpdateConfig((void *)&m_RunConfig, CHECK_CONFIG_Run);
re = m_pALLImgCheckAnalysisy->UpdateConfig((void *)m_pConfigManager, CHECK_CONFIG_Module);
VERSION_INFO tm;
tm.InterfaceVersion = ALL_INTERFACE_VERSION;
tm.ConfigVersion = CONFIGBASE_VERSION;
tm.ResultVersion = RESULT_VERSION;
re = m_pALLImgCheckAnalysisy->RunStart(&tm);
if (re != 0)
{
printf("RunStart Fail %d\n", re);
return re;
}
printf(">>>> ImgCheckThread Start Succ \n");
return 0;
}
int deal::InitConfig()
{
m_pConfigManager = ConfigManagerBase::GetInstance();
return 0;
}
int deal::InitSaveImgPath()
{
return 0;
}
int deal::LoadCheckConfig()
{
return 0;
}
int deal::LoadAnalysisConfig()
{
if (!m_pConfigManager)
{
return 1;
}
std::string folder = m_system_param.config_Root_Path;
int re = m_pConfigManager->LoadAnalysisConfig(folder);
// for (const auto &pair : m_pConfigManager->Config_instances_)
// {
// std::cout << "cam: " << pair.first << std::endl;
// }
// getchar();
return re;
}
int deal::StartThread(THREAD_RUN_TYPE type)
{
m_bExit = false;
// 只读图线程
if (type == THREAD_RUN_ALL)
{
// 开启检测线程
ptr_DealImgthread = std::make_shared<std::thread>(&deal::DealImg, this);
// 结果处理线程
// ptr_Resultthread = std::make_shared<std::thread>(&deal::ResultThread, this);
for (int i = 0; i < Save_IMG_THREAD_NUM; ++i)
{
// 创建线程,并使用 std::make_shared 创建 shared_ptr
std::shared_ptr<std::thread> threadPtr = std::make_shared<std::thread>(&deal::ResultThread, this, i);
// 将 shared_ptr 添加到 vector 中
ptr_ResultthreadList.push_back(threadPtr);
}
// 结果拷贝线程
ptr_GetResultthread = std::make_shared<std::thread>(&deal::GetResultThread, this);
}
for (int i = 0; i < READ_IMG_THREAD_NUM; ++i)
{
// 创建线程,并使用 std::make_shared 创建 shared_ptr
std::shared_ptr<std::thread> threadPtr = std::make_shared<std::thread>(&deal::ReadImgThread, this, i);
// 将 shared_ptr 添加到 vector 中
threadArray.push_back(threadPtr);
}
return 0;
}
int deal::StopThread()
{
return 0;
}
int deal::preCheck()
{
string cur_time = CheckUtil::getCurTimeHMS();
printf("[%s]>>> preCheck start \n", cur_time.c_str());
std::string strRoot = "../data/img/t1";
std::string strProductID = "";
std::string strRoot2 = "../data/img/t1";
{
READ_IMG_INFO read;
readTestImg(read);
strRoot = read.strpath;
strProductID = read.strproduct;
strRoot2 = read.strpath_2;
printf("strSearchImg strRoot %s\n", strRoot.c_str());
std::ifstream file123(strRoot);
bool bhave = file123.good();
if (!bhave)
{
printf("read img path error %d %s\n", bhave, strRoot.c_str());
return 1;
}
}
// 获取图片路径
std::string strSearchImg = strRoot;
Read_Image dfe;
int re = 0;
dfe.pimage_ReadChannel = &m_image_ReadChannel;
re = dfe.Read_Image_List(strSearchImg, strProductID);
if (re != 0)
{
return re;
}
if (dfe.m_product_Camera_List.size() <= 0)
{
printf("error m_product_Camera_List.size() %ld \n", dfe.m_product_Camera_List.size());
return -1;
}
int idx = 0;
for (int i = 0; i < dfe.m_product_Camera_List.size(); i++)
{
if (dfe.m_product_Camera_List[i]->strProductID == strProductID)
{
idx = i;
break;
}
}
std::shared_ptr<Product_File_Info> product = dfe.m_product_Camera_List[idx];
int AllImgNum = product->getImgNum();
printf("product %s img num %d \n", product->strProductID.c_str(), AllImgNum);
long t1 = getcurTime();
// 读图现场都开启
setReadThreadStart();
// 遍历所有图片 开始读图处理
AllImgNum = 0;
for (const auto pcam : product->camera_list)
{
std::shared_ptr<JC_IMAGE_INFO_> tem = std::make_shared<JC_IMAGE_INFO_>();
tem->strCamID = pcam->strCamName;
for (const auto pimage : pcam->image_list)
{
tem->strchannelName = pimage->strchannelName;
tem->strName = pimage->strName;
tem->strProductID = pimage->strProductID;
if (tem->strPath == "")
{
tem->strPath = pimage->strPath;
}
else
{
tem->strPath_B = pimage->strPath;
}
}
InsertReadImgInfo(tem);
AllImgNum++;
// break;
}
// AllImgNum = 1;
{
IN_IMG_Status_ temstatus = IN_IMG_Status_Start;
std::shared_ptr<JC_IMAGE_INFO_> tempDetImageInfo = nullptr;
int pushImgNum = 0;
long det_time_start = getcurTime();
std::string strImgSN = strProductID;
int GetImgNum = 0;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(50)); //
int ThreadIdx = GetReadImgCompleteThreadIdx();
if (ThreadIdx < 0)
{
continue;
}
std::shared_ptr<JC_IMAGE_INFO_> pDetImageInfo = nullptr;
pDetImageInfo = m_ReadImgThread_Result[ThreadIdx];
// 开始送到检测进行处理
if (pDetImageInfo != nullptr)
{
// printf(">>> %s----start \n", pDetImageInfo->strName.c_str());
tempDetImageInfo = pDetImageInfo;
int re = SendImgToCheck(pDetImageInfo, temstatus);
if (re != 0)
{
continue;
}
pushImgNum++;
}
SetStatus_List(ThreadIdx, Thread_Status_READY);
GetImgNum++;
if (IN_IMG_Status_Start == temstatus)
{
temstatus = IN_IMG_Status_Other;
}
// 图是否都读取完了。
bool bReadCompleted = false;
if (GetImgNum >= AllImgNum)
{
bReadCompleted = true;
}
// 退出
if (bReadCompleted)
{
SendImgToCheck(tempDetImageInfo, IN_IMG_Status_End);
break;
}
}
string cur_time = CheckUtil::getCurTimeHMS();
printf("[%s]>>> preCheck push img end \n", cur_time.c_str());
int getresultNum = 0;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟消费过程
// 处理结果
std::shared_ptr<CheckResult> checkResult;
int re = m_pALLImgCheckAnalysisy->GetCheckReuslt(checkResult);
saveImg("/home/aidlux/BOE/ZB_SOCKET/testresult/", checkResult);
getresultNum++;
if (getresultNum == pushImgNum)
{
break;
}
}
}
printf(">>> ALL preCheck complete \n");
return 0;
}
int deal::readTestImg(READ_IMG_INFO &read)
{
std::string strRoot = "../data/img/TestImg.json";
printf("Reading Img config %s\n", strRoot.c_str());
Json::CharReaderBuilder builder;
builder["collectComments"] = true;
Json::Value root;
std::string err;
std::ifstream ifs(strRoot);
if (!ifs.is_open())
{
printf("error:file is open\n");
return 1;
}
if (!Json::parseFromStream(builder, ifs, &root, &err))
{
printf("error:parseFromStream\n");
return 1;
}
std::string imgpath = "";
read.strpath = root["TestImg_Path"].asString();
read.strproduct = root["ProductID"].asString();
if (root["TestImg_2_Path"])
{
read.strpath_2 = root["TestImg_2_Path"].asString();
}
else
{
read.strpath_2 = "";
}
return 0;
}
int deal::saveImg(std::string strpath, std::shared_ptr<CheckResult> result)
{
std::string strroot = strpath;
std::string strroot_qx = strpath;
if (result->in_shareImage->imgstr != "")
{
strroot += result->in_shareImage->imgstr;
strroot += "/";
strroot_qx += result->in_shareImage->imgstr;
strroot_qx += "/";
}
if (strpath != "")
{
strroot_qx += "qx/";
if (result->nProductResult != 0)
{
strroot += "NG/";
}
else
{
strroot += "OK/";
}
if (result->in_shareImage->strImgProductID != "")
{
strroot += result->in_shareImage->strImgProductID + "/";
}
if (result->nresult != 0)
{
strroot += "NG/";
}
else
{
if (result->nYS_result != 0)
{
strroot += "OK/YS/";
}
else
{
strroot += "OK/OK/";
}
}
}
printf("result->nresult %d %d \n", result->nresult, result->nYS_result);
printf("%s\n", strroot.c_str());
_sysmkdirs_1(strroot);
std::string str_saveName = "";
// getchar();
if (result->in_shareImage->strImgProductID != "")
{
strroot += result->in_shareImage->strImgProductID;
str_saveName += result->in_shareImage->strImgProductID;
}
if (result->in_shareImage->strImgName != "")
{
strroot += "_" + result->in_shareImage->strImgName;
str_saveName += "_" + result->in_shareImage->strImgName;
}
{
std::string strcam = std::to_string(result->in_shareImage->camera_ID);
strroot += "_" + strcam;
str_saveName += "_" + strcam;
}
writeLog(strroot, result->det_LogList);
WriteJsonString(strroot, result->strResultJson);
// printf("%s \n", strroot.c_str());
std::string str = strroot + "_RE_Resultimg.png";
if (!result->resultimg.empty())
{
cv::imwrite(str, result->resultimg);
}
std::string str123 = strroot + "_RE_CutImg.png";
if (!result->cutSrcimg.empty())
{
cv::imwrite(str123, result->cutSrcimg);
}
std::string str123r = strroot + "_RE_CutDrawImg.png";
if (!result->SrcResultImg.empty())
{
cv::imwrite(str123r, result->SrcResultImg);
}
std::string strMask = strroot + "_RE_AIMask.png";
if (!result->resultMaskImg.empty())
{
cv::imwrite(strMask, result->resultMaskImg);
}
std::string str_qx;
printf("result->qxImageResult.size() %ld \n", result->qxImageResult.size());
for (int i = 0; i < result->qxImageResult.size(); i++)
{
std::string str = strroot + "_RE_" + std::to_string(i) + "_Src.png";
if (!result->qxImageResult.at(i).srcImg.empty())
{
cv::imwrite(str, result->qxImageResult.at(i).srcImg);
}
str_qx = strroot_qx + result->qxImageResult.at(i).strTypeName + "/";
printf("-1-- %s\n", str_qx.c_str());
_sysmkdirs_1(str_qx);
str_qx += str_saveName + "_RE_" + std::to_string(i) + "_Src.png";
// printf("-2-- %s\n", str_qx.c_str());
if (!result->qxImageResult.at(i).srcImg.empty())
{
cv::imwrite(str_qx, result->qxImageResult.at(i).srcImg);
}
str_qx = strroot_qx + result->qxImageResult.at(i).strTypeName + "/";
str_qx += str_saveName + "_RE_" + std::to_string(i) + "_Small.png";
if (!result->qxImageResult.at(i).resizeImg.empty())
{
cv::imwrite(str_qx, result->qxImageResult.at(i).resizeImg);
}
{
str_qx = strroot_qx + result->qxImageResult.at(i).strTypeName + "/";
str_qx += str_saveName + "_RE_" + std::to_string(i) + "_AI_In.png";
if (!result->qxImageResult.at(i).AI_in_Img.empty())
{
cv::imwrite(str_qx, result->qxImageResult.at(i).AI_in_Img);
}
str_qx = strroot_qx + result->qxImageResult.at(i).strTypeName + "/";
str_qx += str_saveName + "_RE_" + std::to_string(i) + "_AI_In_mask.png";
if (!result->qxImageResult.at(i).AI_out_img.empty())
{
cv::imwrite(str_qx, result->qxImageResult.at(i).AI_out_img);
}
}
// printf("-1111-- %s\n", str_qx.c_str());
std::string str1 = strroot + "_RE_" + std::to_string(i) + "_Small.png";
if (!result->qxImageResult.at(i).resizeImg.empty())
{
cv::imwrite(str1, result->qxImageResult.at(i).resizeImg);
}
}
printf("result->YS_ImageResult.size() %ld\n", result->YS_ImageResult.size());
for (int i = 0; i < result->YS_ImageResult.size(); i++)
{
std::string str = strroot + "_RE_" + std::to_string(i) + "_YS_Src.png";
if (result->YS_ImageResult.at(i).srcImg.empty())
{
printf("resqwwwwwwwwwwwwwwwult->YS_ImageResult.size() %ld \n", result->YS_ImageResult.size());
}
if (!result->YS_ImageResult.at(i).srcImg.empty())
{
cv::imwrite(str, result->YS_ImageResult.at(i).srcImg);
}
str_qx = strroot_qx + result->YS_ImageResult.at(i).strTypeName + "/";
// printf("-3-- %s\n", str_qx.c_str());
_sysmkdirs_1(str_qx);
str_qx += str_saveName + "_RE_" + std::to_string(i) + "_YS_Src.png";
// printf("-4-- %s\n", str_qx.c_str());
if (!result->YS_ImageResult.at(i).srcImg.empty())
{
cv::imwrite(str_qx, result->YS_ImageResult.at(i).srcImg);
}
str_qx = strroot_qx + result->YS_ImageResult.at(i).strTypeName + "/";
str_qx += str_saveName + "_RE_" + std::to_string(i) + "_YS_Small.png";
if (!result->YS_ImageResult.at(i).resizeImg.empty())
{
cv::imwrite(str_qx, result->YS_ImageResult.at(i).resizeImg);
}
{
str_qx = strroot_qx + result->YS_ImageResult.at(i).strTypeName + "/";
str_qx += str_saveName + "_RE_" + std::to_string(i) + "_YS_AI_In.png";
if (!result->YS_ImageResult.at(i).AI_in_Img.empty())
{
cv::imwrite(str_qx, result->YS_ImageResult.at(i).AI_in_Img);
}
str_qx = strroot_qx + result->YS_ImageResult.at(i).strTypeName + "/";
str_qx += str_saveName + "_RE_" + std::to_string(i) + "_YS_AI_In_mask.png";
if (!result->YS_ImageResult.at(i).AI_out_img.empty())
{
cv::imwrite(str_qx, result->YS_ImageResult.at(i).AI_out_img);
}
}
// printf("-1111-- %s\n", str_qx.c_str());
std::string str1 = strroot + "_RE_" + std::to_string(i) + "_YS_Small.png";
if (!result->YS_ImageResult.at(i).resizeImg.empty())
{
cv::imwrite(str1, result->YS_ImageResult.at(i).resizeImg);
}
}
return 0;
}
int deal::writeLog(std::string strSavePath, std::vector<std::string> logList)
{
std::string str = strSavePath + ".txt";
// 打开文件
std::ofstream outFile(str);
// 检查文件是否成功打开
if (!outFile)
{
std::cerr << "Failed to open file." << std::endl;
return 1;
}
// 将vector中的内容写入文件
for (const auto &str : logList)
{
// printf("%s \n",str.c_str());
outFile << str << std::endl;
}
// 关闭文件
outFile.close();
return 0;
}
int deal::WriteJsonString(std::string strSavePath, std::string strjson)
{
std::string str = strSavePath + ".json";
// 打开文件
std::ofstream outFile(str);
// 检查文件是否成功打开
if (!outFile)
{
std::cerr << "Failed to open file." << std::endl;
return 1;
}
// 将vector中的内容写入文件
outFile << strjson << std::endl;
// 关闭文件
outFile.close();
return 0;
}
void deal::ResultThread(int id)
{
std::vector<int> vi;
int startidx = m_CPUInfo[THREAD_CPU_Main_saveImg].startIdx;
int cpunum = m_CPUInfo[THREAD_CPU_Main_saveImg].num;
// for (int i = 0; i < cpunum; i++)
// {
// vi.push_back(startidx + i);
// }
vi.push_back(startidx + id);
auto nRet = set_cpu_id(vi);
printf("THREAD_CPU_Main_saveImg %d bind cpu ret %d startidx %d num %d\n", id, nRet, startidx + id, 1);
int re = 0;
cv::Mat detImg;
int kkkkk = 0;
static int saveidx = 0;
while (!m_bExit)
{
std::shared_ptr<CheckResult> dealResult;
mutex_Result_list.lock();
if (m_Result_list.size() > 0)
{
dealResult = m_Result_list.front();
m_Result_list.pop();
if (m_Result_list.size() > 10)
{
printf("Result_list size %ld \n", m_Result_list.size());
}
mutex_Result_list.unlock();
}
else
{
mutex_Result_list.unlock();
usleep(10000);
continue;
}
{
updataResltInfo(dealResult);
}
{
if (true)
{
// 存图
// std::string savepath = "/home/aidlux/BOE/Detsave/" + runConfig.filePath + "/";
// saveImg(savepath, dealResult);
saveImg("/home/aidlux/BOE/ZB_SOCKET/Detsave/", dealResult);
}
{
// 存 检测统计 日志
mutex_DetResult_.lock();
m_DetResult.print(false);
std::string strlog = "/home/aidlux/BOE/ZB_SOCKET/ResultImg/";
if (m_strCurDate != "")
{
strlog += m_strCurDate;
strlog += "/result";
}
else
{
strlog += "/result";
}
// 确保日志目录存在(否则 writeLog 报 Failed to open file)
_sysmkdirs_1(strlog.substr(0, strlog.find_last_of('/')));
writeLog(strlog, m_DetResult.strlist);
mutex_DetResult_.unlock();
}
}
usleep(5 * 1000);
}
}
int deal::set_cpu_id(const std::vector<int> &cpu_set_vec)
{
// for cpu affinity
int nRet = 0;
#ifdef __linux
cpu_set_t _cur_cpu_set;
CPU_ZERO(&_cur_cpu_set);
for (auto _id : cpu_set_vec)
{
CPU_SET(_id, &_cur_cpu_set);
}
if (0 > pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &_cur_cpu_set))
{
perror("set cpu affinity failed: ");
printf("Warning: set cpu affinity failed ... ...\n");
nRet = -1;
}
#endif //__linux
return nRet;
}
void deal::GetDealResultToQueu()
{
// 处理结果
std::shared_ptr<CheckResult> checkResult;
if (!m_pALLImgCheckAnalysisy)
{
return;
}
int re = m_pALLImgCheckAnalysisy->GetCheckReuslt(checkResult);
if (re == 0)
{
mutex_Result_list.lock();
m_Result_list.push(checkResult);
mutex_Result_list.unlock();
}
else
{
printf("Check error >>>>>>>>>>>>>>>>> \n");
}
return;
}
bool deal::ReadSystemConfig(const std::string &strPath)
{
printf("Reading system config %s\n", strPath.c_str());
Json::CharReaderBuilder builder;
builder["collectComments"] = true;
Json::Value root;
std::string err;
std::ifstream ifs(strPath);
if (!ifs.is_open())
{
printf("error:file is open\n");
return false;
}
if (!Json::parseFromStream(builder, ifs, &root, &err))
{
printf("error:parseFromStream\n");
return false;
}
m_system_param.Use_CPU_StartIdx = root["Use_CPU_StartIdx"].asInt();
// path
m_system_param.Analysis_Config_path = root["Analysis_Config_path"].asString();
m_system_param.config_Root_Path = root["Config_Root_Path"].asString();
m_system_param.Check_Config_path = root["Check_Config_path"].asString();
m_system_param.preCheckImg_Path = root["preCheckImg_Path"].asString();
m_system_param.preCHeck_YX = root["preCHeck_YX"].asInt();
m_system_param.preCHeck_defect = root["preCHeck_defect"].asInt();
m_nCurUseCPUIDX = m_system_param.Use_CPU_StartIdx;
return m_system_param.valid();
}
int deal::GetDetImageInfo(std::string strProductID, std::string strSearchImg, std::vector<JC_IMAGE_INFO_> &jcImageInfoList)
{
// -f 批量跑新格式: 产品目录下 input 子目录, 只取 _src 原图
// (如 1M10121554R2B3_buckle_down2_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_SOCKET_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";
cv::glob(strs1, img_paths, true);
// printf("%ld \n", img_paths.size());
jcImageInfoList.erase(jcImageInfoList.begin(), jcImageInfoList.end());
// 遍历每一套图片
for (int idx = 0; idx < img_paths.size(); idx++)
{
// printf("---- %d / %d %s----\n", idx, m_OffLineCheckImgNameList.size(), m_OffLineCheckImgNameList.at(idx).c_str());
std::string path = img_paths.at(idx);
JC_IMAGE_INFO_ tem;
int re = 0;
{
re = GetImgInfo_POL_ET(path, &tem);
if (re != 0)
{
continue;
}
}
tem.strProductID = strProductID;
jcImageInfoList.push_back(tem);
}
return 0;
}
int deal::GetImgInfo_POL_ET(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo)
{
if (pImageInfo == NULL)
{
return 1;
}
string strName = "";
size_t lastUnderscore;
strName = ExtractFileNameWithoutExtension(strImgPath);
printf("strName %s \n", strName.c_str());
std::string strImageChannel;
// 使用 find 检查是否包含 "CA" 或 "TA"
if (strName.find("CA") != std::string::npos || strName.find("CF") != std::string::npos)
{
strImageChannel = "CA";
}
else if (strName.find("TA") != std::string::npos || strName.find("TFT") != std::string::npos)
{
strImageChannel = "TA";
}
else
{
return 1;
}
printf("strImageChannel %s\n", strImageChannel.c_str());
pImageInfo->strchannelName = strImageChannel;
pImageInfo->strName = strName;
pImageInfo->strPath = strImgPath;
pImageInfo->strCamID = strImageChannel;
printf("strImgPath %s strName %s strChannel %s\n", strImgPath.c_str(), strName.c_str(), strImageChannel.c_str());
return 0;
}
int deal::GetImgInfo_POL_ET_PNG(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo)
{
if (pImageInfo == NULL)
{
return 1;
}
string strImageChannel = ExtractFileNameWithoutExtension(strImgPath);
printf("strImageChannel %s\n", strImageChannel.c_str());
std::string strChannle = m_image_ReadChannel.strDetName(strImageChannel);
if (strChannle == "")
{
return 1;
}
pImageInfo->strchannelName = strChannle;
pImageInfo->strName = strChannle;
pImageInfo->strPath = strImgPath;
pImageInfo->strCamID = "0";
// printf("strImgPath %s strChannel %s\n", strImgPath.c_str(), strChannle.c_str());
// 使用 find 函数检查是否包含 "_左"
if (strImgPath.find("_工位右") != std::string::npos)
{
pImageInfo->strCamID = "1";
;
}
return 0;
}
// -f 批量跑新格式: 解析图片名组装产品信息
// 图片名示例: 1M10121554R2B3_buckle_down2_src.jpg
// 产品ID: 第一个 '_' 之前的部分 (1M10121554R2B3)
// 相机名/通道名: 只处理文件名包含 buckle 且后缀为 _src 的原图
int deal::GetImgInfo_SOCKET_SRC(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo)
{
if (pImageInfo == NULL)
{
return 1;
}
std::string strName = ExtractFileNameWithoutExtension(strImgPath);
// 只处理文件名包含 buckle 的图片, 跳过 t_face_bright/t_face_dark 等其它相机
if (strName.find("buckle") == std::string::npos)
{
printf("GetImgInfo_SOCKET_SRC: no buckle in name, skip %s\n", strImgPath.c_str());
return 1;
}
// 只处理后缀为 _src 的原图, 跳过 _roi 等其它图
const std::string strSrcSuffix = "_src";
if (strName.size() <= strSrcSuffix.size() ||
strName.compare(strName.size() - strSrcSuffix.size(), strSrcSuffix.size(), strSrcSuffix) != 0)
{
return 1;
}
// 相机名同时作为通道名
std::string strCamName = "buckle";
// 产品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 = strCamName;
pImageInfo->strName = strName;
pImageInfo->strPath = strImgPath;
printf("strImgPath %s strName %s strProductID %s strCam %s\n",
strImgPath.c_str(), strName.c_str(), strProductID.c_str(), strCamName.c_str());
return 0;
}
int deal::InsertDetResult(ReadImgInfo tem)
{
std::lock_guard<std::mutex> lock(mtx_List[Mutex_Type_DetResult]);
m_DetResultList.push_back(tem);
return 0;
}
int deal::SendImgToCheck(std::shared_ptr<JC_IMAGE_INFO_> pDetImageInfo, IN_IMG_Status_ status)
{
if (pDetImageInfo == nullptr)
{
return -1;
}
if (status == IN_IMG_Status_End)
{
std::shared_ptr<shareImage> tem = std::make_shared<shareImage>();
tem->strImgProductID = pDetImageInfo->strProductID;
tem->Status = -1;
if (m_pALLImgCheckAnalysisy)
{
m_pALLImgCheckAnalysisy->SetDataRun_SharePtr(tem);
}
return 0;
}
std::shared_ptr<shareImage> tem = std::make_shared<shareImage>();
tem->strChannel = pDetImageInfo->strchannelName;
string cur_time = CheckUtil::getCurTimeHMS();
printf("[%s]========SendImgToCheck============ %s \n", cur_time.c_str(), tem->strChannel.c_str());
// cv::imwrite(tem->strChannel+".png",pDetImageInfo->img);
tem->nImgBigIdx = 0;
tem->strImgName = pDetImageInfo->strName;
tem->strImgProductID = pDetImageInfo->strProductID;
tem->imgstr = m_strCurDate;
tem->strCameraName = pDetImageInfo->strCamID;
tem->camera_ID = 0;
if (m_nSaveDetprocessImg == 1)
{
tem->otherValue = 9;
}
if (pDetImageInfo->img_B.empty())
{
tem->bCam_AB = false;
}
else
{
tem->bCam_AB = true;
tem->img_B = pDetImageInfo->img_B;
}
tem->getImgTimeMs = getcurTime();
tem->readImg_start = pDetImageInfo->readImg_start;
tem->readImg_end = pDetImageInfo->readImg_end;
tem->Status = status;
tem->Det_Mode = DET_MODE_Det;
if ( runConfig.det_Type == RUNTYPE_RUN_Merge_Img)
{
tem->Det_Mode = DET_MODE_MergeImg;
}
tem->img = pDetImageInfo->img;
if (m_nSaveDetprocessImg == 1)
{
tem->bsaveProcessImg = true;
}
if (runConfig.bSaveProcessImg)
{
tem->bsaveProcessImg = true;
}
int re = 0;
if (m_pALLImgCheckAnalysisy)
{
re = m_pALLImgCheckAnalysisy->SetDataRun_SharePtr(tem);
}
return re;
}
int deal::ReJson_ALL()
{
printf(">>> ReJson ALL start \n");
// 1、获取所有的json
std::vector<cv::String> img_paths;
cv::glob(runConfig.filePath + "/*.json", img_paths, true);
if (img_paths.size() <= 0)
{
printf("json file is NULL \n");
return 1;
/* code */
}
// 用map存储每个id对应的vector
std::unordered_map<std::string, std::vector<cv::String>> ProductJsonList;
// 遍历路径并按照ID分组
for (const auto &path : img_paths)
{
// 获取路径中的 ID 部分(即文件夹名部分)
size_t start_pos = path.find_last_of("/") + 1;
size_t end_pos = path.find("_", start_pos);
std::string id = path.substr(start_pos, end_pos - start_pos);
// printf("id %s\n",id.c_str());
// 将文件路径加入对应 ID 的vector中
ProductJsonList[id].push_back(path);
}
for (const auto &product : ProductJsonList)
{
std::cout << product.first << " => " << product.second.size() << std::endl;
std::vector<Json_Det_Path> jsonList;
std::string strProductName = product.first;
for (const auto &str : product.second)
{
{
// 2、获取第一个 名称
std::string strPath = str;
size_t lastSlashPos = strPath.find_last_of('/');
// 提取文件名(从最后一个斜杠之后的部分)
std::string filename = strPath.substr(lastSlashPos + 1);
// 查找文件名中的第一个下划线位置
size_t firstUnderscorePos = filename.find('_');
// 提取文件名中的名称部分(下划线之前的字符串)
std::string strProduct = filename.substr(0, firstUnderscorePos);
// printf("strProduct %s \n", strProduct.c_str());
if (strProduct == strProductName)
{
Json_Det_Path tem;
tem.strPath_Json = str;
tem.strPath_CutImg = str;
size_t pos = tem.strPath_CutImg.rfind(".json");
if (pos != std::string::npos)
{
// 替换 ".json" 为 "_RE_CutImg.png"
tem.strPath_CutImg.replace(pos, 5, "_RE_CutImg.png");
}
std::cout << " Path: " << tem.strPath_Json << std::endl;
std::cout << " Path: " << tem.strPath_CutImg << std::endl;
jsonList.push_back(tem);
}
}
}
ReJson_product(jsonList, strProductName);
}
// 获取要检测的 json 图片 list
printf(">>>>>>>>>>>>>>>>>>>> rejson ALL is Complete \n");
return 0;
}
int deal::DetImg()
{
// 单张检测
if (runConfig.det_Type == RUNTYPE_RUN_Pre || runConfig.det_Type == RUNTYPE_RUN_Merge_Img)
{
m_nReadThread_type = READ_THREAD_TYPE_READIMG;
StartThread(THREAD_RUN_Only_ReadImg);
// -8 循环执行:像 -f 批量一样,线程只启动一次,内部重复跑同一套图
do
{
preCheck();
usleep(10 * 1000);
} while (runConfig.bLoop);
return 0;
}
if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST ||
runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI)
{
std::string str1 = "/home/aidlux/BOE/Edge/Big/";
_sysmkdirs_1(str1);
str1 = "/home/aidlux/BOE/Edge/Result/";
_sysmkdirs_1(str1);
str1 = "/home/aidlux/BOE/Edge/Smasll/";
_sysmkdirs_1(str1);
m_nReadThread_type = READ_THREAD_TYPE_READIMG;
StartThread(THREAD_RUN_Only_ReadImg);
Det_Funtion_Test();
return 0;
}
m_nReadThread_type = READ_THREAD_TYPE_READIMG;
// 文件夹套图处理
if (RUNTYPE_RUN_File == runConfig.det_Type)
{
std::string str = runConfig.filePath;
LoadProductID(str);
}
// 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)
{
// 获取要检测的 json 图片 list
int temstatus = IN_IMG_Status_Start;
int PushNum = 0;
// 开始逐一复测
for (int i = 0; i < jsonList.size(); i++)
{
std::string strJson = jsonList.at(i).strPath_Json;
std::string strimg = jsonList.at(i).strPath_CutImg;
std::ifstream file(strJson);
if (!file.is_open())
{
std::cerr << "Unable to open file!" << std::endl;
return -1;
}
// 读取文件内容到 std::string
std::stringstream buffer;
buffer << file.rdbuf();
std::string json_str = buffer.str(); // 获取 JSON 文件的内容作为字符串
// 显示读取到的 JSON 字符串
// std::cout << "JSON content: " << json_str << std::endl;
cv::Mat cutimg = cv::imread(strimg, cv::IMREAD_UNCHANGED);
int f0 = strJson.rfind('_');
int f1 = strJson.rfind('.');
int f2 = strJson.rfind('/');
std::string str1 = strJson.substr(f2 + 1, f1 - f2 - 1);
std::string str2 = strJson.substr(f0 + 1, f1 - f0 - 1);
// std::string str3 = strJson.substr(f2 + 1, strJson.size() - f2);
std::cout << str1 << std::endl;
std::cout << str2 << std::endl;
if (str1.find("CA") != std::string::npos)
{
str2 = "CA";
}
else if (str1.find("TA") != std::string::npos)
{
str2 = "TA";
}
else
{
continue;
}
std::cout << "start " << strJson << std::endl;
std::shared_ptr<CheckResult> result;
// 多线程 互斥 作用域
{
std::shared_ptr<shareImage> temdet = std::make_shared<shareImage>();
temdet->strCameraName = str2;
temdet->strImgProductID = strProductName;
temdet->strChannel = str2;
temdet->strImgName = str1;
std::cout << "strChannel " << temdet->strChannel << std::endl;
temdet->Det_Mode = DET_MODE_ReJson;
temdet->img = cutimg;
temdet->resultJson = json_str;
{
if (i == 0)
{
temdet->Status = IN_IMG_Status_Start;
}
else if (i == jsonList.size() - 1)
{
temdet->Status = IN_IMG_Status_End;
}
else
{
temdet->Status = IN_IMG_Status_Other;
}
}
int re = m_pALLImgCheckAnalysisy->SetDataRun_SharePtr(temdet);
if (re != 0)
{
printf("reJson Error %d \n", re);
continue;
}
PushNum++;
// 结果异常
}
}
int getresultNum = 0;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟消费过程
// 处理结果
std::shared_ptr<CheckResult> checkResult;
int re = m_pALLImgCheckAnalysisy->GetCheckReuslt(checkResult);
printf("********************** Get result %d -- %s \n", getresultNum, checkResult->in_shareImage->strChannel.c_str());
saveImg("/home/aidlux/BOE/ReJsonresult/", checkResult);
getresultNum++;
if (getresultNum == PushNum)
{
break;
}
}
return 0;
}
void deal::GetResultThread()
{
std::vector<int> vi;
vi.push_back(18);
auto nRet = set_cpu_id(vi);
printf("bind cpu ret %d, %d\n", nRet, 18);
int re = 0;
int nsleep1 = 2 * 1000;
while (!m_bExit)
{
// 1、拷贝检测结果到队列
GetDealResultToQueu();
usleep(nsleep1);
}
}
void deal::ReadImgThread(int id)
{
int nsleep1 = 200 * 1000;
int readThreadIdx = id;
while (!m_bExit)
{
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟消费过程
// 读图模式
if (READ_THREAD_TYPE_READIMG == m_nReadThread_type)
{
Thread_ReadImg(readThreadIdx);
}
else if (READ_THREAD_Detect == m_nReadThread_type)
{
}
}
}
int deal::updataResltInfo(std::shared_ptr<CheckResult> result)
{
mutex_DetResult_.lock();
std::string productID = result->in_shareImage->strImgProductID;
std::string imgName = result->in_shareImage->strChannel;
// printf("add productID %s imgName %s %d\n", productID.c_str(), imgName.c_str(), result->nresult);
long t1 = getcurTime();
m_DetResult.updata(productID, imgName, result->nresult, t1);
for (int i = 0; i < ERROR_TYPE_COUNT; i++)
{
if (result->defectResultList[i].nresult == 1)
{
m_DetResult.update_qx(result->defectResultList[i].keyName, result->defectResultList[i].num);
}
}
mutex_DetResult_.unlock();
return 0;
}
int deal::SetStatus(int type, int status)
{
std::lock_guard<std::mutex> lock(mtx_List[Mutex_Type_DetStatus]);
m_DetStatusList[type] = status;
return 0;
}
int deal::GetStatus(int type)
{
std::lock_guard<std::mutex> lock(mtx_List[Mutex_Type_DetStatus]);
return m_DetStatusList[type];
}
bool deal::IsStatus(int type, int status)
{
std::lock_guard<std::mutex> lock(mtx_List[Mutex_Type_DetStatus]);
if (m_DetStatusList[type] == status)
{
return true;
}
return false;
}
int deal::SetStatus_List(int idx, Thread_Status_ status)
{
std::lock_guard<std::mutex> lock(mtx_List[Mutex_Type_ReadImgThread]);
m_nReadStausList[idx] = status;
return 0;
}
int deal::GetStatus_List(int idx)
{
std::lock_guard<std::mutex> lock(mtx_List[Mutex_Type_ReadImgThread]);
return m_nReadStausList[idx];
}
bool deal::IsStatus_List(int idx, Thread_Status_ status)
{
std::lock_guard<std::mutex> lock(mtx_List[Mutex_Type_ReadImgThread]);
if (idx < 0 || idx >= READ_IMG_THREAD_NUM)
{
}
else
{
if (m_nReadStausList[idx] == status)
{
return true;
}
}
return false;
}
int deal::setReadThreadStart()
{
for (int i = 0; i < READ_IMG_THREAD_NUM; i++)
{
SetStatus_List(i, Thread_Status_READY);
}
return 0;
}
int deal::GetReadImgCompleteThreadIdx()
{
for (int i = 0; i < READ_IMG_THREAD_NUM; i++)
{
if (IsStatus_List(i, Thread_Status_COMMPLET))
{
return i;
}
}
return -1;
}
bool deal::IsALLComplete()
{
std::lock_guard<std::mutex> lock(mtx_List[Mutex_Type_DetStatus]);
for (size_t i = 0; i < READ_IMG_THREAD_NUM; i++)
{
if (m_nReadStausList[i] == ReadImg_Status_COMMPLET)
{
return false;
}
}
return true;
}
int deal::InitCPUIDX()
{
int start = 3;
m_CPUInfo[THREAD_CPU_Main_Det].set(start, 4);
start += 4;
m_CPUInfo[THREAD_CPU_Main_readImg].set(start, READ_IMG_THREAD_NUM);
start += READ_IMG_THREAD_NUM;
m_CPUInfo[THREAD_CPU_Main_saveImg].set(start, Save_IMG_THREAD_NUM);
start += Save_IMG_THREAD_NUM;
// 注意:检测线程的核带已下沉到库内部(AlgorithmModule/include/Define_Base.h 的
// CHECK_CPU_BAND_START / CHECK_CPU_BAND_NUM = 24 / 8),下面这项仅为兼容赋值,不再影响检测线程绑核。
m_CPUInfo[THREAD_CPU_CheckSo].set(start, 15);
return 0;
}
void deal::Thread_ReadImg(int id)
{
if (!IsStatus_List(id, Thread_Status_READY))
{
return;
}
int re = 0;
std::shared_ptr<JC_IMAGE_INFO_> pImageInfo = nullptr;
re = GetReadImgInfo(pImageInfo);
if (pImageInfo == nullptr)
{
printf("pImageInfo == nullptr=================id %d=============\n", id);
return;
}
// 原图保持原始通道(彩色图不再强制转灰度),结果图/缺陷小图才能显示真实色彩
pImageInfo->img = cv::imread(pImageInfo->strPath, cv::IMREAD_UNCHANGED);
// cv::imwrite(pImageInfo->strchannelName + "_A_ssssde.png", pImageInfo->img);
if (pImageInfo->strPath_B != "")
{
pImageInfo->img_B = cv::imread(pImageInfo->strPath_B, cv::IMREAD_UNCHANGED);
// cv::imwrite(pImageInfo->strchannelName + "_B_sssde.png", pImageInfo->img_B);
}
m_ReadImgThread_Result[id] = pImageInfo;
// 线程完成读图,设置现场状态为 完成
SetStatus_List(id, Thread_Status_COMMPLET);
// printf("Thread_ReadImg=================id %d %s=============\n", id, pImageInfo->strPath.c_str());
}
int deal::InsertReadImgInfo(std::shared_ptr<JC_IMAGE_INFO_> pImageInfo)
{
std::lock_guard<std::mutex> lock(mutex_ReadImgList);
m_ReadImg_queue.push(pImageInfo);
cv_ReadImgList.notify_one(); // 唤醒等待的线程
return 0;
}
int deal::GetReadImgInfo(std::shared_ptr<JC_IMAGE_INFO_> &pImageInfo)
{
// printf("===============waite img info ===============\n");
std::unique_lock<std::mutex> lock(mutex_ReadImgList);
cv_ReadImgList.wait(lock, [this]()
{ return !m_ReadImg_queue.empty(); });
pImageInfo = m_ReadImg_queue.front(); // 获取队首数据
if (pImageInfo == NULL)
{
return 1;
}
m_ReadImg_queue.pop(); // 弹出队首数据
return 0;
}
bool deal::isValidString(const std::string &str)
{
// 检查字符串长度是否为10
if (str.length() < 14 || str.length() > 19)
{
return false;
}
// 检查字符串中的每个字符是否都是字母或数字
for (char c : str)
{
if (!std::isalnum(c))
{ // 如果字符不是字母或数字
return false;
}
}
// 字符串满足条件
return true;
}
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";
std::cout << str_bmp << std::endl;
cv::glob(str_bmp, img_paths, true);
for (int i = 0; i < img_paths.size(); i++)
{
std::string path = img_paths[i];
// 提取所有文件夹名称
std::vector<std::string> allDirectories = extractAllDirectories(path);
std::string strSN = "";
// 输出所有文件夹名称
std::string strAllPath = "/";
for (const auto &dir : allDirectories)
{
// std::cout << dir << std::endl;
strAllPath += dir;
if (isValidString(dir))
{
strSN = dir;
break;
}
strAllPath += "/";
}
bool bh = false;
for (int j = 0; j < m_product_ID_List.size(); j++)
{
if (m_product_ID_List.at(j) == strAllPath)
{
bh = true;
break;
}
}
if (!bh)
{
if (m_product_ID_List.size() < m_nTestNum)
{
m_product_ID_List.push_back(strAllPath);
std::cout << strAllPath << std::endl;
}
}
}
}
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()
{
// -8 循环执行:每次重新加载产品列表,重复跑同一批产品
if (runConfig.bLoop && runConfig.filePath != "")
{
LoadProductID(runConfig.filePath);
}
size_t totalSize = m_product_ID_List.size();
if (totalSize > 0)
{
m_DetResult.Init();
/* code */
}
for (size_t idx = 0; idx < totalSize; idx++)
{
string cur_time = CheckUtil::getCurTimeHMS();
printf("[%s]>>> %zu / %zu %s----start \n", cur_time.c_str(), idx, totalSize, m_product_ID_List.at(idx).c_str());
long t1, t2;
t1 = getcurTime();
Det_OneProduct_Cell_ET(m_product_ID_List.at(idx), idx);
t2 = getcurTime();
string cur_time_end = CheckUtil::getCurTimeHMS();
printf("[%s]>>> %zu / %zu %s----End use time %ld\n", cur_time_end.c_str(), idx, totalSize, m_product_ID_List.at(idx).c_str(), t2 - t1);
}
if (totalSize > 0)
{
// 等待所有检测都完成
while (true)
{
usleep(1000 * 1000 * 10);
printf("len %zu \n", m_Result_list.size());
if (m_Result_list.size() <= 0)
{
printf("check =============== complete \n");
break;
}
}
}
m_product_ID_List.erase(m_product_ID_List.begin(), m_product_ID_List.end());
m_product_ID_List.clear();
return 0;
}
int deal::Det_OneProduct_Cell_ET(std::string strProductName, int Idx)
{
std::string strProductID = GetFileName(strProductName);
// -f 批量跑新格式: 产品目录名为 <产品ID>_<时间戳>(如 1M10121554R2B3_20261012.151453.582176)
// 取第一个 '_' 之前的部分作为产品ID; 旧格式目录名本身即产品ID(无 '_')不受影响
size_t nProductIDPos = strProductID.find('_');
if (nProductIDPos != std::string::npos)
{
strProductID = strProductID.substr(0, nProductIDPos);
}
// 获取图片路径
std::vector<JC_IMAGE_INFO_> detImgInfoList;
string strSearchImg = strProductName;
int re = GetDetImageInfo(strProductID, strSearchImg, detImgInfoList);
if (re != 0)
{
return re;
}
// 没有图片
if (detImgInfoList.size() <= 0)
{
return 1;
}
// 读图现场都开启
setReadThreadStart();
int AllImgNum = detImgInfoList.size();
// 遍历所有图片 开始读图处理
for (int i = 0; i < detImgInfoList.size(); i++)
{
std::shared_ptr<JC_IMAGE_INFO_> tem = std::make_shared<JC_IMAGE_INFO_>();
tem->copy(detImgInfoList.at(i));
InsertReadImgInfo(tem);
}
m_DetResult.startTime_S = getcurTime();
IN_IMG_Status_ temstatus = IN_IMG_Status_Start;
std::shared_ptr<JC_IMAGE_INFO_> tempDetImageInfo = nullptr;
Det_One_Result_Info tem_one;
tem_one.Product_ID = strProductID;
tem_one.result = 0;
long ts = getcurTime();
tem_one.time_s = ts;
int GetImgNum = 0;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟消费过程
int ThreadIdx = GetReadImgCompleteThreadIdx();
if (ThreadIdx < 0)
{
continue;
}
std::shared_ptr<JC_IMAGE_INFO_> pDetImageInfo = nullptr;
pDetImageInfo = m_ReadImgThread_Result[ThreadIdx];
// 开始送到检测进行处理
if (pDetImageInfo != nullptr)
{
// printf(">>> %s----start \n", pDetImageInfo->strName.c_str());
tempDetImageInfo = pDetImageInfo;
int re = SendImgToCheck(pDetImageInfo, temstatus);
if (re != 0)
{
continue;
}
Det_single_img_Result_Info tem_single;
tem_single.name = pDetImageInfo->strchannelName;
tem_single.result = -1;
tem_one.img_result_list.push_back(tem_single);
}
SetStatus_List(ThreadIdx, Thread_Status_READY);
GetImgNum++;
if (IN_IMG_Status_Start == temstatus)
{
temstatus = IN_IMG_Status_Other;
}
// 图是否都读取完了。
bool bReadCompleted = false;
if (GetImgNum >= AllImgNum)
{
bReadCompleted = true;
}
// 退出
if (bReadCompleted)
{
SendImgToCheck(tempDetImageInfo, IN_IMG_Status_End);
break;
}
}
m_DetResult.one_result_list.push_back(tem_one);
m_DetResult.det_num_all++;
// if (m_DetResult.det_num_all == 1)
// {
// }
// printf("startTime_S==== %ld \n", m_DetResult.startTime_S);
// getchar();
return 0;
}
int deal::Det_Funtion_Test()
{
int re = 0;
if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST ||
runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI)
{
Det_Funtion_Edge();
return 0;
}
// 获取图片
return 0;
}
int deal::Det_Funtion_Edge()
{
int imgNum = 0;
std::string strchannel = "L255";
std::string str = runConfig.filePath + "/*" + strchannel + ".tif";
{
std::cout << str << std::endl;
m_OffImageSNPathList.erase(m_OffImageSNPathList.begin(), m_OffImageSNPathList.end());
cv::glob(str, m_OffImageSNPathList, true);
}
imgNum = m_OffImageSNPathList.size();
if (imgNum > m_nTestNum && m_nTestNum > 0)
{
imgNum = m_nTestNum;
}
printf("Img Num %d \n", imgNum);
if (imgNum <= 0)
{
return 0;
}
// 读图现场都开启
setReadThreadStart();
int AllImgNum = imgNum;
// 遍历所有图片 开始读图处理
for (int i = 0; i < imgNum; i++)
{
std::shared_ptr<JC_IMAGE_INFO_> tem = std::make_shared<JC_IMAGE_INFO_>();
tem->strPath = m_OffImageSNPathList.at(i);
tem->strchannelName = strchannel;
InsertReadImgInfo(tem);
}
int GetImgNum = 0;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟消费过程
int ThreadIdx = GetReadImgCompleteThreadIdx();
if (ThreadIdx < 0)
{
continue;
}
std::shared_ptr<JC_IMAGE_INFO_> pDetImageInfo = nullptr;
pDetImageInfo = m_ReadImgThread_Result[ThreadIdx];
SetStatus_List(ThreadIdx, Thread_Status_READY);
GetImgNum++;
// 开始送到检测进行处理
if (pDetImageInfo == nullptr)
{
continue;
}
// printf("GetImgNum:111111111111111 %d\n", GetImgNum);
{
std::shared_ptr<CheckResult> result;
std::shared_ptr<shareImage> temdet = std::make_shared<shareImage>();
if (m_nSaveDetprocessImg == 1)
{
temdet->otherValue = 9;
}
temdet->strImgName = "test";
temdet->strImgProductID = "test";
temdet->strChannel = strchannel;
if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST ||
runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI)
{
temdet->Det_Mode = DET_MODE_EDGE;
if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI)
{
temdet->ninstruct = 999;
}
}
temdet->img = pDetImageInfo->img;
m_pALLImgCheckAnalysisy->CheckImg(temdet, result);
// 结果异常
}
// 图是否都读取完了。
if (GetImgNum >= AllImgNum)
{
break;
}
}
return 0;
}
void deal::DealImg()
{
// 线程送图处理:
std::vector<int> vi;
int startidx = m_CPUInfo[THREAD_CPU_Main_Det].startIdx;
int cpunum = m_CPUInfo[THREAD_CPU_Main_Det].num;
for (int i = 0; i < cpunum; i++)
{
vi.push_back(startidx + i);
}
auto nRet = set_cpu_id(vi);
printf("THREAD_CPU_Main_Det bind cpu ret %d startidx %d num %d\n", nRet, startidx, cpunum);
int re = 0;
while (!m_bExit)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟消费过程
re = DelImg_Cell_ET();
}
}
// 提取所有文件夹名称函数
std::vector<std::string> deal::extractAllDirectories(const std::string &path)
{
std::vector<std::string> directories;
std::string directory;
// 遍历路径中的每个字符
for (char c : path)
{
// 如果遇到路径分隔符,则将当前文件夹名称存储起来
if (c == '/' || c == '\\')
{
if (!directory.empty())
{ // 确保文件夹名称不为空
directories.push_back(directory);
directory.clear(); // 清空当前文件夹名称
}
}
else
{
directory += c; // 将字符添加到当前文件夹名称中
}
}
// 将最后一个文件夹名称添加到列表中
if (!directory.empty())
{
directories.push_back(directory);
}
return directories;
}