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.

2613 lines
76 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 "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;
}
bool customSort(const AI_Det_Channel_ &a, const AI_Det_Channel_ &b)
{
// 特定规则排序: "a" 排第一, "b" 排第二, "L" 排最后
if (a.strChannel == "Up-Particle" && b.strChannel != "Up-Particle")
{
return true; // "a" 排在前面
}
if (a.strChannel != "Up-Particle" && b.strChannel == "Up-Particle")
{
return false;
}
if (a.strChannel == "Down-Particle" && b.strChannel != "Down-Particle" && b.strChannel != "Up-Particle")
{
return true; // "b" 排第二
}
if (a.strChannel != "Down-Particle" && b.strChannel == "Down-Particle")
{
return false;
}
if (a.strChannel == "L0" && b.strChannel != "L0" && b.strChannel != "Up-Particle" && b.strChannel != "Down-Particle")
{
return false; // "L" 排最后
}
if (a.strChannel != "L0" && b.strChannel == "L0")
{
return true;
}
// 对其他情况使用字典顺序排序
return a.strChannel < b.strChannel;
}
// 定义图片读取函数
void readImage(const std::string &filename)
{
cv::Mat image = cv::imread(filename);
if (image.empty())
{
std::cerr << "Error: Unable to read image " << filename << std::endl;
return;
}
// // 在这里可以添加对图像的处理操作
// // 例如:显示图像、保存图像、进行其他处理等
// // 示例:显示图像
// cv::imshow(filename, image);
// cv::waitKey(0);
// cv::destroyWindow(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;
m_pextractImg = 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 (Process_Run_SaveImg == runConfig.run_Type)
{
Testsaveimg();
return 1;
}
else 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();
// 如果是 cell aoi 需要 加载初始化 图片解密 库
InitExtractImg();
if (Process_Run_SaveImg == runConfig.run_Type)
{
return 0;
}
// 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::InitExtractImg()
{
m_pextractImg = ExtractBase::GetInstance();
// cv::Mat outimg;
// m_pextractImg->ReadCELLImg("/mnt/4116e2a5-46a0-4c3e-a6e2-ed30d3ed7012/downloads/TestSets02/Cell AOI/20250627/研磨划伤和圈印/27圈印/6L7F52D001A2AEA/CA_20250508074237.ytimage",outimg);
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());
bool bhave = fs::exists(strRoot);
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)
{
auto& imgList = pcam->image_list;
// 同一camera内按配对处理每两张图一组 (CAA+CAB / TAA+TAB)
// cv::glob 返回字母序,确保 A_CAA 在 A_CAB 前M_CAA 在 M_CAB 前
for (size_t i = 0; i < imgList.size(); i += 2)
{
std::shared_ptr<JC_IMAGE_INFO_> tem = std::make_shared<JC_IMAGE_INFO_>();
tem->strCamID = pcam->strCamName;
tem->strchannelName = imgList[i]->strchannelName;
tem->strName = imgList[i]->strName;
tem->strProductID = imgList[i]->strProductID;
tem->strPath = imgList[i]->strPath;
if (i + 1 < imgList.size())
{
tem->strPath_B = imgList[i + 1]->strPath;
}
InsertReadImgInfo(tem);
AllImgNum++;
}
}
// 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;
}
}
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/CELL_AOI/testresult/", checkResult);
getresultNum++;
if (getresultNum == pushImgNum)
{
break;
}
}
}
printf(">>> ALL preCheck complete \n");
return 0;
}
int deal::Testsaveimg()
{
printf(">>> preCheck start \n");
std::string strRoot = "../data/img/t1";
std::string strProductID = "";
{
READ_IMG_INFO read;
readTestImg(read);
strRoot = read.strpath;
strProductID = read.strproduct;
printf("strSearchImg strRoot %s\n", strRoot.c_str());
bool bhave = fs::exists(strRoot);
if (!bhave)
{
printf("read img path error %d %s\n", bhave, strRoot.c_str());
return 1;
}
}
// 获取图片路径
std::string strSearchImg = strRoot;
Read_Image dfe;
dfe.pimage_ReadChannel = &m_image_ReadChannel;
int re = dfe.Read_Image_List(strSearchImg, strProductID);
if (re != 0)
{
return re;
}
if (dfe.m_product_Camera_List.size() <= 0)
{
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();
// 读图现场都开启
for (const auto pcam : product->camera_list)
{
for (const auto pimage : pcam->image_list)
{
cv::Mat img;
long t1 = CheckUtil::getcurTime();
re = m_pextractImg->ReadCELLImg(pimage->strPath, img, runConfig.bdecode);
long t2 = CheckUtil::getcurTime();
printf("read re = %d img time %ld ms \n", re, t2 - t1);
if (!img.empty())
{
cv::imwrite(pimage->strName + ".jpg", img);
}
else
{
printf("img.empty() \n");
}
// getchar();
}
}
return 0;
}
std::string deal::readTestImg()
{
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 "";
}
if (!Json::parseFromStream(builder, ifs, &root, &err))
{
printf("error:parseFromStream\n");
return "";
}
std::string imgpath = "";
imgpath = root["TestImg_Path"].asString();
return imgpath;
}
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::repeatCheck()
{
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/CELL_AOI/Detsave/", dealResult);
}
{
// 存 检测统计 日志
mutex_DetResult_.lock();
m_DetResult.print(false);
std::string strlog = "/home/aidlux/BOE/CELL_AOI/ResultImg/";
if (m_strCurDate != "")
{
strlog += m_strCurDate;
strlog += "/result";
}
else
{
strlog += "/result";
}
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.Analysis_Config_path_Cam2 = root["Analysis_Config_path_Cam2"].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::GetJcImageInfo(std::string strpath, std::vector<JC_IMAGE_INFO_> &jcImageInfoList)
{
LoadOfflineCheckImg(strpath);
jcImageInfoList.erase(jcImageInfoList.begin(), jcImageInfoList.end());
// 遍历每一套图片
for (int idx = 0; idx < m_OffLineCheckImgNameList.size(); idx++)
{
std::string path = m_OffLineCheckImgNameList.at(idx);
JC_IMAGE_INFO_ tem;
int re = GetImgInfo_POL_ET(path, &tem);
}
// getchar();
return 0;
}
int deal::GetDetImageInfo(std::string strProductID, std::string strSearchImg, std::vector<JC_IMAGE_INFO_> &jcImageInfoList)
{
// 1、获取图片路径
std::vector<cv::String> img_paths;
std::string strs1 = strSearchImg + "/*.ytimage";
if(!runConfig.bdecode)
{
strs1 = strSearchImg + "/*.png";
cv::glob(strs1, img_paths, true);
}
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;
}
int deal::ReadTestImgaData()
{
std::string strPath = "../data/testImg.json";
printf("ReadTestImgaData 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_TestJC_ImageDate.erase(m_TestJC_ImageDate.begin(), m_TestJC_ImageDate.end());
{
auto value = root["img_date"];
if (value.isObject())
{
auto arr = value["date"];
std::cout << arr << std::endl;
if (arr.isArray())
{
// 遍历数组中的每个元素
for (int i = 0; i < arr.size(); i++)
{
// 读取对象中的属性值
std::string strdata = arr[i].asString();
m_TestJC_ImageDate.push_back(strdata);
// 输出属性值
std::cout << "date: " << strdata << std::endl;
}
}
}
}
// getchar();
return 0;
}
int deal::InitDetData()
{
m_read_ImgNum = 0;
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::GetUpMaskImg(cv::Mat inImg, cv::Rect roi, cv::Mat &maskimg)
{
// 定义滑动窗口的大小和步长
int windowWidth = 128;
int windowHeight = 128;
int stepX = 110; // 横向步长
int stepY = 110; // 纵向步长
maskimg = cv::Mat(roi.height, roi.width, CV_8U, cv::Scalar(0));
int sx = roi.x;
int ex = roi.x + roi.width;
int sy = roi.y;
int ey = roi.y + roi.height;
cv::Rect detroi;
detroi.width = windowWidth;
detroi.height = windowHeight;
cv::Rect maskroi;
maskroi.width = windowWidth;
maskroi.height = windowHeight;
cv::Mat temmask;
// 遍历图像,使用滑动窗口
for (int y = sy; y <= ey; y += stepY)
{
detroi.y = y;
if (detroi.y + windowHeight > ey)
{
detroi.y = ey - windowHeight;
}
maskroi.y = detroi.y - sy;
for (int x = sx; x <= ex; x += stepX)
{
detroi.x = x;
if (detroi.x + windowWidth > ex)
{
detroi.x = ex - windowWidth;
}
maskroi.x = detroi.x - sx;
int thresholdValue = 30; // 初始阈值OTSU将自动计算
int maxVal = 255; // 最大值
double otsuThreshold;
cv::Scalar mean, stddev;
cv::meanStdDev(inImg(detroi), mean, stddev);
int varianceImg;
varianceImg = mean[0] + 1 * mean[0];
if (mean[0] > 100)
{
continue;
}
// 使用 OTSU 阈值处理
otsuThreshold = cv::threshold(inImg(detroi), temmask, thresholdValue, maxVal, cv::THRESH_BINARY | cv::THRESH_OTSU);
thresholdValue = otsuThreshold;
if (thresholdValue < 30)
{
thresholdValue = 30;
}
if (thresholdValue < varianceImg)
{
thresholdValue = varianceImg;
}
if (thresholdValue > 100)
{
continue;
}
// std::cout << "varianceImg value is: " << varianceImg << std::endl;
// std::cout << "OTSU threshold value is: " << otsuThreshold << std::endl;
// std::cout << "stddev[0] value is: " << stddev[0] << std::endl;
otsuThreshold = cv::threshold(inImg(detroi), maskimg(maskroi), thresholdValue, maxVal, cv::THRESH_BINARY);
// cv::threshold(inImg(detroi), maskimg(maskroi), thresholdValue, maxVal, cv::THRESH_BINARY + cv::THRESH_OTSU);
// 提取当前窗口
// cv::rectangle(inImg, detroi, cv::Scalar(255, 0, 0));
}
}
// cv::imwrite("inImg1123.png", inImg);
// cv::imwrite("maskimg.png", maskimg);
// getchar();
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()
{
return 0;
}
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);
preCheck();
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);
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, 0);
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)
{
}
}
}
void deal::testimg(cv::Mat img)
{
}
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;
}
// 滑动窗口二值化函数
void deal::slidingWindowAutoThreshold(const cv::Mat &src, cv::Mat &dst, int windowSize, int step, double C)
{
// 确保窗口大小为奇数
// if (windowSize % 2 == 0)
// {
// windowSize++;
// }
// 创建目标图像
dst = cv::Mat::zeros(src.size(), CV_8UC1);
// 获取源图像的尺寸
int rows = src.rows;
int cols = src.cols;
int xs = 0;
int xe = windowSize;
int ys = 0;
int ye = windowSize;
for (int y = ye; y < rows;)
{
int xs = 0;
int xe = windowSize;
for (int x = xe; x < cols;)
{
cv::Rect roi;
roi.x = xs;
roi.width = windowSize;
roi.y = ys;
roi.height = windowSize;
cv::Mat window = src(roi);
// 计算窗口中的平均值和标准差
cv::Scalar mean, stdDev;
cv::meanStdDev(window, mean, stdDev);
// printf(" x %d %d y %d %d %f %f \n", xs, xe, ys, ye, mean[0], stdDev[0]);
int T = mean[0] + 20 * stdDev[0];
cv::threshold(window, dst(roi), T, 255, cv::THRESH_BINARY);
// cv::rectangle(src, roi, cv::Scalar(255, 0, 255));
if (xe == cols)
{
break;
}
xs = xs + step;
xe = xs + windowSize;
if (xs < cols && xe > cols)
{
xe = cols;
xs = xe - windowSize;
}
}
if (ye == rows)
{
break;
}
ys = ys + step;
ye = ys + windowSize;
if (ys < rows && ye > rows)
{
ye = rows;
ys = ye - windowSize;
}
}
// // 遍历图像的每个像素
// for (int i = 0; i < rows; ++i)
// {
// for (int j = 0; j < cols; ++j)
// {
// // 计算窗口边界
// int startRow = std::max(0, i - windowSize / 2);
// int endRow = std::min(rows - 1, i + windowSize / 2);
// int startCol = std::max(0, j - windowSize / 2);
// int endCol = std::min(cols - 1, j + windowSize / 2);
// // 提取窗口中的图像块
// cv::Mat window = src(cv::Range(startRow, endRow + 1), cv::Range(startCol, endCol + 1));
// // 计算窗口中的平均值和标准差
// cv::Scalar mean, stdDev;
// cv::meanStdDev(window, mean, stdDev);
// // 计算局部阈值
// double threshold = mean[0] - C * stdDev[0];
// // 根据局部阈值进行二值化
// if (src.at<uchar>(i, j) >= threshold)
// {
// dst.at<uchar>(i, j) = 255;
// }
// else
// {
// dst.at<uchar>(i, j) = 0;
// }
// }
// }
}
int deal::testimgUP(cv::Mat img)
{
cv::Mat dst;
slidingWindowAutoThreshold(img, dst, 200, 180, 10);
cv::imwrite("up_dst.png", dst);
cv::imwrite("up.png", img);
printf("1111\n");
getchar();
return 0;
}
int deal::test_ZF(ReadImgInfo tem, int id)
{
std::string ressss = "**";
for (int i = 0; i < id; i++)
{
ressss += "*******";
}
// printf("%s %d start redimg img idx %d ID %s ch %s tem.imglist %zu\n ", ressss.c_str(), id, tem.idx, tem.strImgSN.c_str(), tem.strChannel.c_str(), tem.imglist.size());
long t1 = getcurTime();
cv::Mat L255Img = cv::imread(tem.strPath, 0);
long t2 = getcurTime();
mtx_DetImgQueue_com.lock();
m_read_ImgNum++;
long useTime = t2 - m_readImgStarttime;
// printf("read Img mean time %ld -- m_read_ImgNum %d use time %ld \n", useTime / m_read_ImgNum, m_read_ImgNum, useTime / 1000);
mtx_DetImgQueue_com.unlock();
printf("---------------------ThreadID %d readimg %d / %d use time %ld %s \n", id, tem.idx, tem.sumNUm, t2 - t1, tem.strPath.c_str());
// printf("tem.strPath %s *\n", tem.strPath.c_str());
// printf("%s %d End redimg use time %ld \n ", ressss.c_str(), id, t2 - t1);
cv::Mat mask;
if (L255Img.empty())
{
printf("error:No L255 Img -------------- \n");
InsertDetResult(tem);
return 1;
}
tem.status = 1;
int re = 0;
std::shared_ptr<CheckResult> result;
// 多线程 互斥 作用域
// if (false)
{
std::lock_guard<std::mutex> lock(mtx_DetImgQueue_edge);
{
if (tem.strChannel == "L255")
{
std::shared_ptr<shareImage> temdet = std::make_shared<shareImage>();
if (m_nSaveDetprocessImg == 1)
{
temdet->otherValue = 9;
}
temdet->strImgName = "test";
temdet->strImgProductID = tem.strImgSN;
temdet->strChannel = tem.strChannel;
// if (m_nReadThread_type == READ_THREAD_TYPE_EDGE)
{
temdet->Det_Mode = DET_MODE_EDGE;
if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI)
{
temdet->ninstruct = 999;
}
}
temdet->img = L255Img;
printf(">>>>>>>>>>>m_nReadThread_type %d runConfig.det_Type %d temdet->ninstruct %d >>>>>>>>> ThreadID %d start Check readimg %d / %d ID %s ch %s \n ", m_nReadThread_type, runConfig.det_Type, temdet->ninstruct, id, tem.idx, tem.sumNUm, tem.strImgSN.c_str(), tem.strChannel.c_str());
m_pALLImgCheckAnalysisy->CheckImg(temdet, result);
// 结果异常
if (result->nresult != 0)
{
printf("preCheck Img edge error..... %s \n", tem.strPath.c_str());
InsertDetResult(tem);
return ERROR_PRECHECK_IMG_NULL;
}
tem.status = 2;
InsertDetResult(tem);
}
}
}
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;
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, 0);
if (!runConfig.bdecode)
{
// 不解码模式:直接用 opencv 读取图片
pImageInfo->img = cv::imread(pImageInfo->strPath, cv::IMREAD_GRAYSCALE);
if (pImageInfo->strPath_B != "")
{
pImageInfo->img_B = cv::imread(pImageInfo->strPath_B, cv::IMREAD_GRAYSCALE);
}
}
else
{
m_pextractImg->ReadCELLImg(pImageInfo->strPath, pImageInfo->img, runConfig.bdecode);
if (pImageInfo->strPath_B != "")
{
m_pextractImg->ReadCELLImg(pImageInfo->strPath_B, pImageInfo->img_B, runConfig.bdecode);
}
}
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;
}
int deal::LoadOfflineCheckImg(std::string strImgPath)
{
std::vector<cv::String> img_paths;
cv::glob(strImgPath, img_paths, true);
m_OffLineCheckImgList.erase(m_OffLineCheckImgList.begin(), m_OffLineCheckImgList.end());
m_OffLineCheckImgNameList.erase(m_OffLineCheckImgNameList.begin(), m_OffLineCheckImgNameList.end());
for (int i = 0; i < img_paths.size(); i++)
{
size_t found = img_paths[i].find_last_of("/\\");
// std::cout << img_paths[i] << std::endl;
std::string str = img_paths[i];
m_OffLineCheckImgNameList.push_back(str);
}
return 0;
}
int deal::LoadImgPath_JCSN(std::string strImgPath)
{
std::cout << strImgPath << std::endl;
std::vector<cv::String> img_paths;
cv::glob(strImgPath, img_paths, true);
m_OffImageSNPathList.erase(m_OffImageSNPathList.begin(), m_OffImageSNPathList.end());
for (int i = 0; i < img_paths.size(); i++)
{
std::string path = img_paths[i];
// std::cout << img_paths[i] << std::endl;
// 提取所有文件夹名称
std::vector<std::string> allDirectories = extractAllDirectories(path);
std::string strSN = "";
// 输出所有文件夹名称
std::string strAllPath = "/";
for (const auto &dir : allDirectories)
{
strAllPath += dir;
if (isValidString(dir))
{
strSN = dir;
// std::cout << strSN << std::endl;
break;
}
strAllPath += "/";
}
bool bh = false;
for (int j = 0; j < m_OffImageSNPathList.size(); j++)
{
if (m_OffImageSNPathList.at(j) == strAllPath)
{
bh = true;
break;
}
}
if (!bh)
{
if (m_OffImageSNPathList.size() < m_nTestNum)
{
m_OffImageSNPathList.push_back(strAllPath);
std::cout << strAllPath << std::endl;
}
// std::cout << strSN << std::endl;
}
}
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;
// tif 格式
{
std::string str_bmp = strImgPath + "/*.ytimage";
if(!runConfig.bdecode)
{
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;
}
}
}
}
return 0;
}
int deal::DelImg_Cell_ET()
{
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 RESULT_OK;
}
int deal::Det_OneProduct_Cell_ET(std::string strProductName, int Idx)
{
std::string strProductID = GetFileName(strProductName);
// 获取图片路径
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_Edge_Test_OneImg()
{
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;
}
for (int i = 0; i < m_OffImageSNPathList.size(); i++)
{
printf(">>> %d / %zu --start \n", i, m_OffImageSNPathList.size());
long t1, t2;
cv::Mat detimg = cv::imread(m_OffImageSNPathList.at(i));
{
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 = "L255";
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 = detimg;
m_pALLImgCheckAnalysisy->CheckImg(temdet, result);
// 结果异常
}
}
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;
}
int deal::RandDrawImg(cv::Mat srcimg, cv::Mat &randErrorImg)
{
randErrorImg = srcimg.clone();
cv::Rect roi;
roi.x = (rand() % (srcimg.cols - 20 - 20)) + 20;
roi.y = (rand() % (srcimg.rows - 20 - 20)) + 20;
roi.width = (rand() % (100 - 5)) + 5;
roi.height = roi.width;
if (roi.x + roi.width >= srcimg.cols)
{
roi.x = srcimg.cols - roi.width - 1;
/* code */
}
if (roi.y + roi.height >= srcimg.rows)
{
roi.y = srcimg.rows - roi.height - 1;
/* code */
}
randErrorImg(roi).setTo(30);
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;
}