diff --git a/include/global.h b/include/global.h index 35d62d3..7d5a670 100644 --- a/include/global.h +++ b/include/global.h @@ -11,7 +11,7 @@ #include #pragma execution_character_set("utf-8") -const std::string softwareVersion = "20260127-2.3.11"; +const std::string softwareVersion = "20260129-2.3.12"; const std::string euiJsonVersion = "1.0.6"; #define GigaByte 1073741824 #define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径 diff --git a/src/core/service/detData.h b/src/core/service/detData.h index fa1bac5..d1eba91 100644 --- a/src/core/service/detData.h +++ b/src/core/service/detData.h @@ -164,10 +164,10 @@ public: #pragma region 结果相关 bool aiDetOK = true; bool halconOK = true; - std::vector resultSaveText; - void setNg(bool aiNg, bool halconNg, std::vector saveText) { - aiDetOK = !aiNg; - halconOK = !halconNg; + std::vector resultSaveText; + void setNg(bool aiDetOK, bool halconOK, std::vector saveText) { + aiDetOK = aiDetOK; + halconOK = halconOK; resultSaveText = saveText; } //结果图展示预设 diff --git a/src/core/service/imgSaveThreadManager.h b/src/core/service/imgSaveThreadManager.h index 63774f3..c278eff 100644 --- a/src/core/service/imgSaveThreadManager.h +++ b/src/core/service/imgSaveThreadManager.h @@ -36,7 +36,7 @@ public: result.replace("{imageType}", typeStr); // 替换检测结果占位符 - QString processResult; + std::string processResult; if (!data->aiDetOK && !data->halconOK) processResult = "NG"; else if (!data->aiDetOK) processResult = "aiNG"; else if (!data->halconOK) processResult = "algoNG"; @@ -44,7 +44,7 @@ public: for (int i = 0; i < data->resultSaveText.size(); i++) { processResult.append("_" + data->resultSaveText[i]); } - result.replace("{processResult}", QString::fromStdString(repairWindowsFileName(processResult.toStdString()))); + result.replace("{processResult}", QString::fromStdString(repairWindowsFileName(processResult))); // 替换SN/设备信息占位符 QString snCode = (data->SNcode.size() > 0 && data->SNcode.size() < 50) diff --git a/src/mission/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h b/src/mission/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h index da66973..ff3dd5c 100644 --- a/src/mission/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h +++ b/src/mission/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h @@ -16,7 +16,7 @@ static bool ALGO_BaoMoHouDiBu(std::shared_ptr data, baoMoHouDiBuDetPar class _581_BaoMo : public mission { public: - using baoMoHouDiBuTrigger = _581_Single_triggerTemplate; + using baoMoHouDiBuTrigger = _581_Single_triggerTemplate; baoMoHouDiBuTrigger _station_1; baoMoHouDiBuTrigger _station_2; diff --git a/src/mission/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.cpp b/src/mission/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.cpp new file mode 100644 index 0000000..734688e --- /dev/null +++ b/src/mission/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.cpp @@ -0,0 +1,170 @@ +#include <581_YiCiZhuYe_canye.h> + +void exceptionResume(std::shared_ptr data, canyeParams* _detParams, sx_581_address address, QString why = "") { + qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode) << why; + cv::Mat Paint; + data->getOriImg(0).copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, why.toStdString(), cv::Point(500, 50), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->insertResultImg(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 +} +bool yizhuCanYe(std::shared_ptr data, canyeParams* _detParams, sx_581_address address) { + + try + { + if (!_detParams->DOGLIVE) + { + exceptionResume(data, _detParams, address, "未插加密狗"); + return true; + } + else + { + std::vectordefects; + QByteArray plcResult = "1"; + QString detResult = "OK"; + cv::Mat sourceImg = data->getOriImg(0); + //sourceImg = cv::imread("C:\\Users\\Main\\Desktop\\yizhu\\1.bmp",-1); + cv::Mat Paint; + + +#if 1 + HalconCpp::HObject in_Image = MatToHObject(sourceImg); + + { + HDevEngineCpp::HDevProcedure proc("Crop_Image_DJY_8"); + HDevProcedureCall procedureCall(proc); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_FilePath", "./halconFiles/"); + procedureCall.Execute(); + HObject out_CroImage = procedureCall.GetOutputIconicParamObject("out_CroImage"); + HTuple out_X = procedureCall.GetOutputCtrlParamTuple("out_X"); + HTuple out_Y = procedureCall.GetOutputCtrlParamTuple("out_Y"); + HTuple out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + int outFlag = out_Flag.D(); + cv::Mat AfterCutImage; + + if (outFlag == 1) + { + AfterCutImage = HObject2Mat(out_CroImage); + } + else + { + AfterCutImage = sourceImg; + defects.push_back("定位算法切图失败"); + qCritical() << "定位算法切图失败"; + } + AfterCutImage.copyTo(Paint); + TextRendererZH TextRenderer(Paint.cols, Paint.rows, 100); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + if (outFlag == 0) + { + TextRenderer.putText(Paint, out_NgTails.ToString().Text(), cv::Point(100, 300), cv::Scalar(0, 0, 255)); + } + cv::Mat clsMat; + cv::resize(AfterCutImage, clsMat, cv::Size(256, 256)); + int res = _detParams->clsCanYe->Evaluate(clsMat);//一级粗分类 + if (res)//不为0,则为缺陷 + { + data->insertSegOriginImg(AfterCutImage); + TextRenderer.putText(Paint, "残液粗分类识别NG", cv::Point(100, 200), cv::Scalar(0, 0, 255)); + defects.push_back("残液粗分类识别NG"); + plcResult = "2"; + } + else + { + cv::Mat DefectResultImg = ~_detParams->segCanYe->Evaluate(AfterCutImage); + data->insertSegOriginImg(AfterCutImage); + { + std::vector>contours; + cv::findContours(DefectResultImg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + int totalArea = 0; + for (int i = 0; i < contours.size(); i++) + { + int Area = cv::contourArea(contours[i]); + totalArea += Area; + cv::drawContours(Paint, contours, i, cv::Scalar(0, 0, 255));//大于阈值画红色 + } + QString str = "TotalArea:" + QString::number(totalArea); + if (totalArea > 0) { + TextRenderer.putText(Paint, "残液总面积(pix):" + std::to_string(totalArea), cv::Point(100, 200), cv::Scalar(255, 0, 0)); + } + if (totalArea > 10000) + { + plcResult = "2"; + defects.push_back("残液面积过大NG"); + } + } + } + if (plcResult == "1") + { + TextRenderer.putText(Paint, "OK", cv::Point(100, 100), cv::Scalar(0, 255, 0)); + } + else + { + TextRenderer.putText(Paint, "NG", cv::Point(100, 100), cv::Scalar(0, 0, 255)); + data->aiDetOK = false; + } + } +#elif 1 + sourceImg.copyTo(Paint); + QString okNgSaveText = "OK"; + { + cv::Mat workImg; + cv::resize(sourceImg, workImg, cv::Size(), 0.25, 0.25); + cv::Rect rect1; + /////////////定位 ////////////////// + //cv::resize(workImg, workImg, cv::Size(), 0.25, 0.25); + cv::Mat dingWeiResultImg = ~_detParams->segDingWei->Evaluate(workImg); + cv::Rect dingWeiRect = findMaxAreaContour(dingWeiResultImg); + if (dingWeiRect.x == 0 && dingWeiRect.y == 0 || dingWeiRect.width < 10 || dingWeiRect.height < 10) { + exceptionResume(data, _detParams, address, "定位注液孔失败"); + return true; + } + cv::Point2f center(dingWeiRect.x + dingWeiRect.width / 2, dingWeiRect.y + dingWeiRect.height / 2); + cv::Mat centerImg; + cv::Rect cutArea = cv::Rect(center.x - 64, center.y - 64, 128, 128); + workImg(cutArea).copyTo(centerImg); + //////////////////////////////////// + int res = 0; + res = _detParams->clsCanYe->Evaluate(centerImg); + data->segOriginImgs.push_back(centerImg); + if (res == 0) { + + cv::putText(Paint, "OK", cv::Point(100, 500), 1, 20, cv::Scalar(0, 255, 0), 10); + cv::rectangle(Paint, cv::Rect(cutArea.x * 4, cutArea.y * 4, cutArea.width * 4, cutArea.height * 4), cv::Scalar(0, 255, 0), 3); + } + else { + + cv::putText(Paint, "OK", cv::Point(100, 500), 1, 20, cv::Scalar(0, 255, 0), 10); + cv::rectangle(Paint, cv::Rect(cutArea.x * 4, cutArea.y * 4, cutArea.width * 4, cutArea.height * 4), cv::Scalar(0, 0, 255), 3); + plcResult = "2"; + data->aiDetOK = false; + } + } +#endif + plcResult = "1"; + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + data->service->_missionResultHandle->toBarChart(data->SNcode, defects); + data->insertResultImg(Paint); + return true; + } + } + CATCH_EXCEPTIONS + exceptionResume(data, _detParams, address, "检测程序异常"); + return true; +} + +mission* createMission() { + return new _581_YiCiZhuYe_canye(); +} +void destroyMission(mission* _mission) { + delete _mission; +} + diff --git a/src/mission/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.h b/src/mission/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.h new file mode 100644 index 0000000..2349d92 --- /dev/null +++ b/src/mission/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.h @@ -0,0 +1,59 @@ +#include +#include +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +#pragma endregion +class canyeParams { +public: + handdleAI::pSegmentation* segDingWei = nullptr; + handdleAI::pSegmentation* segCanYe = nullptr; + handdleAI::pClassification* clsCanYe = nullptr; + bool YiZhu = true; + bool DOGLIVE = true; +}; + +bool yizhuCanYe(std::shared_ptr data, canyeParams* _detParams, sx_581_address address); +bool erzhuCanYe(std::shared_ptr data, canyeParams* _detParams, sx_581_address address); + +class _581_YiCiZhuYe_canye : public mission { +public: + _581_SX_Single_triggerTemplate< canyeParams> cam_1; + _581_SX_Single_triggerTemplate< canyeParams> cam_2; + _581_SX_Single_triggerTemplate< canyeParams> cam_3; + std::vector < canyeParams> canyeDetParams = std::vector < canyeParams>(3); + bool initOnce = false; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl"); + if (initOnce == false) { + for (auto¶m : canyeDetParams) { + if (param.DOGLIVE == false) + continue; + //param.segDingWei = handdleAI::CreateSegObjS("./handleaiModels/yiCiZhuYe/pSeg_DingWei.BHD", 16, 0); + param.segCanYe = handdleAI::CreateSegObjS("./handleaiModels/yiCiZhuYe/pSeg_CanYe.BHD", 16, 0); + param.clsCanYe = handdleAI::CreateClsObjV3("./handleaiModels/yiCiZhuYe/pCls_CanYe.BHD", 0, 1); + + } + initOnce = true; + } + } + bool initCustom() { +#pragma region 注册触发器回调 + + cam_1.init("Camera1", "残液检测-相机1", { { 1900, 1,{1800},"1910","1920"} }, 1, &canyeDetParams[0], _serviceManager, bridge, yizhuCanYe); + cam_2.init("Camera2", "残液检测-相机2", { { 1901, 1,{1830},"1911","1921"} }, 1, & canyeDetParams[1], _serviceManager, bridge, yizhuCanYe); + cam_3.init("Camera3", "残液检测-相机3", { { 1902, 1,{1850},"1912","1922"} }, 1, & canyeDetParams[2], _serviceManager, bridge, yizhuCanYe); + +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581_YiCiZhuYe_canye/CMakeLists.txt b/src/mission/581_YiCiZhuYe_canye/CMakeLists.txt new file mode 100644 index 0000000..599e8f5 --- /dev/null +++ b/src/mission/581_YiCiZhuYe_canye/CMakeLists.txt @@ -0,0 +1,78 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES})