/* * @Author: your name * @Date: 2022-04-20 15:50:00 * @LastEditTime: 2025-09-24 11:03:35 * @LastEditors: xiewenji 527774126@qq.com * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp */ #include "ALLImgCheckAnalysisy.hpp" #include "CheckUtil.hpp" #include "Define.h" #include "AI_Factory.h" #include std::vector m_FlawCodeList; std::vector QX_Result_Names = { "OK", "AD_YX", "X_Line", "Y_Line", "fangge", "Rubbing_Mura", "Broken_line", "ZARA", "MTX", "POL_Cell", "Bright_Point", "Dark_Point", "BLack_Point", "White_Point", "Scratch", "Weak_Bright_Mura", "No_Label", "Bright_Mura_Exe", "Sweak_Line_Dark", "STEAM_POCKET", "Dirty", "other", "Cell_W", "Cell_B", "LackPol"}; std::vector QX_Result_Code = { "P1153", "P6873", "P3351", "P3452", "P3453", "P1550", "P3379", "P1153", "P1164", "P1101", "P1112", "P1111", "P1104", "P1103", "P1557", "P1654", "P2833", "P1549", "P1204", "P2534", "P2534", "P1101", "P1103", "P1104", "P8001", }; int ReadFlawCodeConfig(std::string json_path) { m_FlawCodeList.erase(m_FlawCodeList.begin(), m_FlawCodeList.end()); std::string strPath = json_path; printf("ReadFlawCodeConfig path %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 0; } if (!Json::parseFromStream(builder, ifs, &root, &err)) { printf("error:parseFromStream\n"); return 0; } for (int i = 0; i < root.size(); i++) { // printf("Node idx %d /%d \n", i, root.size()); ReadFlawCode tem; tem.flaw_name = root[i]["zh_name"].asString(); tem.flaw_code = root[i]["en_name"].asString(); string desc = root[i]["desc"].asString(); { std::istringstream stream(desc); std::string token; // 使用 getline 按照分号分割 while (std::getline(stream, token, ';')) { tem.config_flaw_name.push_back(token); } } m_FlawCodeList.push_back(tem); } for(int i = 0; i < m_FlawCodeList.size(); i++) { if(i >= QX_Result_Names.size()) { QX_Result_Names.push_back(m_FlawCodeList.at(i).flaw_name); QX_Result_Code.push_back(m_FlawCodeList.at(i).flaw_code); } else { QX_Result_Names.at(i) = m_FlawCodeList.at(i).flaw_name; QX_Result_Code.at(i) = m_FlawCodeList.at(i).flaw_code; } } return 0; } double calculateDistanceBetweenRectCenters(const cv::Rect &rect1, const cv::Rect &rect2, float fx, float fy) { // 计算矩形1的中心点 cv::Point center1(rect1.x + rect1.width / 2, rect1.y + rect1.height / 2); // 计算矩形2的中心点 cv::Point center2(rect2.x + rect2.width / 2, rect2.y + rect2.height / 2); center1.x *= fx; center1.y *= fy; center2.x *= fx; center2.y *= fy; // 计算中心点之间的欧几里得距离 double distance = cv::norm(center1 - center2); return distance; } ALLImgCheckAnalysisy::ALLImgCheckAnalysisy() { m_strTest = ""; } ALLImgCheckAnalysisy::~ALLImgCheckAnalysisy() { StopThread(); } int ALLImgCheckAnalysisy::RunStart(void *pconfig1) { // 1、参数版本核对 int re = CheckConfigVersion(pconfig1); if (re != 0) { printf("*************CheckConfigVersion error %d*************** \n", re); m_nErrorCode = INIT_CameraCheck_Error; return m_nErrorCode; } m_pParamName = ParmNameChange::getInstance(); m_pParamName->m_nWorkIdx = m_RunConfig.nWorkIdx; // 2、初始化相机类 re = InitCameraCheckAnalysisy(); if (re != 0) { printf("*************InitCameraCheckAnalysisy error %d*************** \n", re); m_nErrorCode = INIT_CameraCheck_Error; return m_nErrorCode; } re = InitRun(); if (CHECK_OK != re) { m_nErrorCode = re; return m_nErrorCode; } re = InitAIFactory(); if (CHECK_OK != re) { m_nErrorCode = re; return m_nErrorCode; } m_nErrorCode = CHECK_OK; printf(">>>> ALLImgCheckAnalysisy Start Succ \n"); m_nErrorCode = CHECK_OK; m_bInitSucc = true; return m_nErrorCode; } int ALLImgCheckAnalysisy::SetDataRun_SharePtr(std::shared_ptr p) { int re = PushInImg_New(p); if (re != 0) { printf("SetDataRun_SharePtr======================= re %d \n", re); } return re; } int ALLImgCheckAnalysisy::GetCheckReuslt(std::shared_ptr &pResult) { std::unique_lock lk(mtx_CheckResult); // 使用 unique_lock CheckResult_cond.wait(lk, [this] { return !m_CheckResultList.empty(); }); // 等待直到数据队列非空 pResult = m_CheckResultList.front(); // 从队列中取出数 m_CheckResultList.pop(); lk.unlock(); return 0; } int ALLImgCheckAnalysisy::ReJson(std::shared_ptr p, std::shared_ptr &pResult) { return 0; } int ALLImgCheckAnalysisy::CheckImg(std::shared_ptr p, std::shared_ptr &pResult) { return 0; } int ALLImgCheckAnalysisy::GetStatus() { return 0; } int ALLImgCheckAnalysisy::UpdateConfig(void *pconfig, int nConfigType) { int re = 0; RunInfoST *tempconfig; switch (nConfigType) { case CHECK_CONFIG_Run: tempconfig = (RunInfoST *)pconfig; m_RunConfig.copy(*tempconfig); break; case CHECK_CONFIG_Module: m_pConfigManager = (ConfigManagerBase *)pconfig; break; default: break; } return 0; } std::string ALLImgCheckAnalysisy::GetVersion() { return std::string("BOE_2.0.5"); } std::string ALLImgCheckAnalysisy::GetErrorInfo() { std::string result = ""; return result; } int ALLImgCheckAnalysisy::ErrorReturn(std::shared_ptr p) { std::shared_ptr result = std::make_shared(); result->in_shareImage = p; result->checkStatus = 1; result->nresult = -CHECK_ERROR_PushImg_ID_Error; result->basicResult.img_id = p->img_id; result->basicResult.imgtype = p->imgtype; result->basicResult.imgstr = p->imgstr; result->basicResult.strChannel = p->strChannel; // printf("ErrorReturn==== %s %s\n", p->strImgProductID.c_str(), p->strChannel.c_str()); { std::lock_guard lock(mtx_CheckResult); m_CheckResultList.push(result); } CheckResult_cond.notify_all(); return 0; } std::shared_ptr ALLImgCheckAnalysisy::GetProduct(std::string strProduct) { std::lock_guard lock(mtx_ProductList); for (int i = 0; i < m_ProductList.size(); i++) { // printf("ddd %s \n", m_ProductList.at(i)->productBaseResult->strproductName.c_str()); if (m_ProductList.at(i)->productBaseResult->strproductName == strProduct) { return m_ProductList.at(i); } } return std::shared_ptr(); } int ALLImgCheckAnalysisy::InitAIFactory() { std::shared_ptr AI_Factory; AI_Factory = AIFactory::GetInstance(); GPU_Config gpu; int num = 0; for (int i = 0; i < MAX_GPU_NUM; i++) { gpu.UseGPUList[i] = m_RunConfig.UseGPUList[i]; if (gpu.UseGPUList[i] >= 0) { num++; } } if (num == 0) { gpu.UseGPUList[0] = 0; gpu.UseGPUList[1] = 1; } for (int i = 0; i < MAX_GPU_NUM; i++) { printf("=====InitAIFactory gpu %d %d \n", i, gpu.UseGPUList[i]); } AI_Factory->InitALLAIModle(gpu); return 0; } int ALLImgCheckAnalysisy::LoadRunConfig(void *p) { return 0; } int ALLImgCheckAnalysisy::LoadCheckConfig(void *p) { return 0; } int ALLImgCheckAnalysisy::InitRun() { int re; re = StartThread(); if (CHECK_OK != re) { return re; } return 0; } int ALLImgCheckAnalysisy::StartCheck() { return 0; } int ALLImgCheckAnalysisy::SetIDLE() { return 0; } int ALLImgCheckAnalysisy::CheckConfigVersion(void *pconfig1) { int re = 0; VERSION_INFO *pVersionconfig = (VERSION_INFO *)pconfig1; if (pVersionconfig == NULL) { m_nErrorCode = CHECK_ERROR_VERSION; // 参数或接口版本问题 return m_nErrorCode; } int v1 = ALL_INTERFACE_VERSION; int v2 = CONFIGBASE_VERSION; int v3 = RESULT_VERSION; printf("**************************** ALL_INTERFACE_VERSION so: %d in:%d CONFIGBASE_VERSION so:%d in:%d RESULT_VERSION so:%d in:%d\n", v1, pVersionconfig->InterfaceVersion, v2, pVersionconfig->ConfigVersion, v3, pVersionconfig->ResultVersion); // 版本控制 if (pVersionconfig->InterfaceVersion != ALL_INTERFACE_VERSION || pVersionconfig->ConfigVersion != CONFIGBASE_VERSION || pVersionconfig->ResultVersion != RESULT_VERSION) { m_nErrorCode = CHECK_ERROR_VERSION; // 参数或接口版本问题 return m_nErrorCode; } return 0; } int ALLImgCheckAnalysisy::StartThread() { m_bExit = false; { // 开启检测线程 ptr_thread_Run = std::make_shared(std::bind(&ALLImgCheckAnalysisy::Run, this)); } return 0; } int ALLImgCheckAnalysisy::StopThread() { m_bExit = true; if (ptr_thread_Run != nullptr) { if (ptr_thread_Run->joinable()) { ptr_thread_Run->join(); } } return 0; } int ALLImgCheckAnalysisy::ExitSystem() { return 0; } int ALLImgCheckAnalysisy::InitCameraCheckAnalysisy() { ReadFlawCodeConfig("/var/aidlux/efs/cell_aoi/model/defect_list.json"); m_pCameraCheckAnalysisyList.clear(); // m_pQX_Merge_Analysis->Clear(); for (const auto &config : m_pConfigManager->Config_instances_) { std::cout << "key: " << config.first << std::endl; std::shared_ptr p = std::make_shared(); p->m_RunConfig.copy(m_RunConfig); p->m_pConfig = config.second; int re = p->Init(config.first); if (re != 0) { std::cout << "Init CameraCheckAnalysisy " << config.first << " Failed" << std::endl; return -1; } m_pCameraCheckAnalysisyList[config.first] = p; // m_pQX_Merge_Analysis->AddCamer(config.first); } if (m_pCameraCheckAnalysisyList.size() < 0) { printf("ALLImgCheckAnalysisy::InitCameraCheckAnalysisy error camera config is null \n"); return 1; /* code */ } printf("ALLImgCheckAnalysisy::InitCameraCheckAnalysisy end \n"); // getchar(); return 0; } int ALLImgCheckAnalysisy::InitData() { return 0; } int ALLImgCheckAnalysisy::Det_Product(std::shared_ptr &product) { // m_pQX_Merge_Analysis->InitData(); // 处理每个相机 while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); { std::lock_guard lock(product->mtx_CameraResultList); // for (auto &ptr : product->m_pCameraResultList) { if (ptr->GetCheckStep() == Check_Step_NODet) { m_pCameraCheckAnalysisyList[ptr->cameraBaseResult->strCameraName]->StartCheck(ptr); } } } // 判断每个相机是否都处理完了。 bool bdetComplete = product->bCheckCamplate(); // 处理完成,退出循环 if (bdetComplete) { break; } } // 联合分析 // AnalysiyAll(0); MergeShowImg(product); SetProductResult(product); printf(">>>>>>>>>>>>>>>Det_Product****************det End************\n"); return 0; } std::shared_ptr ALLImgCheckAnalysisy::GetProduct() { std::unique_lock lk(mtx_ProductList); // 使用 unique_lock ProductList_cond.wait(lk, [this] { return !m_ProductList.empty(); }); // 等待直到数据队列非空 std::shared_ptr tem = m_ProductList.at(0); lk.unlock(); return tem; } int ALLImgCheckAnalysisy::AnalysiyAll(int productIdx) { return 0; } int ALLImgCheckAnalysisy::SetProductResult(std::shared_ptr product) { int nDetCamNum = product->m_pCameraResultList.size(); // 相机2的起始位置 bool bNG = false; for (int icam = 0; icam < nDetCamNum; icam++) { std::shared_ptr pcam = product->m_pCameraResultList.at(icam); for (int i = 0; i < pcam->ImageALLDetResultList.size(); i++) { std::shared_ptr pCheckResult = pcam->ImageALLDetResultList.at(i)->result; if (pCheckResult->qxImageResult.size() > 0) { bNG = true; } if (bNG) { break; } } if (bNG) { break; } } if (bNG) { for (int icam = 0; icam < nDetCamNum; icam++) { std::shared_ptr pcam = product->m_pCameraResultList.at(icam); for (int i = 0; i < pcam->ImageALLDetResultList.size(); i++) { std::shared_ptr pCheckResult = pcam->ImageALLDetResultList.at(i)->result; pCheckResult->nProductResult = 1; } } } return 0; } int ALLImgCheckAnalysisy::SetSetComplet_New(std::shared_ptr product, int nerror) { if (product) { int nDetCamNum = product->m_pCameraResultList.size(); for (int icam = 0; icam < nDetCamNum; icam++) { std::shared_ptr pcam = product->m_pCameraResultList.at(icam); for (int i = 0; i < pcam->ImageALLDetResultList.size(); i++) { std::shared_ptr pCheckResult = pcam->ImageALLDetResultList.at(i)->result; { std::lock_guard lock123(mtx_CheckResult); m_CheckResultList.push(pCheckResult); } CheckResult_cond.notify_all(); } } } return 0; } int ALLImgCheckAnalysisy::PushInImg_New(std::shared_ptr p) { if (!m_bInitSucc) { printf("Init fail exit \n"); return CHECK_ERROR_Config_Null; } p->strParm_WorkCamName = m_pParamName->GetWebConfigCamName_DetImgCamName(p->strCameraName); std::string strlog = ""; m_strTest += " PushInImg->SN:"; m_strTest += p->strImgProductID; m_strTest += " Channel:"; m_strTest += p->strChannel; m_strTest += " CameraID:"; m_strTest += p->strCameraName; m_strTest += " WorkCamName:"; m_strTest += p->strParm_WorkCamName; std::string strBase = ""; strBase += " PushInImg->SN:"; strBase += p->strImgProductID; strBase += " camera:"; strBase += p->strCameraName; strBase += " WorkCamName:"; strBase += p->strParm_WorkCamName; strBase += " Channel:"; strBase += p->strChannel; printf("strBase %s p->Status %d\n", strBase.c_str(), p->Status); std::shared_ptr product; { std::string strcameraName = p->strParm_WorkCamName; // 判断 相机名称是否存在 if (!m_pCameraCheckAnalysisyList.count(strcameraName) && -1 != p->Status) { return CHECK_ERROR_Camear_ID_Error; } product = GetProduct(p->strImgProductID); bool ProductID_Exist = false; // 是否存在当前产品ID strlog += "productID "; if (product) { strlog += "exist"; ProductID_Exist = true; } // 产品ID存在 if(ProductID_Exist) { // 模式为第一张图,返回异常 if(IN_IMG_Status_Start == p->Status) { cout << "---ProductID_Exist && IN_IMG_Status_Start == p->Status---" << endl; return CHECK_ERROR_PRODUCT_ID_EXIST; } // 图片都已经完了的状态 if(product->bIsImgComplete) { cout << "---ProductID_Exist && product->bIsImgComplete is true---" << endl; ErrorReturn(p); return CHECK_ERROR_PRODUCT_ID_EXIST; } } // 产品ID不存在 else { strlog += "isnot exist"; //设置其他m_ProductList送图状态设置为结束 cout << "-------set m_ProductList other product to end-------" << endl ; std::lock_guard lock(mtx_ProductList); for(auto &tem:m_ProductList){ tem->bIsImgComplete = true; } if(-1 == p->Status) { return CHECK_ERROR_PushImg_ID_Error; } } // 产品不存在 新建一个 if (!product) { std::lock_guard lock(mtx_ProductList); { if (m_ProductList.size() > 50) { Clear_m_ProductList(); return CHECK_ERROR_PushImg_ListSize; } } strlog += " | create new product"; product = std::make_shared(); product->productBaseResult->strproductName = p->strImgProductID; if (m_CurProductIdx > 999999) { m_CurProductIdx = 0; } product->productUseCount = m_CurProductIdx; m_CurProductIdx++; m_ProductList.push_back(product); std::string strTimg = CheckUtil::getCurTimeHMS(); product->productBaseResult->detlog->bPrintStr = true; product->productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg", "add new product %s %s ", p->strImgProductID.c_str(), strTimg.c_str()); } else { strlog += " | product: "; strlog += product->productBaseResult->strproductName; // printf("Product Is %s \n", product->productBaseResult->strproductName.c_str()); } // 送入图的状态 结束 if(-1 == p->Status) { strlog += " | p->Status == -1, set product complete"; product->bIsImgComplete = true; } // 送入图的状态 不是结束 else { strlog += " | create new camera result"; // 对应相机的 检测结果 std::shared_ptr pCamera = product->GetCameraResult(strcameraName); if (pCamera.get() == nullptr) { strlog += " | CHECK_ERROR_Camear_ID_Error"; product->productBaseResult->detlog->bPrintStr = true; product->productBaseResult->detlog->AddCheckstr(PrintLevel_1, "PushInImg end", "%s", strlog.c_str()); ErrorReturn(p); return CHECK_ERROR_Camear_ID_Error; } // 添加产品信息 pCamera->AddDetImage(p); } product->UpdatePushStatus(p->Status); if (IN_IMG_Status_End == p->Status) { strlog += " | p->Status == IN_IMG_Status_End, set product complete"; product->bIsImgComplete = true; m_strTest += "\n"; product->AddLog(m_strTest); m_strTest = ""; } product->productBaseResult->detlog->bPrintStr = true; product->productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg end", "%s", strlog.c_str()); ProductList_cond.notify_all(); } return 0; } cv::Mat ALLImgCheckAnalysisy::hconcatWithFirstBase(const cv::Mat &img1, const cv::Mat &img2, int interpolation = cv::INTER_LINEAR) { // 如果高度相同,直接拼接 if (img1.rows == img2.rows) { cv::Mat result; cv::hconcat(img1, img2, result); return result; } // 计算缩放比例 double scale = static_cast(img1.rows) / img2.rows; // 调整img2的高度 cv::Mat img2_resized; cv::resize(img2, img2_resized, cv::Size(), scale, scale, interpolation); // 拼接 cv::Mat result; cv::hconcat(img1, img2_resized, result); return result; } int ALLImgCheckAnalysisy::MergeShowImg(std::shared_ptr product) { int nDetCamNum = product->m_pCameraResultList.size(); // printf("MergeShowImg %s \n", product->productBaseResult->strproductName.c_str()); // 2个相机才操作 if (nDetCamNum == 2) { std::shared_ptr pcam_0 = product->m_pCameraResultList.at(0); std::shared_ptr pcam_1 = product->m_pCameraResultList.at(1); for (int i = 0; i < pcam_0->ImageALLDetResultList.size(); i++) { std::shared_ptr pCheckResult_0 = pcam_0->ImageALLDetResultList.at(i)->result; // printf("cam %s channel %s \n", pcam_0->cameraBaseResult->strCameraName.c_str(), // pCheckResult_0->in_shareImage->strChannel.c_str()); for (int j = 0; j < pcam_1->ImageALLDetResultList.size(); j++) { std::shared_ptr pCheckResult_1 = pcam_1->ImageALLDetResultList.at(j)->result; if (pCheckResult_1->in_shareImage->strChannel == pCheckResult_0->in_shareImage->strChannel) { // printf("cam %s channel %s \n", pcam_1->cameraBaseResult->strCameraName.c_str(), // pCheckResult_1->in_shareImage->strChannel.c_str()); if (!pCheckResult_0->resultimg.empty() && !pCheckResult_1->resultimg.empty()) { cv::Mat meregeimg; if (pCheckResult_0->in_shareImage->strCameraName == "left") { meregeimg = hconcatWithFirstBase(pCheckResult_0->resultimg, pCheckResult_1->resultimg); } else { meregeimg = hconcatWithFirstBase(pCheckResult_1->resultimg, pCheckResult_0->resultimg); } pCheckResult_0->resultimg = meregeimg; pCheckResult_1->resultimg = meregeimg; } break; } } } } return 0; } void ALLImgCheckAnalysisy::Clear_m_ProductList(){ int num = m_ProductList.size(); string strlog = ""; printf("******************\n\n m_ProductImgDetResultList %ld \n", m_ProductList.size()); std::lock_guard lock(mtx_ProductList); int idx = -1; for (int i = 0; i < m_ProductList.size(); i++) { int sub = std::abs(m_CurProductIdx - m_ProductList.at(i)->productUseCount); if (sub > 50) { // 删除指定位置的元素 // m_ProductList.at(i)->productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg", "%s Delete size > %d; m_CurProductIdx %d - nNotDetCount %d > 50", // m_ProductList.at(i)->, // m_ProductList.size(), m_CurProductIdx, // m_ProductList.at(i)->productUseCount); m_ProductList.erase(m_ProductList.begin() + i); } } } int ALLImgCheckAnalysisy::Run() { while (!m_bExit) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); std::shared_ptr product = GetProduct(); int re = Det_Product(product); // // 检测失败 // if (re != 0) // { // continue; // } SetSetComplet_New(product, re); // 更新 产品队列 { std::lock_guard lock(mtx_ProductList); // if (!m_ProductList.empty()) { m_ProductList.erase(m_ProductList.begin()); } } } return 0; } int ALLImgCheckAnalysisy::set_cpu_id(const std::vector &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; }