From 0c3703a6a6b2ba5be3e6bc7870a259f94ab71ecc Mon Sep 17 00:00:00 2001 From: RCi <15089880081@163.com> Date: Sun, 16 Nov 2025 19:17:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/generalJsonParsing.hpp | 15 +- include/simpleAlgo.h | 1 + include/yhGlobal.h | 26 +- src/core/service/detCallbackChain.hpp | 2 +- src/core/service/paramSyncManager.h | 17 +- src/core/service/triggerManager.cpp | 16 +- src/core/service/triggerManager.h | 18 +- src/cutImage/baoMo.hpp | 47 +++- src/cutImage/main.cpp | 2 +- src/launcher/appConfig/auth.hpp | 2 +- .../581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp | 231 ++++++++++++++++++ .../581-BaoMo-Cam1213/581-BaoMo-Cam1213.h | 44 ++++ .../581-BaoMo-Cam1213}/CMakeLists.txt | 0 .../581-BaoMo-Cam1234/581-BaoMo-Cam1234.cpp | 160 ++++++++++++ .../581-BaoMo-Cam1234/581-BaoMo-Cam1234.h | 64 +++++ .../BaoMo/581-BaoMo-Cam1234/CMakeLists.txt | 77 ++++++ .../581-BaoMo-Cam5678/581-BaoMo-Cam5678.cpp | 8 + .../581-BaoMo-Cam5678/581-BaoMo-Cam5678.h | 221 +++++++++++++++++ .../BaoMo/581-BaoMo-Cam5678/CMakeLists.txt | 77 ++++++ .../581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp | 0 .../581-BaoMo-Cam91011/581-BaoMo-Cam91011.h | 17 +- .../BaoMo/581-BaoMo-Cam91011/CMakeLists.txt | 77 ++++++ src/mission/BaoMo/CMakeLists.txt | 11 + 23 files changed, 1070 insertions(+), 63 deletions(-) create mode 100644 src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp create mode 100644 src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h rename src/mission/{581-BaoMo-Cam91011 => BaoMo/581-BaoMo-Cam1213}/CMakeLists.txt (100%) create mode 100644 src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.cpp create mode 100644 src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.h create mode 100644 src/mission/BaoMo/581-BaoMo-Cam1234/CMakeLists.txt create mode 100644 src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.cpp create mode 100644 src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.h create mode 100644 src/mission/BaoMo/581-BaoMo-Cam5678/CMakeLists.txt rename src/mission/{ => BaoMo}/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp (100%) rename src/mission/{ => BaoMo}/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h (70%) create mode 100644 src/mission/BaoMo/581-BaoMo-Cam91011/CMakeLists.txt create mode 100644 src/mission/BaoMo/CMakeLists.txt diff --git a/include/generalJsonParsing.hpp b/include/generalJsonParsing.hpp index 5d32b29..171d010 100644 --- a/include/generalJsonParsing.hpp +++ b/include/generalJsonParsing.hpp @@ -1,4 +1,5 @@ -#include +#pragma once +#include #include #include @@ -122,14 +123,4 @@ static void printNlohmannJson(nlohmann::json input, int depth = 0) else if (input.is_null()) { std::cout << indent_str << "null\n"; } -} - -template -T getOrInit(nlohmann::json& j, const std::string& key, const T& def) { - if (!j.contains(key) || j[key].is_null()) { - j[key] = def; // 如果键不存在或值为 null,初始化为默认值 - return def; - } - return j[key].get(); // 返回键对应的值 -} -#pragma once \ No newline at end of file +} \ No newline at end of file diff --git a/include/simpleAlgo.h b/include/simpleAlgo.h index cdda621..70dd8f5 100644 --- a/include/simpleAlgo.h +++ b/include/simpleAlgo.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #pragma once using namespace HalconCpp; diff --git a/include/yhGlobal.h b/include/yhGlobal.h index 63f3f8d..0ef7fe0 100644 --- a/include/yhGlobal.h +++ b/include/yhGlobal.h @@ -55,6 +55,24 @@ public: //算法回调函数需要包含完整的算法流程以及发送信号,发送ui图表,捕获异常,处理异常等操作 //并且注意 异常可能会导致运行不到发送信号的函数,请在处理异常时发送异常结果 + + +void generalExceptionResume(std::shared_ptr data, yh_581_address address, QString why = "") { + qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode) << why; + cv::Mat Paint; + data->oriImgs[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->resultImgs.push_back(Paint); + if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + else + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//结果反馈 +} static bool generalAlgoTest(std::shared_ptr data, detParams* _detParams, yh_581_address address) { try { qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; @@ -82,9 +100,9 @@ static bool generalAlgoTest(std::shared_ptr data, detParams* _detParam else src1.copyTo(Paint); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "划伤", cv::Point(10,10), cv::Scalar(0, 255, 0)); - cv::putText(Paint, "pos:" + data->additional["触发地址"].toString().toStdString(), cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 0, 0), 2); + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, "OK", cv::Point(10,10), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.123");//发送数据1 data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2)+ "_0.456");//发送数据2 data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 @@ -96,8 +114,8 @@ static bool generalAlgoTest(std::shared_ptr data, detParams* _detParam data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送异常结果 return false; } -template +template //此类适用于单相机多触发地址需要联合判断的情况的情况 比如顶盖焊,包膜,入壳机台 //例触发地址有4个,输入信号为 1 0 0 1 则触发1和4的地址拍照检测,2和3拍照取图并废弃 class _581_Union_triggerTemplate { diff --git a/src/core/service/detCallbackChain.hpp b/src/core/service/detCallbackChain.hpp index 12fc504..614a089 100644 --- a/src/core/service/detCallbackChain.hpp +++ b/src/core/service/detCallbackChain.hpp @@ -99,7 +99,7 @@ public: // 通用的检测结果处理 void detectionResultHandle(std::shared_ptr data) { //计算处理总耗时(CT) - QString totalCtStr = "algoCT->" + QString::number(data->algoTime) + "ms|SN" + QString::fromStdString(data->SNcode); + QString totalCtStr = data->uuid + QString::fromStdString(data->SNcode) + "algoCT->" + QString::number(data->algoTime) + "ms|SN" + QString::fromStdString(data->SNcode); qDebug() << totalCtStr; //std::cout << totalCtStr.toStdString() << std::endl; // 将耗时数据等保存入数据库或日志 diff --git a/src/core/service/paramSyncManager.h b/src/core/service/paramSyncManager.h index f1c56c4..d5bf681 100644 --- a/src/core/service/paramSyncManager.h +++ b/src/core/service/paramSyncManager.h @@ -8,7 +8,7 @@ #include #include #include - +#include class paramSyncManager :public QObject{ @@ -155,9 +155,9 @@ public: updateJsonFromMap(); return json; } - + //遍历 map,重新构建嵌套的 JSON 结构 void updateJsonFromMap() { - //遍历 map,重新构建嵌套的 JSON 结构 + nlohmann::ordered_json newJson; for (auto it = map.begin(); it != map.end(); ++it) { QString key = it.key(); @@ -168,20 +168,21 @@ public: QString paramName = parts.mid(1).join('.'); //确保组存在 - if (json.find(group.toStdString()) == json.end()) { - json[group.toStdString()] = nlohmann::ordered_json::object(); + if (newJson.find(group.toStdString()) == newJson.end()) { + newJson[group.toStdString()] = nlohmann::ordered_json::object(); } //添加参数到组 - json[group.toStdString()][paramName.toStdString()] = qVariantToJson(it.value()); + newJson[group.toStdString()][paramName.toStdString()] = qVariantToJson(it.value()); } else { - json[key.toStdString()] = qVariantToJson(it.value()); + newJson[key.toStdString()] = qVariantToJson(it.value()); } } missionKey.clear(); - for (auto it = json.begin(); it != json.end(); ++it) { + for (auto it = newJson.begin(); it != newJson.end(); ++it) { missionKey.push_back(QString::fromStdString(it.key())); } + json = newJson; } // 清空所有参数 diff --git a/src/core/service/triggerManager.cpp b/src/core/service/triggerManager.cpp index 247ed8d..80d715c 100644 --- a/src/core/service/triggerManager.cpp +++ b/src/core/service/triggerManager.cpp @@ -2,9 +2,9 @@ #include #include #include +#include +triggerManager::triggerManager(ServiceManager* _serviceManager, bSignalHub* bridgeIn,nlohmann::ordered_json& triggerJson){ -triggerManager::triggerManager(ServiceManager* _serviceManager, bSignalHub* bridgeIn,nlohmann::ordered_json& triggerJson) -{ bridge = bridgeIn; dManager = _serviceManager->_detDataManager; _cameraManager = _serviceManager->_cameraManager; @@ -19,8 +19,10 @@ triggerManager::triggerManager(ServiceManager* _serviceManager, bSignalHub* brid triggerFileName = QString::fromStdString(triggerJson["moduleName"]); IpAndPort = QString::fromStdString(triggerJson["initStr"]); - heartBeatIntervalMS = triggerJson["heartBeatIntervalMS"]; - sleepIntervalMS = triggerJson["sleepIntervalMS"]; + + heartBeatIntervalMS = triggerJson.value("heartBeatIntervalMS",1); + sleepIntervalMS = triggerJson.value("sleepIntervalMS", 1); + std::vector heartbeats = triggerJson["heartBeatCmd"]; for (auto& cmd : heartbeats) { heartBeatCmds.push_back(QString::fromStdString(cmd)); @@ -152,7 +154,6 @@ void triggerManager::decodeCameraCMD(readAllStruct& _struct, QByteArray byte) checkPlcValueViewer(_struct, byte); } - void triggerManager::checkCallback(readAllStruct _struct, QByteArray& byteArray) {//检查是否符合回调函数的触发条件 QMutexLocker locer(&mutex); for (auto callback : triggerCallbackFuncs[_struct.readAllCmd]) @@ -249,7 +250,7 @@ void triggerManager::checkPlcValueViewer(readAllStruct& _struct, QByteArray& byt if (newValue != data.value) { data.value = newValue; - if (data.type == finsFloat) + if (data.type == finsFloat) emit bridge->runCommand_refeshPlcValueViewer(data.valueAddr, QString::number(data.value.toDouble(), 'f', 4)); else @@ -258,4 +259,5 @@ void triggerManager::checkPlcValueViewer(readAllStruct& _struct, QByteArray& byt } } -} \ No newline at end of file +} + diff --git a/src/core/service/triggerManager.h b/src/core/service/triggerManager.h index 2cd847b..09d5f35 100644 --- a/src/core/service/triggerManager.h +++ b/src/core/service/triggerManager.h @@ -18,7 +18,7 @@ class detDataManager; class lightSourceManager; class ServiceManager; -// 将此静态函数加入到类 triggerManager 的合适位置(如 private 部分) +//从fins中读取浮点型 static float readFinsFloatFromQByteArray(const QByteArray& buf, int startByteIndex, bool highLowConversion) { if (buf.isEmpty()) { return 0.0f; @@ -54,6 +54,18 @@ static float readFinsFloatFromQByteArray(const QByteArray& buf, int startByteInd std::memcpy(&value, &raw, sizeof(float)); return value; } +//将字符串转换为供发送的语句 +static QByteArray convertStringForFins(const QString& text) { + QByteArray sendText; + for (int i = 0; i < text.size() / 2; i ++) + sendText += QByteArray::number(text[i * 2].unicode() + text[i * 2 + 1].unicode() * 256) + ","; + + if (text.size() % 2 == 1) + sendText += QByteArray::number(text[text.size() - 1].unicode()); + else + sendText.chop(1); + return sendText; +} //防止重复触发 class triggerLockerT { public: @@ -320,9 +332,7 @@ public: std::map> triggerCallbackFuncs; //联合条件的触发器注册 - bool registerUnionCallback(std::vector> triggerAddressAndValue, - conditionMode mode, - uniontriggerCallback func, std::string funcName) { + bool registerUnionCallback(std::vector> triggerAddressAndValue,conditionMode mode,uniontriggerCallback func, std::string funcName) { QMutexLocker locer(&mutex); if (triggerAddressAndValue.size() < 2) { qCritical() << "联合触发器至少需要两个条件"; diff --git a/src/cutImage/baoMo.hpp b/src/cutImage/baoMo.hpp index 7c6ab22..7d7872f 100644 --- a/src/cutImage/baoMo.hpp +++ b/src/cutImage/baoMo.hpp @@ -1,21 +1,44 @@ #include #include #include +#include +#include using namespace std; -void baomoXiaDMianCut(const std::string path, const std::string format, const std::string outputPath) { +void baomoXiaDMianCut(const std::string path, const std::string format, const std::string outputPath,cv::Size fillter) { //int - //handdleAI::pSegmentation* seg = handdleAI::CreateSegObjS("./cutImgFiles/baoMoXiaDaMian_seg.BHD", 1, 0); - //std::vector images; - //cv::glob(path + "/*." + format, images, false); - //for (size_t i = 0; i < images.size(); i++) { - // cv::Mat srcImage = cv::imread(images[i],-1); - // if (srcImage.empty()) { - // std::cout << "ͼƬΪ¿գ¡" << std::endl; - // continue; - // } - // auto SegResult = ~seg->Evaluate(srcImage); + handdleAI::pSegmentation* seg = handdleAI::CreateSegObjS("./cutImgFiles/baoMoXiaDaMian_seg.BHD", 1, 0); + std::vector images; + cv::glob(path + "/*." + format, images, false); + for (size_t i = 0; i < images.size(); i++) { + std::string filePath = outputPath + "/" + std::to_string(i) + "/"; + createDirectoryIfNotExists(QString::fromStdString(filePath)); + cv::Mat srcImage = cv::imread(images[i], -1); + cv::Mat Paint; + if (srcImage.cols == 1) + cv::cvtColor(srcImage, Paint, cv::COLOR_GRAY2BGR); + else + srcImage.copyTo(Paint); - //} + if (srcImage.empty()) { + std::cout << "ͼƬΪ¿գ¡" << std::endl; + continue; + } + auto SegResult = ~seg->Evaluate(srcImage); + std::vector> contours; + cv::findContours(SegResult,contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + for (int ii = 0; ii < contours.size(); ii++) { + cv::Rect rect = cv::boundingRect(contours[i]); + if (rect.width > fillter.width || rect.height > fillter.height) { + cv::putText(Paint, std::to_string(i), cv::Point(rect.x + rect.width / 2, rect.y + rect.height / 2), 1, 2, cv::Scalar(255, 255, 255), 5); + cv::rectangle(Paint, rect, cv::Scalar(0, 0, 255), 3); + auto imgs = cutImg2ClsVec(rect, srcImage); + for (int o = 0; o < imgs.size(); o++) { + cv::imwrite(filePath + "/" + std::to_string(ii) + "_" + std::to_string(o) + "CLS.bmp",imgs[o]); + } + } + } + cv::imwrite(filePath + "/Paint.bmp", Paint); + } } \ No newline at end of file diff --git a/src/cutImage/main.cpp b/src/cutImage/main.cpp index 0b3a49d..9d8e7c8 100644 --- a/src/cutImage/main.cpp +++ b/src/cutImage/main.cpp @@ -2,6 +2,6 @@ int main(int argc, char* argv[]) { - std::cout << "hello world" << std::endl; + //baomoXiaDMianCut( return 1; } \ No newline at end of file diff --git a/src/launcher/appConfig/auth.hpp b/src/launcher/appConfig/auth.hpp index 6d7eb07..cae97ff 100644 --- a/src/launcher/appConfig/auth.hpp +++ b/src/launcher/appConfig/auth.hpp @@ -318,7 +318,7 @@ namespace Auth { // 显示权限不足的弹窗 QMessageBox::warning(nullptr, TR("Insufficient permissions"), - QString(TR("您没有足够的权限执行此操作。\n\n需要权限级别: %1\n当前权限级别: %2")) + QString(TR("You do not have sufficient permissions to perform this action.\n\nRequired level: %1\nCurrent level: %2")) .arg(QString::fromStdString(userLevelToString(requiredLevel))) .arg(QString::fromStdString(userLevelToString(currentUserLevel)))); } diff --git a/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp b/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp new file mode 100644 index 0000000..0db6fde --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp @@ -0,0 +1,231 @@ +#include <581-BaoMo-Cam1213.h> + +struct halconResult { + double resultX = -99; + double resultY = -99; +}; +halconResult dituo(std::shared_ptr data,cv::Mat& src, cv::Mat& Paint,bool isLeft) { + halconResult result; + try { + cv::Mat srcHalf; + cv::resize(src, srcHalf, cv::Size(0, 0), 0.5, 0.5); + if (srcHalf.channels() != 3) + cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); + else + srcHalf.copyTo(Paint); + TextRendererZH textPainter(Paint.cols, Paint.rows, 50); + + HalconCpp::HObject in_Image = MatToHObject(src); + HDevEngineCpp::HDevProcedure proc("_4_TD_BlueCover_Inspection"); + HDevProcedureCall procedureCall(proc); + + //vs+halcon联调debug + /*HDevEngineCpp::HDevEngine myEngine; + myEngine.StartDebugServer(); + procedureCall.SetWaitForDebugConnection(true);*/ + + HTuple in_Par, in_FilePath("./halconFiles/"); + in_Par[0] = data->service->_paramSyncManager->get("底托检测", "宽度阈值(mm)", 150).toInt(); + in_Par[1] = data->service->_paramSyncManager->get("底托检测", "高度阈值(mm)", 150).toInt(); + in_Par[2] = data->service->_paramSyncManager->get("底托检测", "面积阈值(mm)", 300).toInt(); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_Par", in_Par); + procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.Execute(); + HTuple out_X = procedureCall.GetOutputCtrlParamTuple("out_X"); + HTuple out_Y = procedureCall.GetOutputCtrlParamTuple("out_Y"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + HTuple out_NgDetails = procedureCall.GetOutputCtrlParamTuple("out_NgDetails"); + int outFlag = out_Flag.D(); + //handleAiFuture.wait(); + //_result = handleAiFuture.get(); + if (outFlag == 1) { + textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + } + else { + data->halconOK = false; + for (int i = 0; i < out_Y.Length() / 2 - 1; i++) { + cv::circle(Paint, cv::Point(out_X[i * 2 + 1].D(), out_Y[i * 2].D()) / 2, 1, + cv::Scalar(0, 0, 255), 1); + } + std::string ngDetails = out_NgDetails.ToString().Text(); + result.resultX = out_X.D(); + result.resultY = out_Y.D(); + if (isLeft == true) { + textPainter.putText(Paint, "缺陷长度:" + std::to_string(result.resultX) + "mm", cv::Point(700, 800), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "缺陷宽度:" + std::to_string(result.resultY) + "mm", cv::Point(700, 850), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, ngDetails.substr(1, ngDetails.length() - 2), cv::Point(700, 900), cv::Scalar(0, 0, 255)); + } + else { + textPainter.putText(Paint, "缺陷长度:" + std::to_string(result.resultX) + "mm", cv::Point(50, 800), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "缺陷宽度:" + std::to_string(result.resultY) + "mm", cv::Point(50, 850), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, ngDetails.substr(1, ngDetails.length() - 2), cv::Point(50, 900), cv::Scalar(0, 0, 255)); + } + } + } + CATCH_EXCEPTIONS + return result; +} +bool ALGO_BaoMoHouDiBu_test(std::shared_ptr data, baoMoHouDiBuDetParams* _detParams, yh_581_address address) { + try { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + std::vector < std::string> defects; + + //data->oriImgs.clear(); + //data->oriImgs.push_back(cv::imread("D://testImage/dituo_1.bmp", -1)); + //data->oriImgs.push_back(cv::imread("D://testImage/dituo_2.bmp", -1)); + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() < 2) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + data->resultImgs.push_back(Paint); + return false; + } + if (data->oriImgs[0].rows == 100) { + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + return false; + } + + cv::Mat Paint,Paint1,Paint2; + bool leftFirst = address.triggerAddr == 20200; + auto feature1 = std::async(std::launch::async,dituo, data, std::ref(data->oriImgs[0]), std::ref(Paint1),leftFirst); + auto feature2 = std::async(std::launch::async, dituo, data, std::ref(data->oriImgs[1]), std::ref(Paint2),~leftFirst); + feature1.wait(); + halconResult hResult1 = feature1.get(); + + feature2.wait(); + halconResult hResult2 = feature2.get(); + cv::hconcat(Paint1, Paint2, Paint); + + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(hResult1.resultX));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(hResult1.resultY));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(hResult2.resultX));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_" + QByteArray::number(hResult2.resultY));//发送结果 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1,0,1");//发送结果 + data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects); + data->resultImgs.push_back(Paint); + } + CATCH_EXCEPTIONS + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1,0,1");//发送结果 + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + data->resultImgs.push_back(Paint); + return true; +} +bool ALGO_BaoMoHouDiBu(std::shared_ptr data, baoMoHouDiBuDetParams* _detParams, yh_581_address address) { + try { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + std::vector < std::string> defects; + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() < 2) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + data->resultImgs.push_back(Paint); + return false; + } + if (data->oriImgs[0].rows == 100) { + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); + data->resultImgs.push_back(Paint); + return false; + } + + cv::Mat Paint; + clock_t start, finish; + start = clock(); + + cv::Mat src1 = data->oriImgs[0]; + cv::Mat srcHalf; + cv::resize(src1, srcHalf, cv::Size(0, 0), 0.5, 0.5); + if (srcHalf.channels() != 3) + cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); + else + srcHalf.copyTo(Paint); + TextRendererZH textPainter(Paint.cols, Paint.rows, 50); + HalconCpp::HObject in_Image = MatToHObject(src1); + //vs+halcon联调debug + HDevEngineCpp::HDevProcedure proc("_4_TD_BlueCover_Inspection"); + HDevProcedureCall procedureCall(proc); + + /*HDevEngineCpp::HDevEngine myEngine; + myEngine.StartDebugServer(); + procedureCall.SetWaitForDebugConnection(true);*/ + + HTuple in_Par, in_FilePath("./halconFiles/"); + in_Par[0] = data->service->_paramSyncManager->get("底托检测","宽度阈值(mm)", 150).toInt(); + in_Par[1] = data->service->_paramSyncManager->get("底托检测", "高度阈值(mm)", 150).toInt(); + in_Par[2] = data->service->_paramSyncManager->get("底托检测", "面积阈值(mm)", 300).toInt(); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_Par", in_Par); + procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.Execute(); + HTuple out_X = procedureCall.GetOutputCtrlParamTuple("out_X"); + HTuple out_Y = procedureCall.GetOutputCtrlParamTuple("out_Y"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + HTuple out_NgDetails = procedureCall.GetOutputCtrlParamTuple("out_NgDetails"); + int outFlag = out_Flag.D(); + //handleAiFuture.wait(); + //_result = handleAiFuture.get(); + double resultX = -99, resultY = -99; + if (outFlag == 1) { + textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + } + else { + data->halconOK = false; + for (int i = 0; i < out_Y.Length() / 2 - 1; i++) { + cv::circle(Paint, cv::Point(out_X[i * 2 + 1].D(), out_Y[i * 2].D()) / 2, 1, + cv::Scalar(0, 0, 255), 1); + } + std::string ngDetails = out_NgDetails.ToString().Text(); + resultX = out_X.D(); + resultY = out_Y.D(); + if (address.triggerAddr == 20200 || address.triggerAddr == 20402) { + textPainter.putText(Paint, "缺陷长度:" + std::to_string(resultX) + "mm", cv::Point(700, 800), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "缺陷宽度:" + std::to_string(resultY) + "mm", cv::Point(700, 850), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, ngDetails.substr(1, ngDetails.length() - 2), cv::Point(700, 900), cv::Scalar(0, 0, 255)); + } + else { + textPainter.putText(Paint, "缺陷长度:" + std::to_string(resultX) + "mm", cv::Point(50, 800), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "缺陷宽度:" + std::to_string(resultY) + "mm", cv::Point(50, 850), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, ngDetails.substr(1, ngDetails.length() - 2), cv::Point(50, 900), cv::Scalar(0, 0, 255)); + } + } + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1,0,1");//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(resultX));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(resultY));//发送结果 + data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects); + data->resultImgs.push_back(Paint); + } + CATCH_EXCEPTIONS + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1,0,1");//发送结果 + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + data->resultImgs.push_back(Paint); + return true; +} + +mission* createMission() { + return new _581_BaoMo(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h b/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h new file mode 100644 index 0000000..ada0fbc --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +using namespace HDevEngineCpp; + +class baoMoHouDiBuDetParams { +public: + +}; +static bool ALGO_BaoMoHouDiBu_test(std::shared_ptr data, baoMoHouDiBuDetParams* _detParams, yh_581_address address); +static bool ALGO_BaoMoHouDiBu(std::shared_ptr data, baoMoHouDiBuDetParams* _detParams, yh_581_address address); + + +class _581_BaoMo : public mission { +public: + using baoMoHouDiBuTrigger = _581_Single_triggerTemplate; + baoMoHouDiBuTrigger _station_1; + baoMoHouDiBuTrigger _station_2; + + baoMoHouDiBuDetParams _baoMoHouDiBuDetParams; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + } + bool initCustom() { +#pragma region 注册触发器回调 + + _station_1.init("Camera1","包膜后底托位置度检测-左-相机12",20200,1,2, &_baoMoHouDiBuDetParams,_serviceManager,bridge, ALGO_BaoMoHouDiBu_test); + _station_2.init("Camera2", "包膜后底托位置度检测-右-相机13",20400,1,2,&_baoMoHouDiBuDetParams, _serviceManager, bridge, ALGO_BaoMoHouDiBu_test); +#pragma endregion + return true; + } + + + //9600 +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581-BaoMo-Cam91011/CMakeLists.txt b/src/mission/BaoMo/581-BaoMo-Cam1213/CMakeLists.txt similarity index 100% rename from src/mission/581-BaoMo-Cam91011/CMakeLists.txt rename to src/mission/BaoMo/581-BaoMo-Cam1213/CMakeLists.txt diff --git a/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.cpp b/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.cpp new file mode 100644 index 0000000..4b84b21 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.cpp @@ -0,0 +1,160 @@ +#include <581-BaoMo-Cam1234.h> + +cv::Rect extractRegion(cv::Mat& src,int binary_threshold = 50) { + cv::Mat binary; + threshold(src, binary, binary_threshold, 255, cv::THRESH_BINARY); + cv::dilate(binary, binary, cv::getStructuringElement(cv::MORPH_RECT,cv::Size(5,5))); + std::vector> contours; + findContours(binary, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + + double maxArea = 0; + int maxAreaIdx = -1; + for (size_t i = 0; i < contours.size(); i++) { + double area = contourArea(contours[i]); + if (area > maxArea) { + maxArea = area; + maxAreaIdx = i; + } + } + cv::Rect boundingRect = cv::boundingRect(contours[maxAreaIdx]); + return boundingRect; +} +int index = 0; +bool BaoMoQianShangDaMian(std::shared_ptr data, baoMoQianDaMianDetParams* _detParams, yh_581_address address) { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + try { + //cv::Mat segImg; + //cv::resize(data->oriImgs[0], segImg, cv::Size(), 0.5, 0.5); + //cv::Rect ROI = extractRegion(segImg); + //segImg(ROI).copyTo(segImg); + cv::Mat Paint; + if (data->oriImgs[0].channels() == 1) + cv::cvtColor(data->oriImgs[0], Paint, cv::COLOR_GRAY2RGB); + else + data->oriImgs[0].copyTo(Paint); + //TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + //textPainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + //segImg = ~_detParams->seg_baomodamian->Evaluate(segImg); + //std::vector>contours; + //cv::findContours(segImg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + //int clsIndex = 0; + //bool isNG = false; + //for (auto& contour : contours) { + // cv::Rect rect = cv::boundingRect(contour); + // if (rect.width < 60 || rect.height < 60) + // continue; + // cv::Mat clsImg = cutImg2Cls(rect, data->oriImgs[0]); + // data->clsOriginImgs.push_back({ std::to_string(clsIndex),clsImg}); + // int clsResult = _detParams->cls_baomodamian->Evaluate(clsImg); + // if (clsResult == 1 || clsResult == 2) { + // cv::drawContours(Paint, contours, clsIndex, cv::Scalar(0, 0, 255), 3); + // //isNG = true; + // } + // clsIndex++; + //} + TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + //if (isNG == true) { + // textPainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + // if (data->service->_paramSyncManager->get("强制OK", false).toBool()) + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2"); + // else + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + //} + //else { + // textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + //} + //data->segOriginImgs.push_back(segImg); + data->resultImgs.push_back(Paint); + textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + return true; + } + CATCH_EXCEPTIONS + generalExceptionResume(data, address, "检测异常"); + return true; + +} + +bool BaoMoQianXiaDaMian(std::shared_ptr data, baoMoQianDaMianDetParams* _detParams, yh_581_address address) { + + QString date = QDateTime::currentDateTime().toString("yyyy_MM_dd_HH_mm_ss_").toUtf8() + QString::number(index); + //data->service->_triggerManager->writeShort("D" + QByteArray::number(address.snAddr) + "_" + convertStringForFins(date)); + data->SNcode = date.toStdString(); + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + index++; + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + if (data->oriImgs[0].rows == 200) { + generalExceptionResume(data, address, "检测异常"); + return false; + } + try { + cv::Mat segImg; + cv::resize(data->oriImgs[0], segImg, cv::Size(), 0.5, 0.5); + cv::Rect ROI = extractRegion(segImg); + segImg(ROI).copyTo(segImg); + cv::Mat Paint; + if (data->oriImgs[0].channels() == 1) + cv::cvtColor(data->oriImgs[0], Paint, cv::COLOR_GRAY2RGB); + else + data->oriImgs[0].copyTo(Paint); + //TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + //textPainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + segImg = ~_detParams->seg_baomodamian->Evaluate(segImg); + std::vector>contours; + cv::findContours(segImg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + int clsIndex = 0; + bool isNG = false; + for (auto& contour : contours) { + cv::Rect rect = cv::boundingRect(contour); + if (rect.width < 60 || rect.height < 60) + continue; + cv::Mat clsImg = cutImg2Cls(rect, data->oriImgs[0]); + data->clsOriginImgs.push_back({ std::to_string(clsIndex),clsImg}); + int clsResult = _detParams->cls_baomodamian->Evaluate(clsImg); + if (clsResult == 1 || clsResult == 2) { + cv::drawContours(Paint, contours, clsIndex, cv::Scalar(0, 0, 255), 3); + //isNG = true; + } + clsIndex++; + } + TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + //if (isNG == true) { + // textPainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + // if (data->service->_paramSyncManager->get("强制OK", false).toBool()) + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2"); + // else + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + //} + //else { + // textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + //} + textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + data->segOriginImgs.push_back(segImg); + data->resultImgs.push_back(Paint); + + + return true; + } + CATCH_EXCEPTIONS + generalExceptionResume(data, address, "检测异常"); + return true; + +} +mission* createMission() { + return new _581_BaoMo_Cam1234(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.h b/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.h new file mode 100644 index 0000000..f881078 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.h @@ -0,0 +1,64 @@ +#include +#include +#include +#include +using namespace HDevEngineCpp; + +class baoMoQianDaMianDetParams { +public: + handdleAI::pSegmentation* seg_baomodamian = nullptr; + handdleAI::pClassification* cls_baomodamian = nullptr; +}; + + +bool BaoMoQianShangDaMian(std::shared_ptr data, baoMoQianDaMianDetParams* _detParams, yh_581_address address); +bool BaoMoQianXiaDaMian(std::shared_ptr data, baoMoQianDaMianDetParams* _detParams, yh_581_address address); +class _581_BaoMo_Cam1234 : public mission { +public: + using baoMoQianDaMianTrigger = _581_Union_triggerTemplate; + baoMoQianDaMianTrigger _shangdamian_1; + baoMoQianDaMianTrigger _xiadamian_2; + std::vector _baoMoQianDaMianDetParams = std::vector< baoMoQianDaMianDetParams>(2); + + using generalTrigger = _581_Union_triggerTemplate; + generalTrigger _station_3; + generalTrigger _station_4; + detParams _detParams; + bool initOnce = false; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + + if (initOnce == false) { + + /* _baoMoQianDaMianDetParams[0].seg_baomodamian = handdleAI::CreateSegObjS("./handleAiModels/BaoMoQianDaMian_Seg.BHD", 64, 0); + _baoMoQianDaMianDetParams[0].cls_baomodamian = handdleAI::CreateClsObjV3("./handleAiModels/BaoMoQianDaMian_Cls.BHD", 0, 1); + + _baoMoQianDaMianDetParams[1].seg_baomodamian = handdleAI::CreateSegObjS("./handleAiModels/BaoMoQianDaMian_Seg.BHD", 64, 1); + _baoMoQianDaMianDetParams[1].cls_baomodamian = handdleAI::CreateClsObjV3("./handleAiModels/BaoMoQianDaMian_Cls.BHD", 1, 1);*/ + + initOnce = true; + } + + + } + bool initCustom() { +#pragma region 注册触发器回调 + _shangdamian_1.init("Camera1","包膜前外观检测大面相机1(上大面)", 18000,2, 1, &_baoMoQianDaMianDetParams[0], _serviceManager, bridge, BaoMoQianShangDaMian); + _xiadamian_2.init("Camera2", "包膜前外观检测大面相机2(下大面)", 18200,2, 1, &_baoMoQianDaMianDetParams[1], _serviceManager, bridge, BaoMoQianXiaDaMian); + + _station_3.init("Camera3", "包膜前产品边缘检测大面-外-相机3(下大面顶盖侧)", 18400,2, 2, &_detParams,_serviceManager,bridge, generalAlgoTest); + _station_4.init("Camera4", "包膜前产品边缘检测大面-内-相机4(下大面底部侧)", 18600 ,2, 2, &_detParams, _serviceManager, bridge, generalAlgoTest); +#pragma endregion + return true; + } + void reloadAlgo(QByteArray& byteArray) { + + } + + //9600 +}; + + + +#pragma once \ No newline at end of file diff --git a/src/mission/BaoMo/581-BaoMo-Cam1234/CMakeLists.txt b/src/mission/BaoMo/581-BaoMo-Cam1234/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam1234/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +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 REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network 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 + ) + + +# 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}) diff --git a/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.cpp b/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.cpp new file mode 100644 index 0000000..a9252aa --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.cpp @@ -0,0 +1,8 @@ +#include <581-BaoMo-Cam5678.h> + +mission* createMission() { + return new _581_BaoMo(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.h b/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.h new file mode 100644 index 0000000..00c5395 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.h @@ -0,0 +1,221 @@ +#include +#include + +struct _581_BaoMoResult +{ + bool result = true; + std::vector < std::string> defects; +}; +class baoMoHouDaMianDetParams { +public: + handdleAI::pSegmentation* dingwei = nullptr; + handdleAI::pSegmentation* seg = nullptr; + handdleAI::pClassification* cls = nullptr; +}; +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +#pragma endregion +#pragma region 算法 + +std::vector BaoMoHou_DaMianAi(std::shared_ptr data, cv::Mat src, cv::Mat& Paint, + baoMoHouDaMianDetParams* _detParams) { + if (_detParams->seg == nullptr || _detParams->cls == nullptr) + return {}; + std::vector defects; + TextRendererZH textPainter(Paint.cols, Paint.rows, 150); + bool huaShangNg = false; + cv::Mat segImg = ~_detParams->seg->Evaluate(src); + std::vector> contours; + cv::findContours(segImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + bool isOK = true; + for (int i = 0; i < contours.size(); i++) { + cv::Rect rect = cv::boundingRect(contours[i]); + if (rect.width < 100 || rect.height < 100) continue; // 过滤掉小轮廓 + auto clsImgs = cutImg2ClsVec(rect, src, cv::Size(128, 128)); + bool clsIsNg = false; + for (auto& clsImg : clsImgs) { + int clsResult = _detParams->cls->Evaluate(clsImg); + if (clsResult == 1) { + clsIsNg = true; + huaShangNg = true; + } + data->clsOriginImgs.push_back({ "CLS",clsImg }); + } + if (clsIsNg == true) { + cv::Scalar color = cv::Scalar(0, 0, 255); + isOK = false; + cv::drawContours(Paint, contours, i, color, 2); + textPainter.putText(Paint, "NG", cv::Point(rect.x + 10, rect.y - 20), color); + } + } + if (huaShangNg == true) + defects.push_back("划伤"); + return defects; +} +static bool BaoMoHou_ShangDaMian(std::shared_ptr data, baoMoHouDaMianDetParams* _detParams, yh_581_address address) +{ + try { + //data->oriImgs[0] = cv::imread("D://testImage//Camera1.bmp", -1); + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + /*if (data->oriImgs[0].rows == 150) { + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); + return false; + }*/ + + cv::Mat Paint; + //QMutex paintMutex; + clock_t start, finish; + start = clock(); + + cv::Mat src1 = data->oriImgs[0]; + cv::Mat srcHalf; + cv::resize(src1, srcHalf, cv::Size(0, 0), 0.5, 0.5); + if (srcHalf.channels() != 3) + cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); + else + srcHalf.copyTo(Paint); + TextRendererZH textPainter(Paint.cols, Paint.rows, 150); + //std::future > handleAiFuture = std::async(std::launch::async, BaoMoHou_DaMianAi, data, srcHalf, Paint, _detParams); + HalconCpp::HObject in_Image = MatToHObject(src1); + HDevEngineCpp::HDevProcedure proc("_4_Cal_Long_Coatingcover_Dist"); + HDevProcedureCall procedureCall(proc); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_xResolution", HTuple(0.0308812)); + procedureCall.SetInputCtrlParamTuple("in_yResolution", HTuple(0.029527)); + procedureCall.Execute(); + HTuple out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance"); + HTuple out_Line = procedureCall.GetOutputCtrlParamTuple("out_Line"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + int outFlag = out_Flag.D(); + // handleAiFuture.wait(); + //auto defects = handleAiFuture.get(); + if (outFlag == 1) { + for (int i = 0; i < out_Line.Length() / 4; i++) { + cv::line(Paint, cv::Point(out_Line[i * 4 + 1].D(), out_Line[i * 4].D()) / 2, + cv::Point(out_Line[i * 4 + 3].D(), out_Line[i * 4 + 2].D()) / 2, + cv::Scalar(0, 255, 0), 5); + } + /*out_Distance[0]: 上端盖到膜的距离< / c> + * out_Distance[1] : 中端盖到膜的距离< / c> + * out_Distance[2] : 下端盖到膜的距离< / c> + * out_Distance[3] : 电芯宽度 < / c> + * out_Distance[4] : 电芯高度< / c>*/ + textPainter.putText(Paint, "上端盖到膜的距离:" + std::to_string(out_Distance[0].D()) + "mm", cv::Point(50, 150), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "中端盖到膜的距离:" + std::to_string(out_Distance[1].D()) + "mm", cv::Point(50, 350), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "下端盖到膜的距离:" + std::to_string(out_Distance[2].D()) + "mm", cv::Point(50, 550), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "电芯宽度:" + std::to_string(out_Distance[3].D()) + "mm", cv::Point(50, 750), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "电芯高度:" + std::to_string(out_Distance[4].D()) + "mm", cv::Point(50, 950), cv::Scalar(0, 255, 0)); + } + else { + data->halconOK = false; + textPainter.putText(Paint, "OK", cv::Point(50, 300), cv::Scalar(0, 255, 0)); + } + + data->resultImgs.push_back(Paint); + //data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123"); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123"); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + return true; + } + CATCH_EXCEPTIONS + generalExceptionResume(data, address, "NG"); +} + +static bool BaoMoHou_XiaDaMian(std::shared_ptr data, baoMoHouDaMianDetParams* _detParams, yh_581_address address) +{ + try { + //data->oriImgs[0] = cv::imread("D://testImage//Camera2.bmp", -1); + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + /*if (data->oriImgs[0].rows == 150) { + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); + return false; + }*/ + + cv::Mat Paint; + //QMutex paintMutex; + clock_t start, finish; + start = clock(); + + cv::Mat src1 = data->oriImgs[0]; + cv::Mat srcHalf; + cv::resize(src1, srcHalf, cv::Size(0, 0), 0.5, 0.5); + if (srcHalf.channels() != 3) + cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); + else + srcHalf.copyTo(Paint); + //切图 + //cv::Mat segResult = _detParams->dingwei->Evaluate(srcHalf); + + //auto _result = BaoMoHou_DaMianAi(data, srcHalf, Paint, _detParams); + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, "OK", cv::Point(500, 50), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123"); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123"); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + return true; + } + CATCH_EXCEPTIONS + generalExceptionResume(data, address, "OK"); +} + +#pragma endregion + +class _581_BaoMo : public mission { +public: + using baoMoHouShangDaMianTrigger = _581_Single_triggerTemplate; + baoMoHouShangDaMianTrigger _station_1;//shangdamian + baoMoHouShangDaMianTrigger _station_3;//shangdamian + + using baoMoHouXiaDaMianTrigger = _581_Single_triggerTemplate; + baoMoHouXiaDaMianTrigger _station_2;//xiadamian + baoMoHouXiaDaMianTrigger _station_4;//xiadamian + + std::vector _baoMoHouDaMianDetParams = std::vector< baoMoHouDaMianDetParams>(4); + detParams _detParams; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + } + bool initCustom() { + +#pragma region 注册触发器回调 + + _station_1.init("Camera1", "包膜后大面外观检测-左上-相机5(上大面1)",18800,1,1, &_baoMoHouDaMianDetParams[0], _serviceManager, bridge, BaoMoHou_ShangDaMian); + _station_3.init("Camera3", "包膜后大面外观检测-右上-相机7(上大面2)", 19200, 1, 1, &_baoMoHouDaMianDetParams[1], _serviceManager, bridge, BaoMoHou_ShangDaMian); + + _station_2.init("Camera2", "包膜后大面外观检测-左下-相机6(下大面四角1)", 19000, 1, 1, &_baoMoHouDaMianDetParams[2], _serviceManager, bridge, BaoMoHou_XiaDaMian); + _station_4.init("Camera4", "包膜后大面外观检测-右下-相机8(下大面四角2)",19400, 1,1, &_baoMoHouDaMianDetParams[3], _serviceManager, bridge, BaoMoHou_XiaDaMian); +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/BaoMo/581-BaoMo-Cam5678/CMakeLists.txt b/src/mission/BaoMo/581-BaoMo-Cam5678/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam5678/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +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 REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network 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 + ) + + +# 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}) diff --git a/src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp b/src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp similarity index 100% rename from src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp rename to src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp diff --git a/src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h b/src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h similarity index 70% rename from src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h rename to src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h index 255e2c5..d5b8006 100644 --- a/src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h +++ b/src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h @@ -18,12 +18,10 @@ static bool ALGO_BaoMoHouCeMian(std::shared_ptr data, baoMoHouDaMianDe class _581_BaoMo : public mission { public: - using baoMoHouDaMianTrigger = _581_Union_triggerTemplate; - baoMoHouDaMianTrigger _station_1; - baoMoHouDaMianTrigger _station_2; + _581_Union_triggerTemplate _station_1; + _581_Union_triggerTemplate _station_2; - using generalTrigger = _581_Union_triggerTemplate; - generalTrigger _station_3; + _581_Union_triggerTemplate _station_3; std::vector < baoMoHouDaMianDetParams> _baoMoHouDaMianDetParams = std::vector < baoMoHouDaMianDetParams>(2); detParams _detParams; @@ -43,17 +41,10 @@ public: bool initCustom() { #pragma region 注册触发器回调 - //baoMoHouDaMianTrigger::resultHandleCallback resultCallback_BaoMoHouCeMian = - // ([=](yh_581_address address, _581_BaoMoResult, std::shared_ptr ) { - // _serviceManager->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - // }); + _station_1.init("Camera1","包膜后侧面贴胶错位检测-外-相机9",19600,2,1,&_baoMoHouDaMianDetParams[0], _serviceManager, bridge, ALGO_BaoMoHouCeMian); _station_2.init("Camera2", "包膜后侧面贴胶错位检测-内-相机10",19800,2,1, &_baoMoHouDaMianDetParams[1], _serviceManager, bridge, ALGO_BaoMoHouCeMian); - //generalTrigger::resultHandleCallback resultCallback_general = - // ([=](yh_581_address address, _581_Result, std::shared_ptr ) { - // _serviceManager->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - // }); _station_3.init("Camera3", "包膜后外观检测大面相机11(下大面)",20000,2,1, &_detParams, _serviceManager, bridge, generalAlgoTest); #pragma endregion return true; diff --git a/src/mission/BaoMo/581-BaoMo-Cam91011/CMakeLists.txt b/src/mission/BaoMo/581-BaoMo-Cam91011/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam91011/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +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 REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network 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 + ) + + +# 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}) diff --git a/src/mission/BaoMo/CMakeLists.txt b/src/mission/BaoMo/CMakeLists.txt new file mode 100644 index 0000000..f9a95fd --- /dev/null +++ b/src/mission/BaoMo/CMakeLists.txt @@ -0,0 +1,11 @@ +# CMakeList.txt: 遍历文件夹 添加子项目 + +set(OUR_LIBS "") +SUBDIRENAMES(OUR_LIBS ${CMAKE_CURRENT_SOURCE_DIR} "" OFF) +message("OUR_LIBS :" ${OUR_LIBS}) + + +# 遍历子库 +foreach(dll ${OUR_LIBS}) + add_subdirectory(${dll}) +endforeach(dll ${})