diff --git a/include/global.h b/include/global.h index 96e68be..ea246cd 100644 --- a/include/global.h +++ b/include/global.h @@ -11,8 +11,9 @@ #include #pragma execution_character_set("utf-8") -const std::string softwareVersion = "20251211-2.3.2"; +const std::string softwareVersion = "20251231-2.3.3"; const std::string euiJsonVersion = "1.0.6"; +#define savePathToDataBase true #define GigaByte 1073741824 #define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径 #define saveImgEnable 1 diff --git a/include/interface.h b/include/interface.h index 62fb320..7c1d5bf 100644 --- a/include/interface.h +++ b/include/interface.h @@ -69,7 +69,6 @@ public: bSignalHub _signalHub; virtual ~IBackend() = default; virtual void init(SQLiteDB* ,nlohmann::ordered_json& json) = 0; - virtual void cleanup() = 0; virtual nlohmann::ordered_json getBackendJson() = 0; public slots: virtual bool excuteCliCommand(const QString& command) = 0; diff --git a/include/opencvPaintAlgo.hpp b/include/opencvPaintAlgo.hpp index 1425be1..0b4a501 100644 --- a/include/opencvPaintAlgo.hpp +++ b/include/opencvPaintAlgo.hpp @@ -1,5 +1,6 @@ #pragma once #include +#include #pragma region 画叉 static void Cross(cv::Mat& image, const cv::Point& center, int length, int thickness, const cv::Scalar& color = cv::Scalar(255, 255, 255)) { @@ -84,21 +85,28 @@ public: TextRendererZH(int width, int height, int fontSize = 20, const std::wstring& fontName = L"微软雅黑") : width_(width), height_(height), fontSize_(fontSize), fontName_(fontName) { + QMutexLocker locker(&mutex_); screenDC_ = GetDC(nullptr); + if (!screenDC_) { + throw std::runtime_error("Failed to get screen DC"); + } createResources(); } ~TextRendererZH() { + QMutexLocker locker(&mutex_); releaseResources(); if (screenDC_) ReleaseDC(nullptr, screenDC_); } void putText(cv::Mat& image, const std::string& text, cv::Point org, cv::Scalar color = cv::Scalar(255, 0, 0)) override { + QMutexLocker locker(&mutex_); + if (image.channels() != 3) throw std::runtime_error("TextRendererZH only supports 3-channel BGR images."); if (image.cols != width_ || image.rows != height_) { - resize(image.cols, image.rows); + resize_unsafe(image.cols, image.rows); } cv::Mat img; @@ -118,6 +126,12 @@ public: } void resize(int width, int height) { + QMutexLocker locker(&mutex_); + resize_unsafe(width, height); + } + +private: + void resize_unsafe(int width, int height) { if (width == width_ && height == height_) return; releaseResources(); @@ -127,6 +141,140 @@ public: createResources(); } +public: + + struct pointPaintJob { + cv::Point center; + cv::Scalar color; + }; + void appendPaintJob(cv::Point center, cv::Scalar color) { + QMutexLocker locker(&mutex_); + pointPaintJobs.push_back(pointPaintJob{ center,color }); + } + + struct contourPaintJob { + std::vector contour; + cv::Scalar color; + int thikness; + }; + void appendPaintJob(std::vector contour, cv::Scalar color, int thikness) { + QMutexLocker locker(&mutex_); + contourPaintJobs.push_back(contourPaintJob{ contour,color,thikness }); + } + + struct linePaintJob { + cv::Point p1; + cv::Point p2; + cv::Scalar color; + int thikness; + }; + void appendPaintJob(cv::Point p1, cv::Point p2, cv::Scalar color, int thikness) { + QMutexLocker locker(&mutex_); + linePaintJobs.push_back(linePaintJob{ p1,p2,color,thikness }); + } + + struct circleAndCorssPaintJob { + cv::Point center; + double radius; + cv::Scalar color; + int thikness; + int type; + }; + //type0 圆 type1 十字 + void appendPaintJob(cv::Point center, double radius,cv::Scalar color, int thikness,int type) { + QMutexLocker locker(&mutex_); + circleAndCorssPaintJobs.push_back(circleAndCorssPaintJob{ center,radius,color,thikness,type }); + } + + struct rectPaintJob { + cv::Rect rect; + cv::Scalar color; + int thikness; + }; + void appendPaintJob(cv::Rect rect, cv::Scalar color,int thikness) { + QMutexLocker locker(&mutex_); + rectPaintJobs.push_back(rectPaintJob{ rect,color,thikness }); + } + + struct textPaintJob { + std::string text; + cv::Point p; + cv::Scalar color; + }; + void appendPaintJob(std::string text, cv::Point p, cv::Scalar color) { + QMutexLocker locker(&mutex_); + textPaintJobs.push_back(textPaintJob{ text,p,color }); + } + + void excusePaintJobs(cv::Mat& image,double resizeRate = 1.0) { + QMutexLocker locker(&mutex_); + + if (textPaintJobs.empty() && pointPaintJobs.empty() && circleAndCorssPaintJobs.empty() && rectPaintJobs.empty() && contourPaintJobs.empty() && linePaintJobs.empty()) return; + + if (image.channels() != 3) + throw std::runtime_error("TextRendererZH only supports 3-channel BGR images."); + + if (image.cols != width_ || image.rows != height_) { + resize_unsafe(image.cols, image.rows); + } + + // 绘制点 + for (const auto& job : pointPaintJobs) { + cv::circle(image, job.center, 1, job.color, -1); + } + + // 绘制圆或十字 + for (const auto& job : circleAndCorssPaintJobs) { + if(job.type == 0) + cv::circle(image, job.center, job.radius, job.color, job.thikness); + else + cv::drawMarker(image, job.center, job.color, cv::MARKER_CROSS, job.radius, job.thikness); + } + + // 绘制点集 + for (const auto& job : contourPaintJobs) { + cv::drawContours(image, { job.contour }, 0, job.color, job.thikness); + } + + // 绘制线段 + for (const auto& job : linePaintJobs) { + cv::line(image, job.p1, job.p2, job.color, job.thikness); + } + + // 绘制矩形 + for (const auto& job : rectPaintJobs) { + cv::rectangle(image, job.rect, job.color, job.thikness); + } + + // 绘制文本(需要GDI处理) + if (!textPaintJobs.empty()) { + // 只进行一次颜色转换和数据拷贝 + cv::Mat img; + cv::cvtColor(image, img, cv::COLOR_BGR2BGRA); + memcpy(pBits_, img.data, img.total() * img.elemSize()); + + SetBkMode(memDC_, TRANSPARENT); + + // 批量绘制所有文本 + for (const auto& job : textPaintJobs) { + SetTextColor(memDC_, RGB(job.color[2], job.color[1], job.color[0])); + std::wstring wtext = utf8ToWstring(job.text); + TextOutW(memDC_, job.p.x, job.p.y, wtext.c_str(), (int)wtext.length()); + } + + // 只进行一次数据回读和颜色转换 + GetDIBits(memDC_, hBitmap_, 0, height_, img.data, &bmi_, DIB_RGB_COLORS); + cv::cvtColor(img, image, cv::COLOR_BGRA2BGR); + } + + // 清空已执行的任务 + contourPaintJobs.clear(); + linePaintJobs.clear(); + pointPaintJobs.clear(); + circleAndCorssPaintJobs.clear(); + rectPaintJobs.clear(); + textPaintJobs.clear(); + } private: void createResources() { memDC_ = CreateCompatibleDC(screenDC_); @@ -187,6 +335,17 @@ private: BITMAPINFO bmi_{}; HFONT hFont_ = nullptr; + + // 任务队列 + std::vector textPaintJobs; + std::vector pointPaintJobs; + std::vector circleAndCorssPaintJobs; + std::vector linePaintJobs; + std::vector contourPaintJobs; + std::vector rectPaintJobs; + + // 线程保护 + mutable QMutex mutex_; }; #pragma endregion diff --git a/include/sxGlobal.h b/include/sxGlobal.h index 9bc2175..2f01ec5 100644 --- a/include/sxGlobal.h +++ b/include/sxGlobal.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include #include #include @@ -42,7 +41,6 @@ public: static bool generalAlgoTest(std::shared_ptr data, detParams* _detParams, sx_581_address address) { try { qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - std::vector < std::string> defects = {"测试"}; ///////////////////取图//处理////////////////// if (data->getOriImgSize() < 1) { @@ -71,7 +69,6 @@ static bool generalAlgoTest(std::shared_ptr data, detParams* _detParam 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); data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - data->service->_missionResultHandle->toBarChart(data->SNcode, defects);//发送图标操作 data->insertResultImg(Paint); return true; } @@ -115,7 +112,7 @@ public: address = addressIN; saveObjectName = saveObjectNameIN; oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN; - generalDet = new detCallbackChain(_serviceManager, _detParams, bridge); + generalDet = new detCallbackChain(_serviceManager, _detParams, bridge, &_serviceManagerIn->_chainWatcher); generalDet->registerProcessAlgoCallback(_processAlgoCallback); //单次触发器条件 for (int i = 0; i < addressIN.size(); i++) { @@ -135,7 +132,7 @@ public: } //获取图片并进行检测 void evaluate(int batteryOffset, QByteArray& byteArray) { - _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(address[0].triggerAddr) + "_0");//触发信号清零 + _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(address[batteryOffset].triggerAddr) + "_0");//触发信号清零 std::string sn; for (auto& snAddr : address[batteryOffset].snAddr) { @@ -151,7 +148,7 @@ public: QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包 data->saveObjectName = saveObjectName; camera->captureImage(data);//拍照 - generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号 + generalDet->asyncProcess(data, address[batteryOffset], ("D" + address[batteryOffset].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); } private: diff --git a/include/yhGlobal.h b/include/yhGlobal.h index 0729f81..9b19b11 100644 --- a/include/yhGlobal.h +++ b/include/yhGlobal.h @@ -153,7 +153,7 @@ public: oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN; saveObjectName = saveObjectNameIN; - generalDet = new detCallbackChain(_serviceManager, _detParams, bridge); + generalDet = new detCallbackChain(_serviceManager, _detParams, bridge, &_serviceManagerIn->_chainWatcher); generalDet->registerProcessAlgoCallback(_processAlgoCallback); address = generateYh581AddressMap(startAddr, triggerCount); //联合触发器条件 @@ -171,7 +171,7 @@ public: if (val.second == 1) evaluate(cnt, byteArray); else - captrueAndDiscard(); + captrueAndDiscard(cnt); cnt++; } }, ""); @@ -197,16 +197,17 @@ public: camera->captureImage(data);//拍照 - generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法 + generalDet->asyncProcess(data, address[batteryOffset]);//处理算法 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); } //获取图片然后废弃 - void captrueAndDiscard() { + void captrueAndDiscard(int index) { + _serviceManager->_triggerManager->writeShort("D" + address[index].resultAddr + "_4");//发个4防止报警 auto camera = _serviceManager->_cameraManager->getCamera(cameraName); std::shared_ptr data = _serviceManager->_detDataManager->createDetData();//创建数据包 camera->captureImage(data);//拍照 - qDebug() << "uuid" <uuid <<"已取图并丢弃"; - _serviceManager->_detDataManager->deleteDetData(data->uuid); + qDebug() << "uuid" << data->uuid << "将取图并丢弃"; + _serviceManager->_detDataManager->deleteDetDataLater(data->uuid); } private: QString saveObjectName = ""; @@ -250,7 +251,7 @@ public: oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN; saveObjectName = saveObjectNameIN; - generalDet = new detCallbackChain(_serviceManager, _detParams, bridge); + generalDet = new detCallbackChain(_serviceManager, _detParams, bridge, &_serviceManagerIn->_chainWatcher); generalDet->registerProcessAlgoCallback(_processAlgoCallback); address = generateYh581AddressMap(startAddr, triggerCount); //单次触发器条件 @@ -285,7 +286,7 @@ public: camera->captureImage(data);//拍照 - generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法 + generalDet->asyncProcess(data, address[batteryOffset]);//处理算法 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); } private: diff --git a/rpcModule/rpc_finsTcp/CMakeLists.txt b/rpcModule/rpc_finsTcp_boost/CMakeLists.txt similarity index 100% rename from rpcModule/rpc_finsTcp/CMakeLists.txt rename to rpcModule/rpc_finsTcp_boost/CMakeLists.txt diff --git a/rpcModule/rpc_finsTcp/json_rpc_server_1_1_0.exe b/rpcModule/rpc_finsTcp_boost/json_rpc_server_1_1_0.exe similarity index 100% rename from rpcModule/rpc_finsTcp/json_rpc_server_1_1_0.exe rename to rpcModule/rpc_finsTcp_boost/json_rpc_server_1_1_0.exe diff --git a/rpcModule/rpc_finsTcp_boost/readme.txt b/rpcModule/rpc_finsTcp_boost/readme.txt new file mode 100644 index 0000000..ee9b523 --- /dev/null +++ b/rpcModule/rpc_finsTcp_boost/readme.txt @@ -0,0 +1,8 @@ +1.初始化语句修改 +init_192.168.1.101_9600_12 + [ IP ][端口][线程数量] +2.目前发送采用乱序多线程并发,如果需要有序发送需要按照以下放松 + 2.1.强制指定某线程按顺序发送 + SAMPLE: write_D100_1_1 最后一个1为线程号,强制使用1号线程发送 + 2.2.强制指定某线程按顺序发送 + SAMPLE: write_D100_1#write_D100_2#write_D100_3 强制将这几句按顺序在下一线程内按顺序发 diff --git a/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.cpp b/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.cpp new file mode 100644 index 0000000..a290762 --- /dev/null +++ b/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.cpp @@ -0,0 +1,473 @@ +#include "rpc_finsTcp.h" +#include "qprocess.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static QProcess* process = nullptr; +static HANDLE jobHandle = nullptr; +rpc_finsTcp* create(){ + qDebug() << "rpc_finsTcp create success!"; + return new rpc_finsTcp; +} + +void destory(rpc_finsTcp* ptr){ + + if (ptr) + { + delete ptr; + ptr = nullptr; + } + qDebug() << " rpc_finsTcp destory success!"; +} +bool ifRun = true; +rpc_finsTcp::rpc_finsTcp(){ + ifRun = true; +} +bool m_IsFinsTcp = false; +rpc_finsTcp::~rpc_finsTcp() { + + for (auto& client : write_JsonRpcClients) { + if (client.first) { + // 断开所有信号槽连接 + client.first->disconnect(); + + if (client.first->isRunning()) { + client.first->quit(); + if (!client.first->wait(1000)) { + qWarning() << "subThread quit timeout!"; + } + } + // 如果 subThread 没有 parent,则需要手动 delete + //if (!subThread->parent()) { + // delete subThread; + //} + //subThread = nullptr; + } + if (client.second) { + delete client.second; + client.second = nullptr; + } + } + if (hearBeatThread) { + // 断开所有信号槽连接 + hearBeatThread->disconnect(); + + if (hearBeatThread->isRunning()) { + hearBeatThread->quit(); + if (!hearBeatThread->wait(1000)) { + qWarning() << "subThread quit timeout!"; + } + } + // 如果 subThread 没有 parent,则需要手动 delete + //if (!subThread->parent()) { + // delete subThread; + //} + //subThread = nullptr; + } + if (hearBeatClinet) { + delete hearBeatClinet; + hearBeatClinet = nullptr; + } + qDebug() << " ~rpc_finsTcp success!"; +} +QQueue readDataQueue; +// 从类中读数据到实例对象 +QByteArray variantListToByteArray(const QVariant& var) { + QByteArray byteArray; + + if (var.canConvert()) { + QVariantList list = var.toList(); + byteArray.reserve(list.size()); + + for (const QVariant& item : list) { + // 每个元素转为 uchar 存入 QByteArray + byteArray.append(static_cast(item.toInt())); + } + } + + return byteArray; +} +bool rpc_finsTcp::readData(std::vector& vec_mat, QByteArray& data){ + JsonRpcClient* ptr = read_JsonRpcClient[data]; + if(ptr == nullptr) { + ptr = new JsonRpcClient("127.0.0.1", 9000); + read_JsonRpcClient[data] = ptr; + } + QByteArray resp = ptr->finsReadCall("excuteCli", QString(data), "finstcp"); + data = resp; // 已是解码后的原始字节 + return true; +} +bool ifRetryCMD = false; +// 实例对象把数据写入到类 + +void startProcess(const QString& exePath) { + if (process) return; // 避免重复启动 + + process = new QProcess(); + process->setProgram(exePath); + process->start(); + + if (!process->waitForStarted(1000)) { + qDebug() << "Process failed to start."; + delete process; + process = nullptr; + return; + } + + DWORD pid = process->processId(); + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); + + jobHandle = CreateJobObject(nullptr, nullptr); + if (jobHandle == nullptr) { + qDebug() << "Failed to create job object"; + return; + } + + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {}; + jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + SetInformationJobObject(jobHandle, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)); + + if (!AssignProcessToJobObject(jobHandle, hProcess)) { + qDebug() << "Failed to assign process to job object"; + } + + CloseHandle(hProcess); +} + +void stopProcess() { + if (process) { + if (process->state() == QProcess::Running) { + process->kill(); + process->waitForFinished(500); + } + delete process; + process = nullptr; + } + + if (jobHandle) { + CloseHandle(jobHandle); + jobHandle = nullptr; + } +} +bool rpc_finsTcp::writeData(std::vector& vec_mat, QByteArray& data){ + QList m_list = data.split('_'); + if (m_list.size() < 4) + { + qCritical() << data + " m_list.size() != 4;command err"; + return false; + } + QString commond = m_list.at(0); + if (commond == "init") { + m_IP = m_list.at(1); + m_port = m_list.at(2).toInt(); + threadCount = m_list.at(3).toInt(); + } + else if(data.contains("read")) { + readDataQueue.append(data); + } + else { + if (data.contains("null")) + return true; + if (data.contains("Heart") == true) {//专门的发送心跳线程去发送此数据 + emit writeCallSignal("excuteCli", QJsonArray{ QString(data) }, "finstcp", -1); + return true; + } + //检查是不是复数命令 + QList commands = data.split('#'); + + int threadIndex = -1; + { + QMutexLocker locker(&threadUseIndexMutex); + threadIndex = threadUseIndex; + if (++threadUseIndex >= write_JsonRpcClients.size()) threadUseIndex = 0; + } + for (auto& command : commands) {//分割命令 + QList commandSplit = command.split('_'); + if (commandSplit.size() >= 5) {//如果是指定发送线程的 + QString sendData = command.left(command.lastIndexOf("_")); + emit writeCallSignal("excuteCli", QJsonArray{ QString(sendData) }, "finstcp", m_list.at(4).toInt()); + } + else { + emit writeCallSignal("excuteCli", QJsonArray{ QString(command) }, "finstcp", threadIndex); + } + } + + // + } + return true; +} +void rpc_finsTcp::initClientAndThread(std::pair& pairData,const int& i) { + pairData.first = new QThread(); + pairData.second = new JsonRpcClientWorker(i); + pairData.second->moveToThread(pairData.first); + + QObject::connect(this, &rpc_finsTcp::initRpcClient, + pairData.second, &JsonRpcClientWorker::initClient, Qt::QueuedConnection); + + QObject::connect(this, &rpc_finsTcp::writeCallSignal, + pairData.second, &JsonRpcClientWorker::writeCallSlot, Qt::QueuedConnection); + pairData.first->start(); + + while (pairData.second->connection == None) + QThread::msleep(1); + + if (pairData.second->connection == Disconnected) { + qDebug() << "JsonRpcClientSubThread connection failed! threadId" << i; + } + else if (pairData.second->connection == Connected) { + qDebug() << "JsonRpcClientSubThread connected successfully! threadId" << i; + } +} +void rpc_finsTcp::initHearBeatThread() { + hearBeatThread = new QThread(); + hearBeatClinet = new JsonRpcClientWorker(-1); + hearBeatClinet->moveToThread(hearBeatThread); + + QObject::connect(this, &rpc_finsTcp::initRpcClient, + hearBeatClinet, &JsonRpcClientWorker::initClient, Qt::QueuedConnection); + + QObject::connect(this, &rpc_finsTcp::writeCallSignal, + hearBeatClinet, &JsonRpcClientWorker::writeCallSlot, Qt::QueuedConnection); + hearBeatThread->start(); + while (hearBeatClinet->connection == None) + QThread::msleep(1); + + if (hearBeatClinet->connection == Disconnected) { + qDebug() << "JsonRpcClientSubThread connection failed! heartBeatThread"; + } + else if (hearBeatClinet->connection == Connected) { + qDebug() << "JsonRpcClientSubThread connected successfully! threadId heartBeatThread"; + } +} + +bool rpc_finsTcp::initParas(QByteArray& data){ + startProcess("./json_rpc_server_1_1_0.exe"); + QThread::msleep(500); + write_JsonRpcClients = std::vector>(threadCount); + for (int i = 0; i < write_JsonRpcClients.size(); i++) { + initClientAndThread(write_JsonRpcClients[i],i); + } + //心跳线程 + initHearBeatThread(); + //qDebug() << "返回结果:" << result; + emit initRpcClient(); + emit writeCallSignal("init", QJsonArray{ m_IP,m_port }, "finstcp", -1); + for (int i = 0; i < write_JsonRpcClients.size(); i++) + emit writeCallSignal("init", QJsonArray{ m_IP,m_port }, "finstcp", i); + //QList> batchList; + //batchList << qMakePair(QString("read_short"), params) + // << qMakePair(QString("read_bit"), QJsonObject{ {"bit", "M0"} }); + + //QJsonArray resultArray = _JsonRpcClient->batchCall(batchList); + //qDebug() << "批量结果:" << resultArray; + return true; + +} + +bool rpc_finsTcp::run(){ + // 没有用到 + //qDebug() << "[info] " << __FUNCTION__ << " line:" << __LINE__ << " success!"; + return true; +} + + +JsonRpcClient::JsonRpcClient(const QString& host, quint16 port) + :host_(host), port_(port), idCounter_(1) { + + socket_.connectToHost(host_, port_); + if (!socket_.waitForConnected(3000)) { + qWarning() << "[JsonRpcClient] Initial connection failed:" << socket_.errorString(); + _connectionStatus = Disconnected; + } + else { + qDebug() << "[JsonRpcClient] Connected to" << host_ << ":" << port_; + _connectionStatus = Connected; + } +} + +bool JsonRpcClient::reconnect() { + if (socket_.state() == QAbstractSocket::ConnectedState) { + return true; + } + + socket_.abort(); // 清理旧连接 + socket_.connectToHost(host_, port_); + if (socket_.waitForConnected(3000)) { + qDebug() << "[JsonRpcClient] Reconnected successfully."; + return true; + } + else { + qWarning() << "[JsonRpcClient] Reconnection failed:" << socket_.errorString(); + return false; + } +} +QVariant JsonRpcClient::call(const QString& method, const QJsonArray& params, const QString& module){ + QMutexLocker locker(&mutex_); + if (socket_.state() != QAbstractSocket::ConnectedState) { + if (!reconnect()) return QVariant(); + } + int myId = idCounter_++; + QJsonObject req{ + {"jsonrpc", "2.0"}, + {"method", method}, + {"params", params}, + {"id", myId} + }; + if (!module.isEmpty()) req.insert("module", module); + + QJsonObject resp = sendRequestBuildAndAwait(req); + if (resp.contains("error")) { + qWarning() << "[JsonRpcClient] Error:" << QJsonDocument(resp["error"].toObject()).toJson(QJsonDocument::Compact); + return QVariant(); + } + if (!resp.contains("result")) return QVariant(); + QJsonValue r = resp.value("result"); + if (r.isString()) return r.toString(); + if (r.isDouble()) return r.toDouble(); + if (r.isBool()) return r.toBool(); + if (r.isArray()) return r.toArray().toVariantList(); + if (r.isObject()) return r.toObject().toVariantMap(); + return QVariant(); +} + +QByteArray JsonRpcClient::finsReadCall(const QString& method, const QString& params, const QString& module) { + auto commands = params.split("_"); + QMutexLocker locker(&mutex_); + if (socket_.state() != QAbstractSocket::ConnectedState) { + if (!reconnect()) return QByteArray(); + } + int myId = idCounter_++; + QJsonArray p; p.append(params); + QJsonObject req{{"jsonrpc","2.0"},{"method",method},{"params",p},{"id",myId}}; + if (!module.isEmpty()) req.insert("module", module); + + QJsonDocument doc(req); + QByteArray payload = doc.toJson(QJsonDocument::Compact); + if (socket_.write(payload) == -1 || !socket_.waitForBytesWritten(1000)) { + qWarning() << "[JsonRpcClient] Write failed."; + return QByteArray(); + } + + QJsonObject respObj; + if (!waitAndReadResponse(myId, respObj)) { + qWarning() << "[JsonRpcClient] Read timeout or parse error."; + return QByteArray(); + } + QString b64 = respObj.value("result").toString(); + QByteArray decoded = QByteArray::fromBase64(b64.toUtf8()); + if (b64.contains("error") || decoded.size()% commands[3].toInt() != 0) { + qWarning() << "[ERROR]" << b64; + QThread::msleep(500); + return b64.toUtf8(); + } + return decoded; +} + +QList JsonRpcClient::extractJsonFrames(QByteArray& buffer) { + QList frames; + int start = -1; + int braceDepth = 0; + bool inString = false; + char prev = 0; + for (int i = 0; i < buffer.size(); ++i) { + char c = buffer[i]; + if (c == '"' && prev != '\\') inString = !inString; + if (!inString) { + if (c == '{') { + if (braceDepth == 0) start = i; + braceDepth++; + } else if (c == '}') { + braceDepth--; + if (braceDepth == 0 && start != -1) { + int len = i - start + 1; + frames.append(buffer.mid(start, len)); + start = -1; + } + } + } + prev = c; + } + if (braceDepth == 0) { + if (!frames.isEmpty()) { + int lastEnd = buffer.lastIndexOf('}'); + if (lastEnd != -1) buffer = buffer.mid(lastEnd + 1); + } + } else { + if (start > 0) buffer = buffer.mid(start); + } + return frames; +} + +bool JsonRpcClient::waitAndReadResponse(int expectId, QJsonObject& outResp, int timeoutMs) { + QElapsedTimer timer; timer.start(); + while (timer.elapsed() < timeoutMs) { + if (socket_.bytesAvailable() == 0) { + int remain = timeoutMs - (int)timer.elapsed(); + if (!socket_.waitForReadyRead(qMin(remain, 1000))) { + continue; + } + } + QByteArray chunk = socket_.readAll(); + if (!chunk.isEmpty()) recvBuffer_.append(chunk); + auto frames = extractJsonFrames(recvBuffer_); + for (const QByteArray& f : frames) { + QJsonParseError perr; + QJsonDocument jd = QJsonDocument::fromJson(f, &perr); + if (perr.error != QJsonParseError::NoError) { + qWarning() << "[JsonRpcClient] parse frame error:" << perr.errorString(); + continue; + } + if (jd.isArray()) { + for (const QJsonValue& v : jd.array()) { + if (!v.isObject()) continue; + QJsonObject obj = v.toObject(); + if (obj.value("id").toInt() == expectId) { outResp = obj; return true; } + } + } else if (jd.isObject()) { + QJsonObject obj = jd.object(); + if (obj.value("id").toInt() == expectId) { outResp = obj; return true; } + } + } + } + return false; +} + +QJsonObject JsonRpcClient::sendRequestBuildAndAwait(const QJsonObject& req, int timeoutMs) { + QByteArray payload = QJsonDocument(req).toJson(QJsonDocument::Compact); + int id = req.value("id").toInt(); + if (socket_.write(payload) == -1 || !socket_.waitForBytesWritten(1000)) { + return QJsonObject{{"error", QJsonObject{{"code", -1},{"message", "write failed"}}}}; + } + QJsonObject resp; + if (!waitAndReadResponse(id, resp, timeoutMs)) { + return QJsonObject{{"error", QJsonObject{{"code", -2},{"message", "timeout"}}}}; + } + return resp; +} + +void JsonRpcClient::writeCall(const QString& method, const QJsonArray& params, const QString& module) { + call(method, params, module); +} \ No newline at end of file diff --git a/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.h b/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.h new file mode 100644 index 0000000..5afa870 --- /dev/null +++ b/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.h @@ -0,0 +1,110 @@ +#ifndef rpc_finsTcp_H +#define rpc_finsTcp_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +enum connectionStatus { + None, + Disconnected, + Connected +}; +class JsonRpcClient : public QObject { + Q_OBJECT +public: + connectionStatus _connectionStatus = None; + JsonRpcClient(const QString& host = "127.0.0.1", quint16 port = 9000); + void writeCall(const QString& method, const QJsonArray& params = {}, const QString& module = QString()); + QVariant call(const QString& method, const QJsonArray& params = {}, const QString& module = QString()); + QByteArray finsReadCall(const QString& method, const QString& params = "", const QString& module = QString()); + bool reconnect(); // 主动重连,或 call() 失败时调用 +private: + // 解析累计缓冲中的完整 JSON 帧(可能存在粘包/拆包) + QList extractJsonFrames(QByteArray& buffer); + bool waitAndReadResponse(int expectId, QJsonObject& outResp, int timeoutMs = 8000); + QJsonObject sendRequestBuildAndAwait(const QJsonObject& req, int timeoutMs = 8000); + QMutex mutex_; // 确保线程安全 + QTcpSocket socket_; + QString host_; + quint16 port_; + int idCounter_; + QByteArray recvBuffer_; // 累计接收缓冲 +}; +class JsonRpcClientWorker : public QObject { + Q_OBJECT +public: + connectionStatus connection; + QQueue readDataQueue; + JsonRpcClientWorker(const int& threadIdIn):threadId(threadIdIn){ + + } +public slots: + void initClient() { + _JsonRpcClient = new JsonRpcClient(); + connection = _JsonRpcClient->_connectionStatus; + } + void writeCallSlot(const QString& method, const QJsonArray& params, const QString& module = QString(),const int& threadIndex = -1) { + if (_JsonRpcClient && threadId == threadIndex) { + if (threadId != -1)qDebug() << params << threadId; + _JsonRpcClient->call(method, params, module); + } + } +private: + int threadId = 0; + JsonRpcClient* _JsonRpcClient = nullptr; +}; +class rpc_finsTcp :public rpcModuleBase +{ + Q_OBJECT +public: + rpc_finsTcp(); + virtual ~rpc_finsTcp(); + bool readData(std::vector&, QByteArray&);// readData将PLC读取或者发送的返回值发回给主线程,通过全局变量的方式逐条发送 + bool writeData(std::vector&, QByteArray&);// writeData调用PLC的收发,将需要的数据发给寄存器,返回OK/NG + bool initParas(QByteArray&); + bool run(); +signals: + void initRpcClient(); + void writeCallSignal(const QString& method, const QJsonArray& params, const QString& module,const int& threadId); +private: + void initHearBeatThread(); + void initClientAndThread(std::pair&, const int& i); + QMutex mutex; + QMap read_JsonRpcClient; // 存储多个 JsonRpcClient 实例 + std::vector> write_JsonRpcClients; + + JsonRpcClientWorker* hearBeatClinet; + QThread* hearBeatThread; + + QString m_IP; + int m_port,threadCount = 1; + QQueue readDataQueue; + QMutex threadUseIndexMutex; + int threadUseIndex = 0; +}; +#pragma once + + +extern "C" +{ +Q_DECL_EXPORT rpc_finsTcp * create(); +Q_DECL_EXPORT void destory(rpc_finsTcp * ptr); +} + +#endif // rpc_finsTcp_H diff --git a/rpcModule/rpc_finsTcp_static/CMakeLists.txt b/rpcModule/rpc_finsTcp_static/CMakeLists.txt new file mode 100644 index 0000000..33c8bb1 --- /dev/null +++ b/rpcModule/rpc_finsTcp_static/CMakeLists.txt @@ -0,0 +1,71 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "basler" "opencv") +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( + + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) + + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC ON) +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 Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C + 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 + Qt5::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME}) diff --git a/rpcModule/rpc_finsTcp_static/json_rpc_server_1_1_0.exe b/rpcModule/rpc_finsTcp_static/json_rpc_server_1_1_0.exe new file mode 100644 index 0000000..ad00ec9 Binary files /dev/null and b/rpcModule/rpc_finsTcp_static/json_rpc_server_1_1_0.exe differ diff --git a/rpcModule/rpc_finsTcp/rpc_finsTcp.cpp b/rpcModule/rpc_finsTcp_static/rpc_finsTcp.cpp similarity index 99% rename from rpcModule/rpc_finsTcp/rpc_finsTcp.cpp rename to rpcModule/rpc_finsTcp_static/rpc_finsTcp.cpp index c7b8467..ea7e1fa 100644 --- a/rpcModule/rpc_finsTcp/rpc_finsTcp.cpp +++ b/rpcModule/rpc_finsTcp_static/rpc_finsTcp.cpp @@ -51,6 +51,7 @@ rpc_finsTcp::~rpc_finsTcp() { // 断开所有信号槽连接 subThread->disconnect(); + // 如果线程在运行,优雅退出 if (subThread->isRunning()) { subThread->quit(); // 最多等待3秒,防止死锁 diff --git a/rpcModule/rpc_finsTcp/rpc_finsTcp.h b/rpcModule/rpc_finsTcp_static/rpc_finsTcp.h similarity index 98% rename from rpcModule/rpc_finsTcp/rpc_finsTcp.h rename to rpcModule/rpc_finsTcp_static/rpc_finsTcp.h index 6b512b5..3e5b48e 100644 --- a/rpcModule/rpc_finsTcp/rpc_finsTcp.h +++ b/rpcModule/rpc_finsTcp_static/rpc_finsTcp.h @@ -62,6 +62,7 @@ public slots: void writeCallSlot(const QString& method, const QJsonArray& params, const QString& module = QString()) { if (_JsonRpcClient) { //qDebug() << params; + //qDebug() << method; _JsonRpcClient->call(method, params, module); } } diff --git a/src/Core/backendInterface.cpp b/src/Core/backendInterface.cpp index 34fbd9f..55341a6 100644 --- a/src/Core/backendInterface.cpp +++ b/src/Core/backendInterface.cpp @@ -4,6 +4,9 @@ Backend::~Backend() { if (_paramSyncManager != nullptr) { delete _paramSyncManager; } + if (_serviceManager._imgSaveThreadManager != nullptr) { + delete _serviceManager._imgSaveThreadManager; + } safeShutdownDelete(_serviceManager._triggerManager); safeShutdownDelete(_serviceManager._cameraManager); } diff --git a/src/core/backendInterface.h b/src/core/backendInterface.h index 59441a7..24e592c 100644 --- a/src/core/backendInterface.h +++ b/src/core/backendInterface.h @@ -15,7 +15,7 @@ public: CsvWriter* _csvWriter = nullptr; missionResultHandle* _missionResultHandle = nullptr; ServiceManager _serviceManager; - paramSyncManager* _paramSyncManager = nullptr; + paramSyncManager* _paramSyncManager = nullptr;//供客户在UI修改/查看 CLIManager* _cliManager; // 命令行接口管理器 rpc::JsonRpcServer _rpcServer; @@ -26,9 +26,6 @@ public: void restartInit(); void run(); - void cleanup() override { - - } // 对普通指针的安全删除 template void safeDelete(T*& ptr) { diff --git a/src/core/service/cameraManager.cpp b/src/core/service/cameraManager.cpp index 3c6637f..e310810 100644 --- a/src/core/service/cameraManager.cpp +++ b/src/core/service/cameraManager.cpp @@ -83,7 +83,7 @@ void camera::run(){ getCameraImg(mats, data->imgAmountMin); data->insertOriImg(mats); if (data->getOriImgSize() >= data->imgAmountMin) { - qDebug() << data->uuid << " Min:" << data->imgAmountMin << " Get:" << data->getOriImgSize(); + qDebug() << QString::fromStdString(data->SNcode) << data->uuid << " Min:" << data->imgAmountMin << " Get:" << data->getOriImgSize(); break; } } diff --git a/src/core/service/cameraManager.h b/src/core/service/cameraManager.h index 4bbef15..a55368f 100644 --- a/src/core/service/cameraManager.h +++ b/src/core/service/cameraManager.h @@ -49,7 +49,6 @@ public: runFlag = false; while (this->isRunning() == true); } - void getImgQueueSize(); void captureImage(std::shared_ptr dataIn){ QMutexLocker locker(&mutex); requestQueue.enqueue(dataIn); @@ -123,8 +122,6 @@ private: QQueueimgQueue; QQueue>requestQueue; bool runFlag = true; - int imgLost = 0;//未取用从而丢失的图片数量 - int showLost = 0;//因为窗口刷新速率低而未显示的数量 }; class cameraManager : public serviceModule{ Q_OBJECT diff --git a/src/core/service/detCallbackChain.hpp b/src/core/service/detCallbackChain.hpp index d522009..585bff6 100644 --- a/src/core/service/detCallbackChain.hpp +++ b/src/core/service/detCallbackChain.hpp @@ -8,30 +8,43 @@ #include #include #include - -using namespace std::placeholders; -template +#include +#include +template class detCallbackChain { public: - enum class State { Idle, algoEvaluate, resultHandle, Finished }; - using processAlgoCallback = std::function, handleAiModelsTemplate*, addressTemplate)>; - detCallbackChain(ServiceManager* _ServiceManagerIn, handleAiModelsTemplate* _handleAiModelsTemplateIn, bSignalHub* bridgeIn) - : _imgSaveThreadManager(_ServiceManagerIn->_imgSaveThreadManager), - _handleAiModels(_handleAiModelsTemplateIn), - _triggerManager(_ServiceManagerIn->_triggerManager), - bridge(bridgeIn){ - _serviceManager = _ServiceManagerIn; - int threadCount = 2 * QThread::idealThreadCount(); - QThreadPool::globalInstance()->setMaxThreadCount(threadCount); + using processAlgoCallback = std::function, customTemplate*, addressTemplate)>; + detCallbackChain(ServiceManager* _ServiceManagerIn, customTemplate* _customTemplateIn, bSignalHub* bridgeIn, detCallbackChainWatcher* _chainWatcherIn = nullptr) + : _imgSaveThreadManager(_ServiceManagerIn->_imgSaveThreadManager), + _handleAiModels(_customTemplateIn), + _triggerManager(_ServiceManagerIn->_triggerManager), + bridge(bridgeIn), _serviceManager(_ServiceManagerIn) + { + int threadCount = 4 * QThread::idealThreadCount(); + QThreadPool::globalInstance()->setMaxThreadCount(threadCount); + _chainWatcher = _chainWatcherIn; } //异步启动检测 - void ansyncProcess(std::shared_ptr data, addressTemplate address, QByteArray completeSignal = "") { + void asyncProcess(std::shared_ptr data, addressTemplate address, QByteArray completeSignal = "") { + if (QThreadPool::globalInstance()->activeThreadCount() == QThreadPool::globalInstance()->maxThreadCount()) { + QThreadPool::globalInstance()->setMaxThreadCount(QThreadPool::globalInstance()->maxThreadCount() + QThread::idealThreadCount()); + qDebug() << "检测线程增加到:" << QThreadPool::globalInstance()->maxThreadCount(); + } QFuture future = QtConcurrent::run([this, data, address, completeSignal]() { process(data, address, completeSignal); }); + if (_chainWatcher != nullptr) { + // 构建任务名称:包含 UUID 和 SN 码便于追踪 + QString taskName = QString("DetTask_UUID[%1]_SN[%2]") + .arg(data->uuid) + .arg(QString::fromStdString(data->SNcode)); + + // 将任务添加到监控器 + int watcherId = _chainWatcher->addFeature(future, taskName); + } } - //启动检测 + //阻塞启动检测 void process(std::shared_ptr data, addressTemplate address, QByteArray completeSignal = "") { data->service = _serviceManager; while (data->getOriImgSize() < data->imgAmountMin) { @@ -40,6 +53,7 @@ public: if(completeSignal != "") _triggerManager->writeShort(completeSignal); //等待图片满足要求后,储存原图,异步执行算法函数 + qDebug() << "Algo start with UUID:" << data->uuid; auto resultData = algoEvaluate(data, _handleAiModels, address); // 确保线程安全退出 qDebug() << "Processing finished for data with UUID:" << data->uuid; @@ -59,14 +73,13 @@ public: } } resultHandle(data); - QThread::currentThread()->quit(); } - bool algoEvaluate(std::shared_ptr data, handleAiModelsTemplate* model, addressTemplate address = addressTemplate()) { + bool algoEvaluate(std::shared_ptr data, customTemplate* customTemplate, addressTemplate address = addressTemplate()) { std::chrono::steady_clock::time_point algoStartTime = std::chrono::steady_clock::now(); bool result = true; try { - result = _processAlgoCallback(data, model, address); + result = _processAlgoCallback(data, customTemplate, address); } catch (HDevEngineCpp::HDevEngineException& ex) { @@ -91,7 +104,7 @@ public: void resultHandle(std::shared_ptr data){ std::shared_ptr dataPtr = data; detDataManager* dManager = data->dManager; - data->dManager->deleteDetData(data->uuid); + data->dManager->deleteDetDataLater(data->uuid); detectionResultHandle(data); // 删除数据释放资源 @@ -122,10 +135,12 @@ public: private: int uiShowImgCompressThreshold = 5000; // 超过该宽或高就压缩 imgSaveThreadManager* _imgSaveThreadManager = nullptr; - handleAiModelsTemplate* _handleAiModels = nullptr; + customTemplate* _handleAiModels = nullptr; triggerManager* _triggerManager = nullptr; processAlgoCallback _processAlgoCallback; bSignalHub* bridge = nullptr; + detCallbackChainWatcher* _chainWatcher = nullptr; ServiceManager* _serviceManager = nullptr; }; + #pragma once \ No newline at end of file diff --git a/src/core/service/detCallbackChainWatcher.h b/src/core/service/detCallbackChainWatcher.h new file mode 100644 index 0000000..7c9f41b --- /dev/null +++ b/src/core/service/detCallbackChainWatcher.h @@ -0,0 +1,220 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +struct FeatureInfo { + QFuture future; + QString name; + QDateTime addTime; + QDateTime lastCheckTime; + bool wasRunning; + int errorCount; + + FeatureInfo() : wasRunning(false), errorCount(0) {} +}; + +class detCallbackChainWatcher : public QThread { + Q_OBJECT + +public: + explicit detCallbackChainWatcher(int Interval = 100, QObject* parent = nullptr) + : QThread(parent) + , _running(false) + , _reportInterval(5000) // 默认5秒报告一次 + , _nextFeatureId(0) + { + _monitorInterval = qMax(100, Interval); + if (!_running) { + _running = true; + start(); + qDebug() << "[Watcher] Monitoring started with interval:" << _monitorInterval << "ms"; + } + } + + ~detCallbackChainWatcher() { + stop(); + } + + // 添加需要监控的Future + int addFeature(const QFuture& future, const QString& name = QString()) { + QMutexLocker locker(&_mutex); + + int id = _nextFeatureId++; + FeatureInfo info; + info.future = future; + info.name = name.isEmpty() ? QString("Feature_%1").arg(id) : name; + info.addTime = QDateTime::currentDateTime(); + info.lastCheckTime = info.addTime; + info.wasRunning = future.isRunning(); + info.errorCount = 0; + + _features.insert(id, info); + + return id; + } + + // 移除监控的Feature + void removeFeature(int id) { + QMutexLocker locker(&_mutex); + if (_features.contains(id)) { + _features.remove(id); + } + } + + // 设置报告间隔(毫秒) + void setReportInterval(int interval) { + QMutexLocker locker(&_mutex); + _reportInterval = qMax(1000, interval); + } + + // 停止监控 + void stop() { + if (_running) { + _running = false; + if (!wait(3000)) { // 等待最多3秒 + qWarning() << "[Watcher] Thread did not stop gracefully, terminating..."; + terminate(); + wait(1000); + } + qDebug() << "[Watcher] Monitoring stopped"; + } + } + + // 获取当前监控的特性数量 + int getFeatureCount() const { + QMutexLocker locker(&_mutex); + return _features.size(); + } + +protected: + void run() override { + QDateTime lastReportTime = QDateTime::currentDateTime(); + + while (_running) { + QDateTime currentTime = QDateTime::currentDateTime(); + + // 检查所有监控的Features + checkFeatures(currentTime); + + // 定期生成状态报告 + if (lastReportTime.msecsTo(currentTime) >= _reportInterval) { + generateStatusReport(); + lastReportTime = currentTime; + } + + // 休眠 + QThread::msleep(_monitorInterval); + } + + qDebug() << "[Watcher] Monitor thread exiting..."; + } + +private: + // 检查所有Features的状态 + void checkFeatures(const QDateTime& currentTime) { + QMutexLocker locker(&_mutex); + + QList toRemove; + + for (auto it = _features.begin(); it != _features.end(); ++it) { + FeatureInfo& info = it.value(); + int id = it.key(); + + info.lastCheckTime = currentTime; + + // 检查Future状态 + if (info.future.isCanceled()) { + qWarning() << "[Watcher] Feature" << info.name + << "(ID:" << id << ") was CANCELLED!" + << "Added at:" << info.addTime.toString("yyyy-MM-dd hh:mm:ss") + << "Duration:" << info.addTime.msecsTo(currentTime) << "ms"; + toRemove.append(id); + continue; + } + + if (info.future.isFinished()) { + toRemove.append(id); + continue; + } + + // 检查是否正在运行 + bool isRunning = info.future.isRunning(); + if (!isRunning && !info.future.isFinished()) { + info.errorCount++; + qWarning() << "[Watcher] Feature" << info.name + << "(ID:" << id << ") is NOT RUNNING!" + << "Error count:" << info.errorCount + << "Elapsed time:" << info.addTime.msecsTo(currentTime) << "ms"; + + // 多次检测到未运行 + if (info.errorCount >= 3) { + qCritical() << "[Watcher] CRITICAL: Feature" << info.name + << "(ID:" << id << ") has failed" << info.errorCount + << "consecutive checks!"; + } + } else if (isRunning && info.errorCount > 0) { + // 如果之前有错误但现在恢复了,只重置计数不打印 + info.errorCount = 0; + } + + info.wasRunning = isRunning; + } + + // 移除已完成或取消的Features + for (int id : toRemove) { + _features.remove(id); + } + } + + // 生成状态报告(仅在有异常时打印) + void generateStatusReport() { + QMutexLocker locker(&_mutex); + + if (_features.isEmpty()) { + return; + } + + int errorCount = 0; + + // 统计有错误的特性 + for (auto it = _features.constBegin(); it != _features.constEnd(); ++it) { + const FeatureInfo& info = it.value(); + if (info.errorCount > 0) { + errorCount++; + } + } + + // 只在有错误时打印报告 + if (errorCount > 0) { + qWarning() << "========== [Watcher] Error Report =========="; + qWarning() << "Total monitored features:" << _features.size() << "| Features with errors:" << errorCount; + + for (auto it = _features.constBegin(); it != _features.constEnd(); ++it) { + const FeatureInfo& info = it.value(); + int id = it.key(); + + // 只打印有错误的特性 + if (info.errorCount > 0) { + qint64 elapsed = info.addTime.msecsTo(QDateTime::currentDateTime()); + qWarning() << " - [ERROR]" << info.name << "(ID:" << id << ")" + << "| Error count:" << info.errorCount + << "| Elapsed:" << elapsed << "ms"; + } + } + + qWarning() << "============================================="; + } + } + + bool _running; + int _monitorInterval; + int _reportInterval; + int _nextFeatureId; + QMap _features; + mutable QMutex _mutex; + +}; \ No newline at end of file diff --git a/src/core/service/detData.h b/src/core/service/detData.h index aed7bf5..abe442f 100644 --- a/src/core/service/detData.h +++ b/src/core/service/detData.h @@ -50,7 +50,7 @@ public: } const cv::Mat& getResultImg(const int index) { QMutexLocker locker(&resultMutex); - if (resultImgs.size() < index) + if (resultImgs.size() - 1 < index) return cv::Mat(100, 100, CV_8UC1,cv::Scalar(0)); return resultImgs[index]; } @@ -125,9 +125,13 @@ public: QMutexLocker locker(&oriImgMutex); return oriImgs.size(); } + std::vector* getOriImgVecPtr() { + QMutexLocker locker(&oriImgMutex); + return &oriImgs; + } const cv::Mat& getOriImg(const int& index) { QMutexLocker locker(&oriImgMutex); - if (oriImgs.size() < index) + if (oriImgs.size() - 1 < index) return cv::Mat(100, 100, CV_8UC1, cv::Scalar(0)); return oriImgs[index]; } @@ -161,6 +165,12 @@ 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; + resultSaveText = saveText; + } //结果图展示预设 std::vector< showImgPack>resultImgShowSet; //打包存入的SQL数据 @@ -226,7 +236,7 @@ public: } return nullptr; } - bool deleteDetData(QString uuid) { + bool deleteDetDataLater(QString uuid) { QMutexLocker locker(&dataMutex); auto it = map.find(uuid); if (it != map.end()) { diff --git a/src/core/service/imgSaveThreadManager.h b/src/core/service/imgSaveThreadManager.h index e6e1f6a..02fb486 100644 --- a/src/core/service/imgSaveThreadManager.h +++ b/src/core/service/imgSaveThreadManager.h @@ -9,14 +9,16 @@ #include #include #include -enum imgSaveThreadType { - oriImg, - resImg, - segImg, - clsImg -}; +#include + class ImageSavePathFormatter { public: + enum imgSaveThreadType { + oriImg, + resImg, + segImg, + clsImg + }; QString rootDir = ""; QString genPath(std::shared_ptr data, const QString& typeStr, QString customPath = "", std::vector>customParams = std::vector>()){ QString pathTemplate = !customPath.isEmpty() ? customPath : defaultPath; @@ -38,6 +40,9 @@ public: else if (!data->aiDetOK) processResult = "aiNG"; else if (!data->halconOK) processResult = "algoNG"; else processResult = "OK"; + for (int i = 0; i < data->resultSaveText.size(); i++) { + processResult.append("_" + data->resultSaveText[i]); + } result.replace("{processResult}", processResult); // 替换SN/设备信息占位符 @@ -172,18 +177,122 @@ struct saveJob { std::string jobName; QQueue> imgQueue; }; + +// 数据库存储线程类 +class dbSaveThread : public QThread { +public: + dbSaveThread(const QString& dbPath) : sqlDB(dbPath) {} + + void run() { + try { + while (true) { + QQueue localQueue; + // 从队列中取出数据 + { + QMutexLocker locker(&queueMutex); + if (pathQueue.isEmpty()) { + break; + } + localQueue.swap(pathQueue); + } + + // 批量处理 + QString tableName = QDateTime::currentDateTime().toString("yyyy-MM-dd-HH"); + + // 创建表(如果不存在) + sqlDB.createTable(tableName, { + {"directory_path", "TEXT UNIQUE"} // 使用UNIQUE约束避免重复 + }); + + while (!localQueue.isEmpty()) { + QString dirPath = localQueue.dequeue(); + + // 查询是否已存在 + if (!isPathExists(tableName, dirPath)) { + // 不存在则插入 + try { + std::map insertData; + insertData["directory_path"] = dirPath; + sqlDB._insert(tableName, insertData); + } + catch (...) { + // 可能是并发插入导致的重复,忽略 + } + } + } + } + } + catch (std::exception& e) { + qCritical() << "[DB存储线程] 异常:" << e.what(); + } + catch (...) { + qCritical() << "[DB存储线程] 未知异常"; + } + } + + // 添加路径到队列 + void addPath(const QString& dirPath) { + QMutexLocker locker(&queueMutex); + pathQueue.enqueue(dirPath); + pendingCount++; + + if (!this->isRunning()) { + this->start(); + } + } + + // 批量添加路径 + void addPaths(const std::vector& dirPaths) { + if (dirPaths.empty()) return; + + QMutexLocker locker(&queueMutex); + for (const auto& path : dirPaths) { + pathQueue.enqueue(QString::fromStdString(path)); + } + pendingCount += dirPaths.size(); + + if (!this->isRunning()) { + this->start(); + } + } + + // 获取待处理数量 + int getPendingCount() { + QMutexLocker locker(&queueMutex); + return pendingCount; + } + +private: + // 检查路径是否已存在 + bool isPathExists(const QString& tableName, const QString& dirPath) { + try { + // 使用参数化查询,避免SQL注入风险 + std::map conditions; + conditions["directory_path"] = dirPath; + auto result = sqlDB._search(tableName, {}, conditions); + return !result.empty(); + } + catch (...) { + return false; + } + } + + SQLiteDB sqlDB; + QQueue pathQueue; + QMutex queueMutex; + int pendingCount = 0; +}; + class imgSaveThread : public QThread { public: + imgSaveThread(int threadIndexIn = 0) + :threadIndex(threadIndexIn){ + } enum type { normal, priority }; - QMutex mutex; - std::vector compressionParams{ cv::IMWRITE_PNG_COMPRESSION ,9 }; - QQueue< std::shared_ptr>priorityQueue; - QQueue< std::shared_ptr>defaultQueue; - int imgRemainCount = 0; void run() { try { while (true) { @@ -191,7 +300,7 @@ public: std::shared_ptr job = nullptr; // 优先处理 priorityQueue { - QMutexLocker locker(&mutex); + QMutexLocker locker(&queueMutex); if (!priorityQueue.isEmpty()) { job = priorityQueue.dequeue(); } @@ -213,6 +322,8 @@ public: auto data = std::move(localQueue.dequeue()); #if saveImgEnable cv::imwrite(data.first, data.second); + QMutexLocker locker(&threadBufferSizeMutex); + threadBufferSize -= data.second.total() * data.second.elemSize(); #endif } @@ -231,8 +342,13 @@ public: } void addJob(std::shared_ptr job, type type_ = normal) { - - QMutexLocker locker(&mutex); + { + QMutexLocker locker(&threadBufferSizeMutex); + for (auto& img : job->imgQueue) { + threadBufferSize += img.second.total() * img.second.elemSize(); + } + } + QMutexLocker locker(&queueMutex); switch (type_) { case normal: defaultQueue.append(job); @@ -248,31 +364,84 @@ public: } } - int queueSize() { - QMutexLocker locker(&mutex); - int size = defaultQueue.size(); + int getQueueSize() { + QMutexLocker locker(&queueMutex); + int size = defaultQueue.size() + priorityQueue.size(); return size; } + int getThreadBufferSize() { + QMutexLocker locker(&threadBufferSizeMutex); + return threadBufferSize; + } +private: + std::vector compressionParams{ cv::IMWRITE_PNG_COMPRESSION ,9 }; + QQueue< std::shared_ptr>priorityQueue; + QQueue< std::shared_ptr>defaultQueue; + int threadIndex = 0, threadBufferSize = 0, imgRemainCount = 0; + QMutex queueMutex, threadBufferSizeMutex; }; class imgSaveThreadManager { public: - imgSaveThreadManager(std::string pathIn, paramSyncManager* paramSyncManagerIn) { + imgSaveThreadManager(std::string pathIn, paramSyncManager* paramSyncManagerIn) + :dbThread(std::make_unique("./sqlDatabase/imgSavePath.db")){ _ImageSavePathFormatter.rootDir = QString::fromStdString(pathIn); _paramSyncManager = paramSyncManagerIn; saveOri = _paramSyncManager->get("通用设置", "存储原图", true).toBool(); saveRes = _paramSyncManager->get("通用设置", "存储结果图", true).toBool(); saveSeg = _paramSyncManager->get("通用设置", "存储Seg图", true).toBool(); saveCls = _paramSyncManager->get("通用设置", "存储Cls图", true).toBool(); + + //初始化存图线程 + saveThreads.emplace_back(std::make_unique(saveThreads.size())); } - ~imgSaveThreadManager() {}; - imgSaveThread saveThread; + ~imgSaveThreadManager() { + // 等待数据库存储线程完成 + if (dbThread && dbThread->isRunning()) { + qDebug() << "等待数据库存储线程完成..."; + dbThread->wait(5000); // 最多等待5秒 + if (dbThread->isRunning()) { + int pending = dbThread->getPendingCount(); + qWarning() << "数据库存储线程未能在超时时间内完成,仍有" << pending << "条待处理,强制终止"; + dbThread->terminate(); + dbThread->wait(); + } + } + + // 等待所有保存线程完成任务 + for (auto& threadPtr : saveThreads) { + if (threadPtr && threadPtr->isRunning()) { + qDebug() << "等待图像保存线程完成..."; + // 等待线程自然结束(队列为空时会自动退出) + threadPtr->wait(3000); // 最多等待3秒 + if (threadPtr->isRunning()) { + qWarning() << "图像保存线程未能在超时时间内完成,强制终止"; + threadPtr->terminate(); + threadPtr->wait(); + } + } + + // 输出未完成任务数量 + if (threadPtr) { + int remainingJobs = threadPtr->getQueueSize(); + if (remainingJobs > 0) { + qWarning() << "析构时仍有" << remainingJobs << "个任务未完成"; + } + } + } + + }; void saveImage(std::shared_ptr data) { - if (getParamTimer.elapsed() > 5000) { - saveOri = _paramSyncManager->get("通用设置", "存储原图", true).toBool(); - saveRes = _paramSyncManager->get("通用设置", "存储结果图", true).toBool(); - saveSeg = _paramSyncManager->get("通用设置", "存储Seg图", true).toBool(); - saveCls = _paramSyncManager->get("通用设置", "存储Cls图", true).toBool(); - getParamTimer.restart(); + // 线程安全地获取参数 + std::vector allDirectoryPaths; + { + QMutexLocker locker(¶mTimerMutex); + if (getParamTimer.elapsed() > 5000) { + saveOri = _paramSyncManager->get("通用设置", "存储原图", true).toBool(); + saveRes = _paramSyncManager->get("通用设置", "存储结果图", true).toBool(); + saveSeg = _paramSyncManager->get("通用设置", "存储Seg图", true).toBool(); + saveCls = _paramSyncManager->get("通用设置", "存储Cls图", true).toBool(); + getParamTimer.restart(); + } } try { std::shared_ptr oriJob(new saveJob("[ORI_JOB]" + data->SNcode)); @@ -280,13 +449,14 @@ public: QString oriSavePath = _ImageSavePathFormatter.genPath(data, "原图", data->customPath, data->customImageSaveTemplateParams);//获取文件夹名 if (saveOri == true || saveSeg == true || saveCls == true) { createDirectoryIfNotExists(oriSavePath);//不存在此文件夹则创建 + allDirectoryPaths.push_back(oriSavePath.toLocal8Bit().toStdString());//记录文件夹路径 if (data->getOriImgSize() != 0 && saveOri == true) { - std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, oriImg, data->getOriImgVec());//按规则为文件创建命名 + std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, ImageSavePathFormatter::oriImg, data->getOriImgVec());//按规则为文件创建命名 packageData(oriJob->imgQueue, oriSavePath.toLocal8Bit().toStdString(), fileNames, data->getOriImgVec());//打包数据 } //SEG原图 if (data->getSegOriginImgSize() != 0 && saveSeg == true) { - std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, segImg, data->getSegOriginImgVec());//按规则为文件创建命名 + std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, ImageSavePathFormatter::segImg, data->getSegOriginImgVec());//按规则为文件创建命名 packageData(resJob->imgQueue, oriSavePath.toLocal8Bit().toStdString(), fileNames, data->getSegOriginImgVec());//打包数据 } //CLS原图 @@ -300,17 +470,28 @@ public: QString resSavePath = _ImageSavePathFormatter.genPath(data, "结果图", data->customPath, data->customImageSaveTemplateParams);//获取文件夹名 if (saveRes == true) { createDirectoryIfNotExists(resSavePath);//不存在此文件夹则创建 + allDirectoryPaths.push_back(resSavePath.toLocal8Bit().toStdString());//记录文件夹路径 //结果图保存 if (data->getResultImgSize() != 0) { - std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, resImg, data->getResultImgVec());//按规则为文件创建命名 + std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, ImageSavePathFormatter::resImg, data->getResultImgVec());//按规则为文件创建命名 packageData(resJob->imgQueue, resSavePath.toLocal8Bit().toStdString(), fileNames, data->getResultImgVec());//打包数据 } } if (oriJob->imgQueue.size() != 0) - saveThread.addJob(oriJob); + getSaveThread()->addJob(oriJob); if (resJob->imgQueue.size() != 0) - saveThread.addJob(resJob, imgSaveThread::priority); + getSaveThread()->addJob(resJob, imgSaveThread::priority); + +#pragma region 将存储目录写入数据库中 +#if savePathToDataBase + if (!allDirectoryPaths.empty() && dbThread) { + dbThread->addPaths(allDirectoryPaths); + } +#endif +#pragma endregion + + } catch (cv::Exception& e) { qCritical() << "打包存图崩溃 OpenCV异常: " << e.what() << " SN: " << QString::fromStdString(data->SNcode) << " uuid: " << data->uuid; @@ -319,8 +500,31 @@ public: } catch (...) { qCritical() << "打包存图崩溃 未知异常 SN: " << QString::fromStdString(data->SNcode) << " uuid: " << data->uuid; } + } + imgSaveThread* getSaveThread() { + QMutexLocker locker(&saveThreadMutexVec); + for (auto& threadPtr : saveThreads) { + int threadbufferSize = threadPtr->getThreadBufferSize(); + if (threadbufferSize < GigaByte) { + return threadPtr.get(); + } + } + // 否则新建线程 + if (saveThreads.size() < maxSaveThreadCount) { + saveThreads.emplace_back(std::make_unique(saveThreads.size())); + qWarning() << "当前存图线程缓存均已超过1Gb,新建存图线程后当前线程数" << saveThreads.size(); + } + else { + qCritical() << "当前存图线程缓存均已超过1Gb,且已达最大线程数限制,继续使用最后一个存图线程,当前线程数" << saveThreads.size(); + } + return saveThreads.back().get(); } private: + std::unique_ptr dbThread; // 数据库存储线程 + QMutex paramTimerMutex; // 保护参数计时器的互斥锁 + int maxSaveThreadCount = 4; + QMutex saveThreadMutexVec; + std::vector> saveThreads; bool saveOri = true, saveRes = true, saveSeg = true, saveCls = true; QElapsedTimer getParamTimer;//防止加锁次数过多导致卡顿 paramSyncManager* _paramSyncManager; diff --git a/src/core/service/serviceManager.h b/src/core/service/serviceManager.h index b861f31..f48745d 100644 --- a/src/core/service/serviceManager.h +++ b/src/core/service/serviceManager.h @@ -5,7 +5,7 @@ #include #include #include - +#include class ServiceManager { public: detDataManager* _detDataManager = nullptr;// 检测数据管理器 需要初始化 @@ -16,6 +16,7 @@ public: CsvWriter* _csvWriter = nullptr; missionResultHandle* _missionResultHandle = nullptr; paramSyncManager* _paramSyncManager = nullptr; + detCallbackChainWatcher _chainWatcher; }; #pragma once \ No newline at end of file diff --git a/src/core/service/triggerManager.cpp b/src/core/service/triggerManager.cpp index b020a06..2b88b21 100644 --- a/src/core/service/triggerManager.cpp +++ b/src/core/service/triggerManager.cpp @@ -3,6 +3,7 @@ #include #include #include +#include triggerManager::triggerManager(ServiceManager* _serviceManager, bSignalHub* bridgeIn,nlohmann::ordered_json& triggerJson){ bridge = bridgeIn; @@ -160,7 +161,7 @@ void triggerManager::checkCallback(readAllStruct _struct, QByteArray& byteArray) { if (checkTrigger(callback.triggerAddress, callback.triggerValue, _struct, byteArray) == true) { - qDebug() << "func:" << QString::fromStdString(callback.funcName) << "->已触发"; + qDebug() << "func:" << QString::fromStdString(callback.funcName) << "->已触发 " << callback.triggerValue; std::thread([callback, byteArray]() mutable { try { callback.func(callback.triggerAddress, callback.triggerValue, byteArray); // 执行回调函数 diff --git a/src/core/service/triggerManager.h b/src/core/service/triggerManager.h index 09d5f35..e91c6d6 100644 --- a/src/core/service/triggerManager.h +++ b/src/core/service/triggerManager.h @@ -125,7 +125,8 @@ public: #pragma region 发送数据 - bool sendFinsMsg(QString cmdx){ + //直接发送数据到模块的方法 + bool sendFinsMsg(const QString& cmdx){ if (trigger == nullptr) return false; if (!trigger->writeData(vec_mat, cmdx.toUtf8())) @@ -135,6 +136,7 @@ public: } return true; } + //直接发送数据到模块的方法 bool sendFinsMsg(const char* cmdx){ QString str = cmdx; if (trigger == nullptr) @@ -146,10 +148,12 @@ public: } return true; } - bool sendFinsMsg(QByteArray write_byte){ + //直接发送数据到模块的方法 + bool sendFinsMsg(const QByteArray& write_byte){ if (trigger == nullptr) return false; - if (!trigger->writeData(vec_mat, write_byte) && trigger != nullptr) + QByteArray dataSend = write_byte; + if (!trigger->writeData(vec_mat, dataSend) && trigger != nullptr) { qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << write_byte; return false; @@ -160,7 +164,7 @@ public: //FINS //useage "D9200_1" - bool writeShort(QByteArray write_byte) { + bool writeShort(const QByteArray& write_byte) { if (trigger == nullptr) return false; QByteArray array("write_short_" + write_byte); @@ -171,10 +175,9 @@ public: } return true; } - //useage {"D9200_1","D9201_1"} - bool writeShort(std::vector write_byte) { - if (trigger == nullptr) + bool writeShort(const std::vector& write_byte) { + if (trigger == nullptr || write_byte.size() == 0) return false; for (auto& byteArray : write_byte) { QByteArray array = QByteArray::fromStdString("write_short_" + byteArray); @@ -186,11 +189,52 @@ public: return true; } - //useage {"D9200_1","D9201_1"} - bool writeFloat(std::vector write_byte) { + bool writeShort(const std::vector& write_byte) { + if (trigger == nullptr || write_byte.size() == 0) + return false; + for (auto& byteArray : write_byte) { + QByteArray array = "write_short_" + byteArray; + if (!trigger->writeData(vec_mat, array) && trigger != nullptr) { + qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << array; + return false; + } + } + + return true; + } + //仅在boost模块中有效 按顺序顺序写入 + bool sequentialWriteShort(const std::vector& write_byte) { + if (trigger == nullptr || write_byte.size() == 0) + return false; + QByteArray arraySend; + for (auto& byteArray : write_byte) { + arraySend += "write_short_" + byteArray + "#"; + } + arraySend.chop(1); + if (!trigger->writeData(vec_mat, arraySend) && trigger != nullptr) { + qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << arraySend; + return false; + } + return true; + } + + //useage "D9200_1" + bool writeFloat(const QByteArray& write_byte) { if (trigger == nullptr) return false; + QByteArray array = "write_float_" + write_byte; + if (!trigger->writeData(vec_mat, array) && trigger != nullptr) { + qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << array; + return false; + } + + return true; + } + //useage {"D9200_1","D9201_1"} + bool writeFloat(const std::vector& write_byte) { + if (trigger == nullptr || write_byte.size() == 0) + return false; for (auto& byteArray : write_byte) { QByteArray array = QByteArray::fromStdString("write_float_" + byteArray); if (!trigger->writeData(vec_mat, array) && trigger != nullptr) { @@ -201,19 +245,9 @@ public: return true; } - bool writeFloat(QByteArray write_byte) { - if (trigger == nullptr) - return false; - QByteArray array = "write_float_" + write_byte; - if (!trigger->writeData(vec_mat, array) && trigger != nullptr) { - qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << array; - return false; - } - - return true; - } - bool writeFloat(std::vector write_byte) { - if (trigger == nullptr) + //useage {"D9200_1","D9201_1"} + bool writeFloat(const std::vector& write_byte) { + if (trigger == nullptr || write_byte.size() == 0) return false; for (auto& byteArray : write_byte) { QByteArray array = "write_float_" + byteArray; @@ -225,6 +259,21 @@ public: return true; } + //仅在boost模块中有效 按顺序顺序写入 + bool sequentialWriteFloat(const std::vector& write_byte) { + if (trigger == nullptr || write_byte.size() == 0) + return false; + QByteArray arraySend; + for (auto& byteArray : write_byte) { + arraySend += "write_floatt_" + byteArray + "#"; + } + arraySend.chop(1); + if (!trigger->writeData(vec_mat, arraySend) && trigger != nullptr) { + qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << arraySend; + return false; + } + return true; + } #pragma endregion #pragma region 接收数据 void reciveCommond(); diff --git a/src/launcher/GUI/mainwindow.h b/src/launcher/GUI/mainwindow.h index 1be7f56..7661d98 100644 --- a/src/launcher/GUI/mainwindow.h +++ b/src/launcher/GUI/mainwindow.h @@ -143,7 +143,6 @@ public: "QPushButton:hover { background-color: rgb(%1); }").arg(sColor_Red)); // 设置透明背景和悬停时的背景色 exitButton->setFixedHeight(topBarHeight); exitButton->setFixedWidth(buttonWidth); - //QObject::connect(exitButton, &QPushButton::clicked, this, &topMenuBar::QuitCheck); // 点击退出按钮退出应用程序 connect(exitButton, &QPushButton::clicked, mainWindow, &QWidget::close); } @@ -454,7 +453,7 @@ protected: int ret = dialog.exec(); if (ret == QDialog::Accepted &&(edit.text() == "Y" || edit.text() == "y")){ - qDebug() << "退出应用程序"; + qDebug() << "手动退出应用程序"; quitFunction(); config->saveSettingJson(); event->accept(); diff --git a/src/launcher/GUI/paramEditorDialog.h b/src/launcher/GUI/paramEditorDialog.h index 76945b7..3766bde 100644 --- a/src/launcher/GUI/paramEditorDialog.h +++ b/src/launcher/GUI/paramEditorDialog.h @@ -108,27 +108,36 @@ public: groupedParams[groupName].push_back(fullKey); } + if (!groups.contains("hide"))groups.insert("hide"); + + for (const QString& group : groups) { + if (!m_allParams.contains("hide." + group) && group != "hide") { + m_allParams.insert("hide." + group, true); + params.push_back({ "hide." + group, true }); + groupedParams["hide"].push_back("hide." + group); + } + } + //添加分组到侧边栏 QStringList groupList = groups.values(); groupList.sort(); - //添加"所有参数"选项 - m_sidebarList->addItem("所有参数"); + //根据viewOnlyMode添加分组 for (const QString& group : groupList) { + // 当viewOnlyMode为false时,隐藏"hide"分组 + if (viewOnlyMode && (group == "hide" || (!m_allParams["hide." + group].toBool()))) { + continue; + } m_sidebarList->addItem(group); } //保存分组参数 m_groupedParamsNames = groupedParams; - for (auto& it = params.begin(); it != params.end(); it++) { - m_groupedParamsNames["所有参数"].push_back(it->first); - } - //默认显示所有参数 - displayGroupParams("所有参数"); - + //默认显示第一个分组 if (m_sidebarList->count() > 0) { m_sidebarList->setCurrentRow(0); + displayGroupParams(m_sidebarList->item(0)->text()); } } @@ -307,7 +316,7 @@ private: imgaeTipLayout->addWidget(imageTipLabel); } void switchImageTipArea(const QString& paramName) { - if (paramName == "所有参数" || paramName == "通用设置") { + if (paramName == "通用设置") { imageTipLabel->setText(paramName); return; } @@ -475,11 +484,9 @@ private: QString displayName = fullKey; //分组显示,去掉分组前缀 - if (groupName != "所有参数") { - int dotIndex = fullKey.indexOf('.'); - if (dotIndex != -1) { - displayName = fullKey.mid(dotIndex + 1); - } + int dotIndex = fullKey.indexOf('.'); + if (dotIndex != -1) { + displayName = fullKey.mid(dotIndex + 1); } // 设置键名(不可编辑) diff --git a/src/launcher/appCore.hpp b/src/launcher/appCore.hpp index a409a72..908edb4 100644 --- a/src/launcher/appCore.hpp +++ b/src/launcher/appCore.hpp @@ -15,7 +15,7 @@ class backEnd { public: IBackend* backendPtr = nullptr; HMODULE hDll; - bool loadCore() { + bool loadCore(SQLiteDB* db, nlohmann::ordered_json& backendJson) { hDll = LoadLibrary("core.dll"); if (!hDll) { std::cerr << "Failed to load Core DLL!" << std::endl; @@ -27,6 +27,7 @@ public: if (CreateBackend && ReleaseBackend) { backendPtr = CreateBackend(); + backendPtr->init(db, backendJson); } else { std::cerr << "Failed to get Core function pointers!" << std::endl; @@ -34,14 +35,9 @@ public: } return true; } - bool initCore(SQLiteDB* db, nlohmann::ordered_json& backendJson) { - backendPtr->init(db, backendJson); - return true; - } void releaseCore(nlohmann::ordered_json& json) { if (backendPtr != nullptr) { json = backendPtr->getBackendJson(); - backendPtr->cleanup(); ReleaseBackend(backendPtr); backendPtr = nullptr; } diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index 7694c76..c5cfa91 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -256,10 +256,9 @@ int main(int argc, char* argv[]) w.show(); QThread::msleep(100); // 创建后端对象 - _core._backEnd.loadCore(); // 加载核心功能 + _core._backEnd.loadCore(config.dataBase, config.missionJson["backend"]); // 加载核心功能 connectFrontSignals(&_core, &w, bridge); // 连接前端UI的信号和槽 connectBackSignals(&_core, &w, &_core._backEnd.backendPtr->_signalHub); // 连接前端UI的信号和槽 - _core._backEnd.initCore(config.dataBase, config.missionJson["backend"]); // 初始化核心功能 w.registerQuitFunc([&]() { auto& config = appConfig::getInstance(); _core._backEnd.releaseCore(config.missionJson["backend"]); diff --git a/src/mission/602/YH/581_YuHan_jixing/581_YuHan_jixing.cpp b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.cpp similarity index 58% rename from src/mission/602/YH/581_YuHan_jixing/581_YuHan_jixing.cpp rename to src/mission/581-Mfd_yh_mh_hh/581-Mfd.cpp index 7760162..c1c5f96 100644 --- a/src/mission/602/YH/581_YuHan_jixing/581_YuHan_jixing.cpp +++ b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.cpp @@ -1,7 +1,7 @@ -#include <581_YuHan_jixing.h> +#include <581-Mfd.h> mission* createMission() { - return new _581_YuHan_hanqian(); + return new _581_Mfd(); } void destroyMission(mission* _mission) { delete _mission; diff --git a/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h new file mode 100644 index 0000000..5452974 --- /dev/null +++ b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h @@ -0,0 +1,651 @@ +#include +#include + +#pragma region 算法 +#include +#include +#include + +class mfd_hh_models { +public: + handdleAI::pSegmentation* seg_hanHou = nullptr; + handdleAI::pClassification* cls_hanHou = nullptr; + handdleAI::pSegmentation* seg_hanHouDingWei = nullptr; +}; +class mfd_detParams { +public: + int biaoding = 0; +}; +class mfdHanHouParam { +public: + QMutex* mutex = new QMutex(); + std::vector< mfd_hh_models>models = std::vector< mfd_hh_models>(4); + QQueue mats; + ~mfdHanHouParam() { + delete mutex; + } + + int waitMs = 4000; + void insertImg(cv::Mat& img) { + QMutexLocker locker(mutex); + //if (mats.size() > 0) { + // qWarning() << "焊后有遗留的图像,已清除"; + // mats.clear(); + //} + cv::Mat tmp; + img.copyTo(tmp); + mats.enqueue(tmp);//发送检测数据到主线程 + } + bool waitImage(cv::Mat& out) { + int cnt = 0; + while (mats.size() == 0 && cnt < waitMs) { + QThread::msleep(100); + cnt += 100; + } + QMutexLocker locker(mutex); + if (mats.size() != 0) { + out = mats.dequeue(); + std::cout << "get" << std::endl; + return true; + } + std::cout << "overTime" << std::endl; + return false; + } +}; +using namespace HDevEngineCpp; +void exceptionResume(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->getOriImg(0).copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 100); + textPainter.putText(Paint, "NG", cv::Point(100, 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 + "_2");//结果反馈 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.01");//结果反馈 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.01");//结果反馈 +} +static bool ManHan(std::shared_ptr data, mfd_detParams* _detParams, yh_581_address address) { + try { + + std::map sqlMapData; + sqlMapData["项目"] = "满焊"; + sqlMapData["相机"] = "相机" + address.triggerAddr; + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->getOriImgSize() != 1) + { + qCritical() << "图片数量不满足要求:" << data->getOriImgSize(); + return false; + } + + // QDateTime currentimenow = QDateTime::currentDateTime(); + cv::Mat Paint; + cv::Mat src1 = data->getOriImg(0); + //src1 = cv::imread("D:\\密封钉CCD存图\\2025-12-14\\满焊CCD原图\\10H\\OK\\相机3孔5\\A100000485_Camera5_0_10-12-45.bmp", -1); + //src1 = cv::imread("D:\\readSnEmpty14-53-27-65_Camera3_0_14-53-27.bmp", -1); + if (src1.channels() != 3) + cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); + else + src1.copyTo(Paint); + //处理算法 +#pragma region halcon处理 + std::string cameraNumberStr = "1", FixtureNumber = "1"; + + if (address.triggerAddr == 20000) { + cameraNumberStr = "1"; + FixtureNumber = "1"; + } + else if (address.triggerAddr == 20002) { + cameraNumberStr = "1"; + FixtureNumber = "2"; + } + else if (address.triggerAddr == 20200) { + cameraNumberStr = "2"; + FixtureNumber = "3"; + } + else if (address.triggerAddr == 20202) { + cameraNumberStr = "2"; + FixtureNumber = "4"; + } + else if (address.triggerAddr == 20400) { + cameraNumberStr = "3"; + FixtureNumber = "5"; + } + else if (address.triggerAddr == 20402) { + cameraNumberStr = "3"; + FixtureNumber = "6"; + } + else if (address.triggerAddr == 20600) { + cameraNumberStr = "4"; + FixtureNumber = "7"; + } + else if (address.triggerAddr == 20602) { + cameraNumberStr = "4"; + FixtureNumber = "8"; + } + data->customPath = "{imgSaveRootDir}/{yyyy-MM-dd}/{saveObjectName}{imageType}/{HH}H/{processResult}/相机" + QString::fromStdString(cameraNumberStr) + "孔" + QString::fromStdString(FixtureNumber); + int ManHanbiaoding_Switch = data->service->_paramSyncManager->get("满焊", "模式选择:1标定0生产", 0).toInt(); + data->service->_paramSyncManager->edit("满焊","模式选择:1标定0生产", 0); + HalconCpp::HObject in_Image = MatToHObject(src1); + + HDevEngineCpp::HDevProcedure proc("_9_manhan"); + HDevProcedureCall procedureCall(proc); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_ProductionType", ManHanbiaoding_Switch); + procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str())); + procedureCall.SetInputCtrlParamTuple("in_FixtureNumber", HTuple(FixtureNumber.c_str())); + procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple(("./halconFiles/template_manHan/" + data->cameraKeyName + "/").c_str())); + procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/base_manHan/")); + procedureCall.SetInputCtrlParamTuple("in_LineType", "602"); + qDebug() << "halconStart"; + procedureCall.Execute(); + qDebug() << "halconEnd"; + // *output(HTuple) : < / c> + // *out_Circle, 圆心坐标(y, x, radius) < / c > + // * out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c> + // *out_OffsetX : 模组X轴的补偿量(mm) < / c > + // *out_OffsetY : 模组Y轴的补偿量(mm) < / c > + HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX"); + HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY"); + HTuple out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails"); + +#pragma endregion + int outFlag = out_Flag.D(); + //qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D(); + TextRendererZH textPainter(Paint.cols, Paint.rows, 150); + textPainter.putText(Paint, "相机:" + cameraNumberStr + " 孔" + FixtureNumber, cv::Point(50, 0), cv::Scalar(0, 255, 0)); + if (outFlag == 1) { //-1为失败,无结果 + //先处理数据 + double offsetX = 0 - out_OffsetX.D(); + double offsetY = 0 - out_OffsetY.D(); + /* if (address.triggerAddr == 20200 || address.triggerAddr == 20202 || address.triggerAddr == 20600 || address.triggerAddr == 20602) { + offsetX = -offsetX; + }*/ + //if (address.triggerAddr == 20000) { + // offsetY += 0.15; + //} + //else if (address.triggerAddr == 20002) { + // offsetY += 0.2; + //} + //else if (address.triggerAddr == 20200) { + // offsetX -= 0.05; + // offsetY -= 0.15; + //} + //else if (address.triggerAddr == 20202) { + // offsetX -= 0.1; + //} + //else if (address.triggerAddr == 20400) { + // //offsetX -= 0.1; + //} + //else if (address.triggerAddr == 20402) { + // //offsetX -= 1.2; + //} + if (abs(offsetX) < 0.01) + { + offsetX = 0.01; + } + if (abs(offsetY) < 0.01) + { + offsetY = 0.01; + } + offsetX *= 1000;//和激光交流后要求我们*1000 + offsetY *= 1000; + double X_Circle = out_Circle[1].D(); + double Y_Circle = out_Circle[0].D(); + + + if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000) + { + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 + qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 满焊X偏移abs(resultData[0]) >= 6000,may err,set 0"; + data->halconOK = false; + } + else { + sqlMapData["偏移X"] = offsetX; + sqlMapData["偏移Y"] = offsetY; + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(offsetX));//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(offsetY));//发送偏移Y + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + data->halconOK = true; + } + //圆及十字 + cv::circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 5); + cv::line(Paint, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 5); + cv::line(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 5); + + textPainter.putText(Paint, "X偏移:" + std::to_string(offsetX), cv::Point(50, 150), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "Y偏移:" + std::to_string(offsetY), cv::Point(50, 350), cv::Scalar(0, 255, 0)); + //textPainter.putText(Paint, "圆心X坐标:" + std::to_string(X_Circle), cv::Point(50, 150), cv::Scalar(0, 255, 0)); + //textPainter.putText(Paint, "圆心Y坐标:" + std::to_string(offsetY), cv::Point(50, 350), cv::Scalar(0, 255, 0)); + + + } + else { + data->halconOK = false; + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 + //textPainter.putText(Paint, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255)); + std::string ngDetail = out_NgTails.ToString().Text(); + textPainter.putText(Paint, ngDetail, cv::Point(50, 300), cv::Scalar(0, 0, 255)); + } + + if (data->halconOK == true) { + textPainter.putText(Paint, "OK", cv::Point(50, 550), cv::Scalar(0, 255, 0)); + sqlMapData["结果"] = "OK"; + } + else { + textPainter.putText(Paint, "NG", cv::Point(50, 500), cv::Scalar(0, 0, 255)); + sqlMapData["结果"] = "NG"; + } + data->service->_csvWriter->addData(QString::fromStdString(data->SNcode), sqlMapData); + + //int rate = MIN(Paint.cols, Paint.rows) / 20; + //TextRendererZH textPainter2(Paint.cols, Paint.rows, rate); + //textPainter2.putText(Paint, "获取图像时间:" + currentimenow.toString().toStdString(), cv::Point(50, Paint.rows-rate), cv::Scalar(0, 255, 255)); + //textPainter2.putText(Paint, "SN条码:" + data->SNcode, cv::Point(50, Paint.rows - (rate*2), cv::Scalar(0, 255, 255)); + data->insertResultImg(Paint); + + return true; + } + CATCH_EXCEPTIONS + exceptionResume(data, address, "异常"); +} +static bool YuHan(std::shared_ptr data, mfd_detParams* _detParams, yh_581_address address) { + try { + std::map sqlMapData; + sqlMapData["项目"] = "预焊"; + sqlMapData["相机"] = "相机" + address.triggerAddr; + ///////////////////取图//处理////////////////// + if (data->getOriImgSize() != 1) { + qCritical() << "图片数量不满足要求:" << data->getOriImgSize(); + return false; + } + + /*QDateTime currentimenow = QDateTime::currentDateTime();*/ + + cv::Mat Paint; + cv::Mat src1 = data->getOriImg(0); + //src1 = cv::imread("D:\\04QCB82602000JFCA00600BN_Camera1_0_04-18-02.bmp",-1); + //src1 = cv::imread("C:\\Users\\Main\\MVS\\Data\\Image_20251205093757260.bmp", -1); + if (src1.channels() != 3) + cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); + else + src1.copyTo(Paint); + //处理算法 +#pragma region halcon处理 + std::string cameraNumberStr = "1", FixtureNumber = "1"; + if (address.triggerAddr == 19600) { + cameraNumberStr = "1"; + FixtureNumber = "1"; + } + else if (address.triggerAddr == 19602) { + cameraNumberStr = "1"; + FixtureNumber = "3"; + } + else if (address.triggerAddr == 19800) { + cameraNumberStr = "2"; + FixtureNumber = "2"; + } + else if (address.triggerAddr == 19802) { + cameraNumberStr = "2"; + FixtureNumber = "4"; + } + data->customPath = "{imgSaveRootDir}/{yyyy-MM-dd}/{saveObjectName}{imageType}/{HH}H/{processResult}/相机" + QString::fromStdString(cameraNumberStr) + "孔" + QString::fromStdString(FixtureNumber);; + int pingDing_aoDing_Switch = data->service->_paramSyncManager->get("预焊","1平钉2凹钉", 2).toInt(); + int YuHanbiaoding_Switch = data->service->_paramSyncManager->get("预焊","模式选择:1标定0生产", 0).toInt(); + data->service->_paramSyncManager->edit("预焊", "1标定0生产", 0); + double tongXingJuThreshold = data->service->_paramSyncManager->get("预焊", "同心距上限", 0.1).toDouble(); + HDevEngineCpp::HDevProcedure proc("_9_yuhan"); + HalconCpp::HObject in_Image = MatToHObject(src1); + HDevProcedureCall procedureCall(proc); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_ProductionType", YuHanbiaoding_Switch); + procedureCall.SetInputCtrlParamTuple("in_Resolution", HTuple(0.0069699)); + procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str())); + procedureCall.SetInputCtrlParamTuple("in_FixtureNumber", HTuple(FixtureNumber.c_str())); + procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple(("./halconFiles/template_yuhan/" + data->cameraKeyName + "/").c_str())); + procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/base_yuhan/")); + procedureCall.SetInputCtrlParamTuple("in_NailType", pingDing_aoDing_Switch);//1:平钉 2:凹钉; + //procedureCall.SetInputCtrlParamTuple("in_LineType", "602"); + procedureCall.Execute(); + // *output(HTuple) : < / c> + // *out_Circle, 圆心坐标(y, x, radius) < / c > + // * out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c> + // *out_OffsetX : 模组X轴的补偿量(mm) < / c > + // *out_OffsetY : 模组Y轴的补偿量(mm) < / c > + HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX"); + HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY"); + HTuple out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails"); + HTuple out_CCDistance = procedureCall.GetOutputCtrlParamTuple("out_CCDistance"); + HTuple out_OffsetValue = procedureCall.GetOutputCtrlParamTuple("out_OffsetValue"); +#pragma endregion + int outFlag = out_Flag.D(); + //qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D(); + TextRendererZH textPainter(Paint.cols, Paint.rows, 150); + textPainter.putText(Paint, "相机:" + cameraNumberStr + " 孔位" + FixtureNumber + (pingDing_aoDing_Switch == 1 ? " 平钉算法" : " 凹钉算法"), cv::Point(50, 0), cv::Scalar(0, 255, 0)); + if (outFlag == 1) { //-1为失败,无结果 + double offsetX = out_OffsetX.D(); + double offsetY = out_OffsetY.D(); + double offsetNum = out_OffsetValue.D(); + double CCDdist = out_CCDistance.D(); + //if (address.triggerAddr == 19600) + // offsetX -= 0.2; + //else if (address.triggerAddr == 19602) { + // offsetX -= 0.15; + // offsetY += 0.1; + //} + //else (address.triggerAddr == 19800) { + // offsetY -= 0.2; + //} + + //圆及十字 + cv::circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 5); + cv::line(Paint, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 5); + cv::line(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 5); + + textPainter.putText(Paint, "X偏移:" + std::to_string(offsetX), cv::Point(50, 150), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "Y偏移:" + std::to_string(offsetY), cv::Point(50, 350), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "同心距:" + std::to_string(CCDdist), cv::Point(50, 550), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "偏移值:" + std::to_string(offsetNum), cv::Point(50, 750), cv::Scalar(0, 255, 0)); + + if (std::abs(tongXingJuThreshold) < CCDdist) { + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(offsetNum));//发送偏移量 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 + qDebug() << __FUNCTION__ << " line:" << __LINE__ << "同心距NG"; + textPainter.putText(Paint, "同心距NG", cv::Point(250, 950), cv::Scalar(0, 0, 255)); + data->halconOK = false; + } + else if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000) { + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(offsetNum));//发送偏移量 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 + qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 预焊X偏移abs(resultData[0]) >= 6000,may err,set 0"; + data->halconOK = false; + } + else { + sqlMapData["偏移X"] = offsetX; + sqlMapData["偏移Y"] = offsetY; + if (offsetX || offsetY == 0) + { + offsetX += 0.01; + offsetY += 0.01; + } + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(offsetX));//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(offsetY));//发送偏移Y + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(offsetNum));//发送偏移量 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + data->halconOK = true; + } + } + else { + data->halconOK = false; + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 + //textPainter.putText(Paint, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255)); + std::string ngDetail = out_NgTails.ToString().Text(); + textPainter.putText(Paint, ngDetail, cv::Point(50, 300), cv::Scalar(0, 0, 255)); + + } + + if (data->halconOK == true) { + textPainter.putText(Paint, "OK", cv::Point(50, 950), cv::Scalar(0, 255, 0)); + sqlMapData["结果"] = "OK"; + } + else { + textPainter.putText(Paint, "NG", cv::Point(50, 950), cv::Scalar(0, 0, 255)); + sqlMapData["结果"] = "NG"; + } + data->service->_csvWriter->addData(QString::fromStdString(data->SNcode), sqlMapData); + + //int rate = MIN(Paint.cols, Paint.rows) / 20; + //TextRendererZH textPainter2(Paint.cols, Paint.rows, rate); + //textPainter2.putText(Paint, "获取图像时间:" + currentimenow.toString().toStdString(), cv::Point(50, Paint.rows-rate), cv::Scalar(0, 255, 255)); + //textPainter2.putText(Paint, "SN条码:" + data->SNcode, cv::Point(50, Paint.rows - (rate*2), cv::Scalar(0, 255, 255)); + + data->insertResultImg(Paint); + + return true; + } + CATCH_EXCEPTIONS + exceptionResume(data, address, "异常"); +} + +bool aiEvaluate(std::shared_ptr data, cv::Mat& input,cv::Mat& Paint,cv::Point center,int index, mfd_hh_models* models,cv::Size fillter) { + try { + HDevEngineCpp::HDevProcedure proc("Crop_Inspection_Image"); + HalconCpp::HObject in_Image_2D = MatToHObject(input); + HDevProcedureCall procedureCall(proc); + procedureCall.SetInputIconicParamObject("in_Image", in_Image_2D); + procedureCall.SetInputCtrlParamTuple("in_CropType", 0); + procedureCall.SetInputCtrlParamTuple("in_FilePath", "./halconFiles/mfd_hh_cut/"); + procedureCall.Execute(); + HObject out_InspectionImage = procedureCall.GetOutputIconicParamObject("out_InspectionImage"); + HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + cv::Mat forSeg = HObject2Mat(out_InspectionImage); + forSeg(cv::Rect(center.x - 650, center.y - 650, 1300, 1300)).copyTo(forSeg); + cv::resize(forSeg, forSeg, cv::Size(), 0.5, 0.5); + data->insertSegOriginImg(forSeg); + cv::Mat segResult = ~models->seg_hanHou->Evaluate(forSeg); + std::vector>contours;//点集 + cv::findContours(segResult, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); // 寻找白色区域并储存为点集 + std::vector> clsImgs; + bool isNg = false; + TextRendererZH textPainter(Paint.cols, Paint.rows, 20); + for (int i = 0; i < contours.size(); i++) {//遍历点集 + cv::Rect rect = cv::boundingRect(contours[i]);//最小外接矩形 + + if (rect.height > fillter.height || rect.width > fillter.width) {// 过滤 只有都大于10像素才进检测 + cv::Mat clsImg = cutImg2Cls(rect, forSeg); + int clsResult = models->cls_hanHou->Evaluate(clsImg); + double prob = models->cls_hanHou->getProbability(); + clsImgs.push_back({ "Result" + std::to_string(clsResult) + "_prob" + std::to_string(prob),clsImg }); + if (clsResult != 0 && prob > 0.6) { + cv::drawContours(Paint, contours, i, cv::Scalar(0, 0, 255), 3, 8, cv::noArray(), INT_MAX, cv::Point(center.x - 650, center.y - 650)); + std::string text; + switch (clsResult) + { + case 1: + text = "焊渣"; + break; + case 2: + text = "裂纹"; + break; + case 3: + text = "炸焊"; + break; + case 4: + text = "焊烟"; + break; + } + textPainter.putText(Paint, text, cv::Point(center.x - 650, center.y - 800), cv::Scalar(0, 0, 255)); + isNg = true; + } + } + } + data->insertClsOriginImg(clsImgs); + return isNg; + } + CATCH_EXCEPTIONS + return false; + +} +static bool HanHou2D(std::shared_ptr data, mfdHanHouParam* _detParams, yh_581_address address) { + cv::Mat segResult; + cv::Mat heightImg; + data->SNcode += "_" + std::to_string(address.index); + try { + if (data->getOriImgSize() < 1) { + qCritical() << "图片数量不满足要求:" << data->getOriImgSize(); + return false; + } + cv::Mat Paint; + cv::Mat src1 = data->getOriImg(0); + //src1 = cv::imread("D:\\test\\04QCB82602000JFCD00776BN_Camera7_0_04-56-43.bmp", -1); + //处理算法 +#pragma region halcon处理 + cv::Mat forHalcon; + cv::resize(src1, forHalcon, cv::Size(), 0.5, 0.5); + if (forHalcon.channels() != 3) + cv::cvtColor(forHalcon, Paint, cv::COLOR_GRAY2BGR); + else + forHalcon.copyTo(Paint); + segResult = _detParams->models[address.index].seg_hanHouDingWei->Evaluate(forHalcon); + data->insertSegOriginImg(segResult); + _detParams->waitImage(heightImg); + HDevEngineCpp::HDevProcedure proc("Cal_2D_3D_PostWelding"); + HDevProcedureCall procedureCall(proc); + + HalconCpp::HObject in_Image_2D = MatToHObject(forHalcon); + HalconCpp::HObject in_Image3DH = MatToHObject(heightImg); + HalconCpp::HObject in_Image_seg = MatToHObject(segResult); + + procedureCall.SetInputIconicParamObject("in_Image_2D", in_Image_2D); + procedureCall.SetInputIconicParamObject("in_Image3DH", in_Image3DH); + procedureCall.SetInputIconicParamObject("in_Image_seg", in_Image_seg); + + procedureCall.SetInputCtrlParamTuple("in_xResolution", HTuple(0.0069699)); + procedureCall.SetInputCtrlParamTuple("in_yResolution", HTuple(0.0069699)); + procedureCall.SetInputCtrlParamTuple("in_zResolution", HTuple(0.0069699)); + procedureCall.SetInputCtrlParamTuple("in_FilePath", "./halconFiles/mfd_hh/"); + procedureCall.SetInputCtrlParamTuple("in_2D_pix", HTuple(0.0069699)); + procedureCall.SetInputCtrlParamTuple("in_Fixture_Number", 1); + HTuple OffsetValue; + for (int i = 0; i < 8; i++) + OffsetValue.Append(0); + procedureCall.SetInputCtrlParamTuple("in_offsetValue", OffsetValue); + procedureCall.Execute(); + + HTuple out_CC_Distance = procedureCall.GetOutputCtrlParamTuple("out_CC_Distance"); + HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle"); + HTuple out_DefectHeight = procedureCall.GetOutputCtrlParamTuple("out_DefectHeight"); + HTuple Out_Angle = procedureCall.GetOutputCtrlParamTuple("Out_Angle"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); +#pragma endregion + int outFlag = out_Flag.D(); + QByteArray plcResult = "1"; + TextRendererZH textPainter(Paint.cols, Paint.rows, 100); + if (outFlag == 1) { //-1为失败,无结果 + cv::Mat forHanddleAi; + double CC_Distance = out_CC_Distance.D(); + cv::Point2f center1(out_Circle[1].D(), out_Circle[0].D()), center2(out_Circle[4].D(), out_Circle[3].D()); + double radius1 = out_Circle[2].D(), radius2 = out_Circle[5].D(); + double defectHeight = out_DefectHeight.D();//密封钉高度 + double angle = Out_Angle.D();//密封钉角度 + + textPainter.putText(Paint, "密封钉高度:" + std::to_string(defectHeight), cv::Point(50, 0), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "密封钉角度:" + std::to_string(angle), cv::Point(50, 350), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "密封钉同心距:" + std::to_string(CC_Distance), cv::Point(50, 550), cv::Scalar(0, 255, 0)); + bool result = aiEvaluate(data, src1,Paint, center1, address.index, &_detParams->models[address.index], + cv::Size(data->service->_paramSyncManager->get("焊后", "过滤宽(pix)", 50).toDouble(), data->service->_paramSyncManager->get("焊后", "过滤高(pix)", 50).toDouble())); + if (result == false && data->service->_paramSyncManager->get("焊后", "模型判定启用", false).toBool()) + plcResult = "2"; + cv::circle(Paint, center1 / 2, radius1 / 2, cv::Scalar(0, 255, 0), 3); + cv::circle(Paint, center2 / 2, radius2 / 2, cv::Scalar(0, 255, 0), 3); + + } + else { + data->halconOK = false; + textPainter.putText(Paint, "NG", cv::Point(50, 300), cv::Scalar(0, 0, 255)); + + } + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + data->insertResultImg(Paint); + + return true; + } + CATCH_EXCEPTIONS + exceptionResume(data, address, "异常"); +} +static bool HanHou3D(std::shared_ptr data, mfdHanHouParam* _detParams, yh_581_address address) { + try { + data->SNcode += "_" + std::to_string(address.index); + ///////////////////取图//处理////////////////// + //if (data->getOriImgSize() < 1) { + // qCritical() << "图片数量不满足要求:" << data->getOriImgSize(); + // return false; + //} + cv::Mat Paint; + cv::Mat src1 = data->getOriImg(0); + cv::Mat heightImg = data->getOriImg(1); + //heightImg = cv::imread("D:\\test\\04QCB82602000JFCD00776BN_Camera8_1_04-56-43.tiff", -1); + if (heightImg.channels() != 3) + cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); + else + src1.copyTo(Paint); + _detParams->insertImg(heightImg); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + data->insertResultImg(Paint); + + return true; + } + CATCH_EXCEPTIONS + exceptionResume(data, address, "异常"); +} +#pragma endregion +class _581_Mfd : public mission { +public: + _581_Single_triggerTemplate< mfd_detParams> yh_1; + _581_Single_triggerTemplate< mfd_detParams> yh_2; + + _581_Single_triggerTemplate< mfd_detParams> mh_1; + _581_Single_triggerTemplate< mfd_detParams> mh_2; + _581_Single_triggerTemplate< mfd_detParams> mh_3; + _581_Single_triggerTemplate< mfd_detParams> mh_4; + + _581_Union_triggerTemplate< mfdHanHouParam> hh_2D; + _581_Union_triggerTemplate< mfdHanHouParam> hh_3D; + + mfd_detParams _params; + + mfdHanHouParam _hhParams; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + for (auto& model : _hhParams.models) { + model.seg_hanHou = handdleAI::CreateSegObjS("./handleaiModels/seg_hanhou.BHD", 16, 0); + model.cls_hanHou = handdleAI::CreateClsObjV3("./handleaiModels/cls_hanhou.BHD", 0, 1); + model.seg_hanHouDingWei = handdleAI::CreateSegObjS("./handleaiModels/seg_hanhouDingWei.BHD", 16, 0); + } + } + bool initCustom() { +#pragma region 注册触发器回调 + yh_1.init("Camera1", "预焊1", 19600, 2, 1, &_params, _serviceManager, bridge, YuHan, "预焊CCD"); + yh_2.init("Camera2", "预焊2", 19800, 2, 1, &_params, _serviceManager, bridge, YuHan, "预焊CCD"); + + mh_1.init("Camera3", "满焊1", 20000, 2, 1, &_params, _serviceManager, bridge, ManHan, "满焊CCD"); + mh_2.init("Camera4", "满焊2", 20200, 2, 1, &_params, _serviceManager, bridge, ManHan, "满焊CCD"); + mh_3.init("Camera5", "满焊3", 20400, 2, 1, &_params, _serviceManager, bridge, ManHan, "满焊CCD"); + mh_4.init("Camera6", "满焊4", 20600, 2, 1, &_params, _serviceManager, bridge, ManHan, "满焊CCD"); + + hh_2D.init("Camera7", "焊后2d", 20800, 4, 1, &_hhParams, _serviceManager, bridge, HanHou2D, "焊后CCD"); + hh_3D.init("Camera8", "焊后3d", 21000, 4, 1, &_hhParams, _serviceManager, bridge, HanHou3D, "焊后CCD"); +#pragma endregion + return true; + } + + + //9600 + +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/602/YH/581_YuHan_hanhou/CMakeLists.txt b/src/mission/581-Mfd_yh_mh_hh/CMakeLists.txt similarity index 91% rename from src/mission/602/YH/581_YuHan_hanhou/CMakeLists.txt rename to src/mission/581-Mfd_yh_mh_hh/CMakeLists.txt index 76e9200..599e8f5 100644 --- a/src/mission/602/YH/581_YuHan_hanhou/CMakeLists.txt +++ b/src/mission/581-Mfd_yh_mh_hh/CMakeLists.txt @@ -40,8 +40,8 @@ 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) +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} @@ -64,6 +64,7 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql ) diff --git a/src/mission/581_Ruanlianjie_dianjiao_tiejiao/581_Ruanlianjie_dianjiao_tiejiao.cpp b/src/mission/581_Ruanlianjie_dianjiao_tiejiao/581_Ruanlianjie_dianjiao_tiejiao.cpp new file mode 100644 index 0000000..16b2ff7 --- /dev/null +++ b/src/mission/581_Ruanlianjie_dianjiao_tiejiao/581_Ruanlianjie_dianjiao_tiejiao.cpp @@ -0,0 +1,339 @@ +#include <581_Ruanlianjie_dianjiao_tiejiao.h> +#include +QByteArray getCameraIndex(QString cameraStr) { + QRegularExpression re("\\d+"); + auto match = re.match(cameraStr); + if (match.hasMatch()) { + return "_" + match.captured(0).toLocal8Bit(); + } + return "_-2"; +} +void exceptionResume(std::shared_ptr data, tieJiaoParams* _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); + //if (data->service->_paramSyncManager->get("通用设置","强制OK", false).toBool() == true) + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + //else + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//结果反馈 +} +void exceptionResume(std::shared_ptr data, dianJiaoParams* _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); + //if (data->service->_paramSyncManager->get("通用设置" ,"强制OK", false).toBool() == true) + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1_4");//结果反馈 + //else + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//结果反馈 +} +QByteArray halconAsyncFuncGlueArea(TextRendererZH* render,std::shared_ptr data,cv::Mat& Paint, cv::Mat& sourceImg, double Resolution, std::string ProductType,double areaOffset = 0) { + double areaNgRate = data->service->_paramSyncManager->get("点胶设置","胶体比例最小阈值(%)", 90.0).toDouble(); + double areaNgEnable = data->service->_paramSyncManager->get("点胶设置","胶体比例判定启用", true).toBool(); + HDevEngineCpp::HDevProcedure proc("_3_Inspection_Glue"); + HDevEngineCpp::HDevProcedureCall procedureCall(proc); + //sourceImg(cv::Rect(0, 700, sourceImg.cols, sourceImg.rows - 1400)).copyTo(Paint); + sourceImg.copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + HObject in_Image = MatToHObject(sourceImg); + HalconCpp::HTuple in_Resolution(Resolution), in_FilePath("./halconFiles/"); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); + procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.SetInputCtrlParamTuple("in_ProductType", ProductType.c_str()); + procedureCall.Execute(); + HalconCpp::HTuple out_Circle, out_GlueArea, out_X, out_Y, out_Flag, out_Ratio, out_NgTails; + out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");//获取输出控制类变量 + out_GlueArea = procedureCall.GetOutputCtrlParamTuple("out_GlueArea");//获取输出控制类变量 + out_X = procedureCall.GetOutputCtrlParamTuple("out_X");//获取输出控制类变量 + out_Y = procedureCall.GetOutputCtrlParamTuple("out_Y");//获取输出控制类变量 + out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 + out_Ratio = procedureCall.GetOutputCtrlParamTuple("out_Ratio");//获取输出控制类变量 + out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails");//获取输出控制类变量 + + QByteArray AreaResult = "1"; + if (out_Flag.D() == 1) + { + int offsetY = 0; + cv::Point circleCenter(out_Circle[1].D(), out_Circle[0].D() - offsetY); + double radius = out_Circle[2].D(); + int glueArea = out_GlueArea.D(); + double rate = out_Ratio.D() + areaOffset; + rate = std::min(rate, 1.0); + render->appendPaintJob(circleCenter, radius, cv::Scalar(0, 0, 255), 3,1); + + //cv::Point gluePos(out_X.D(), out_Y[0].D()); + for (int i = 0; i < out_X.Length() || i < out_Y.Length(); i++) + render->appendPaintJob(cv::Point(out_X[i].D(), out_Y[i].D() - offsetY),(0, 0, 255)); + render->appendPaintJob("胶体面积:" + std::to_string(glueArea * Resolution * Resolution) + "mm²", cv::Point(0, 150), cv::Scalar(0, 255, 0)); + if (rate * 100 > areaNgRate) { + render->appendPaintJob("胶体比例:" + std::to_string(rate * 100) + "%", cv::Point(0, 450), cv::Scalar(0, 255, 0)); + } + else{ + render->appendPaintJob("胶体比例:" + std::to_string(rate * 100) + "%", cv::Point(0, 450), cv::Scalar(0, 0, 255)); + data->halconOK = false; + if(areaNgEnable == true) + AreaResult = "2"; + } + } + else + { + TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + textPainter.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); + textPainter.putText(Paint, gbkToUtf8(out_NgTails.ToString().Text()), cv::Point(0, 550), cv::Scalar(0, 0, 255)); + if (areaNgEnable == true) + AreaResult = "2"; + data->halconOK = false; + } + return AreaResult; +} +QByteArray halconAsyncFuncGlueHeight(std::shared_ptr data,cv::Mat& Paint, cv::Mat& lastImg, cv::Mat& sourceImg, double Resolution) { + HDevEngineCpp::HDevProcedure proc("Cal_Glue_Height_3_2");; + HDevEngineCpp::HDevProcedureCall procedureCall(proc); + lastImg(cv::Rect(0, 700, sourceImg.cols, sourceImg.rows - 1400)).copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + HObject in_Image1 = MatToHObject(lastImg); + HObject in_Image2 = MatToHObject(sourceImg); + HalconCpp::HTuple in_Resolution(Resolution); + procedureCall.SetInputIconicParamObject("in_Image1", in_Image2); + procedureCall.SetInputIconicParamObject("in_Image2", in_Image1); + procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); + procedureCall.Execute();//执行halcon程序 + HalconCpp::HTuple out_LinePoint, out_Rows, out_Cols, out_Height, out_Flag; + out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 + out_Rows = procedureCall.GetOutputCtrlParamTuple("out_Rows");//获取输出控制类变量 + out_Cols = procedureCall.GetOutputCtrlParamTuple("out_Cols");//获取输出控制类变量 + out_Height = procedureCall.GetOutputCtrlParamTuple("out_Height");//获取输出控制类变量 + out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 + + QByteArray plcResult = "1"; + if (out_Flag.D() == 1) + { + int offsetY = 700; + cv::Point p1 = cv::Point(out_LinePoint[1].D(), out_LinePoint[0].D() - offsetY); + cv::Point p2 = cv::Point(out_LinePoint[3].D(), out_LinePoint[2].D() - offsetY); + cv::line(Paint, p1, p2, cv::Scalar(0, 255, 0), 5); + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, "胶体高于基准面的距离:" + std::to_string(out_Height[0].D()), cv::Point(0, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "胶体低于基准面的距离:" + std::to_string(out_Height[1].D()), cv::Point(0, 350), cv::Scalar(0, 255, 0)); + for (int i = 0; i < out_Rows.Length(); i++) + Cross(Paint, cv::Point(out_Cols[i].D(), out_Rows[i].D() - offsetY), 5, 3, cv::Scalar(0, 255, 0)); + plcResult = "1"; + } + else + { + TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + textPainter.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); + plcResult = "1"; + } + return plcResult; +} +bool DianJiaoJianCe(std::shared_ptr data, dianJiaoParams* _detParams, sx_581_address address){ + try + { + data->service->_triggerManager->sequentialWriteShort({ "D999_1","D998_1","D997_1" }); + //data->service->_triggerManager->writeShort("D100_123_1"); + //data->getOriImg(0) = cv::imread("D:/T.bmp",-1); + cv::Mat sourceImg; + if (data->getOriImg(0).rows == 200) { + exceptionResume(data, _detParams, address, "取图超时"); + return true; + } + //data->getOriImg(0)(cv::Rect(1310, 450, 3144, 2776)).copyTo(sourceImg); + cv::imread("D:/T.bmp", -1)(cv::Rect(1310, 450, 3144, 2776)).copyTo(sourceImg); + if (address.triggerAddr == 610 || address.triggerAddr == 710) + cv::rotate(sourceImg, sourceImg, cv::ROTATE_180); + cv::Mat Paint = sourceImg.clone(); + + QByteArray plcResult = "1"; + qDebug() << "algo start" << address.triggerAddr; + + double Resolution = 0.014901; + + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + double offsetArea = 0; + /* if (address.triggerAddr == 110 || address.triggerAddr == 210) + offsetArea = 0.1 ;*/ + if (address.triggerValue == 2) { + //检测胶 + plcResult = halconAsyncFuncGlueArea(&textPainter,data, Paint, sourceImg, Resolution, "CU", offsetArea); + textPainter.appendPaintJob( std::to_string(address.triggerAddr) + "_" + std::to_string(address.triggerValue), cv::Point(100, 2000), cv::Scalar(0, 255, 0)); + + } + else if (address.triggerValue == 4) { + //检测胶 + plcResult = halconAsyncFuncGlueArea(&textPainter,data, Paint, sourceImg, Resolution, "AL", offsetArea); + textPainter.appendPaintJob(std::to_string(address.triggerAddr) + "_" + std::to_string(address.triggerValue), cv::Point(100, 2000), cv::Scalar(0, 255, 0)); + } + + if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool())//如果总强制开启使用总强制 + plcResult = "1"; + else if (data->service->_paramSyncManager->get("点胶设置", "点胶检测强制OK", false).toBool())//否则使用下级强制 + plcResult = "1"; + + QByteArray cameraThreadStr = getCameraIndex(QString::fromStdString(data->cameraKeyName)); + if (address.triggerValue == 2) {//第一/三次的结果需要缓存 + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.resultAddr.toInt() + 1) + "_" + _detParams->cacheResult + cameraThreadStr); + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.resultAddr.toInt() + 2) + "_" + plcResult + cameraThreadStr); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + QByteArray(_detParams->lastResultIsNg == true || plcResult == "2" ? "2" : "1") + cameraThreadStr); + + _detParams->batteryIsNg = (_detParams->lastResultIsNg == true || plcResult == "2"); + _detParams->lastResultIsNg = false; + + textPainter.excusePaintJobs(Paint); + Paint.copyTo(_detParams->lastDetImg); + } + else if (address.triggerValue == 4) { + + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.resultAddr.toInt() + 3) + "_" + _detParams->cacheResult + cameraThreadStr); + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.resultAddr.toInt() + 4) + "_" + plcResult + cameraThreadStr); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + QByteArray(_detParams->lastResultIsNg == true || plcResult == "2"?"2":"1") + cameraThreadStr); + if (_detParams->batteryIsNg == true) + data->halconOK = false; + + _detParams->lastResultIsNg = false; + _detParams->batteryIsNg = false; + + textPainter.excusePaintJobs(Paint); + if (_detParams->lastDetImg.empty() == false) + cv::hconcat(_detParams->lastDetImg, Paint, Paint); + data->insertResultImg(Paint); + } + else { + _detParams->cacheResult = plcResult; + _detParams->lastResultIsNg = (plcResult == "2"); + } + + + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_1" + cameraThreadStr); + + qDebug() << "algo stop" << address.triggerAddr; + sourceImg.release(); + + + return true; + } + CATCH_EXCEPTIONS + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + exceptionResume(data, _detParams, address, "检测失败"); + return false; + +} + +bool TieJiaoJianCe(std::shared_ptr data, tieJiaoParams* _detParams, sx_581_address address) { + try { + + cv::Mat sourceImg = data->getOriImg(0); + if(address.triggerValue == 1 || address.triggerValue == 3) + sourceImg = cv::imread("D:\\testimg\\T_TJ_NG.bmp", -1); + else if(address.triggerValue == 2 || address.triggerValue == 4) + sourceImg = cv::imread("D:\\testimg\\L_TJ_OK.bmp", -1); + if (address.triggerAddr == 810) + cv::rotate(sourceImg, sourceImg, cv::ROTATE_180); + + int start = clock(); + HDevEngineCpp::HDevProcedure proc("_3_Inspection_GlueCover"); + HDevEngineCpp::HDevProcedureCall procedureCall(proc); + + cv::Mat Paint; + sourceImg.copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + + TextRendererZH textPainter(Paint.cols, Paint.rows, 800); + TextRendererZH textPainter2(Paint.cols, Paint.rows, 400); + if ((address.triggerAddr == 310 && (address.triggerValue == 1 || address.triggerValue == 3))|| + (address.triggerAddr == 810 && (address.triggerValue == 1 || address.triggerValue == 3))) { + _detParams->productType = "CU"; + textPainter2.appendPaintJob("铜", cv::Point(10, 900), cv::Scalar(0, 255, 0)); + } + else { + _detParams->productType = "LV"; + textPainter2.appendPaintJob("铝", cv::Point(10, 900), cv::Scalar(0, 255, 0)); + } + + HObject in_Image = MatToHObject(sourceImg); + HalconCpp::HTuple in_ProductType = _detParams->productType.toStdString().c_str(); + HalconCpp::HTuple in_FilePath("./halconFiles/"); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.SetInputCtrlParamTuple("in_ProductType", in_ProductType); + procedureCall.Execute();//执行halcon程序 + HalconCpp::HTuple out_LinePoint, out_NgTails, out_Flag; + out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 + out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails");//获取输出控制类变量 + out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 + int flag = out_Flag.D(); + QByteArray plcResult = "1"; + + if (flag == 1) { + for (auto i = 0; i < 4; i++) { + textPainter2.appendPaintJob( + cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4].D()), + cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), + cv::Scalar(0, 255, 0), 5); + } + textPainter.appendPaintJob("OK", cv::Point(10, 100), cv::Scalar(0, 255, 0)); + } + else { + data->halconOK = false; + std::string ngTails = out_NgTails.ToString().Text(); + textPainter.appendPaintJob("NG", cv::Point(10, 100), cv::Scalar(0, 0, 255)); + textPainter2.appendPaintJob(gbkToUtf8(ngTails), cv::Point(10, 800), cv::Scalar(0, 0, 255)); + if (data->service->_paramSyncManager->get("贴胶", "贴胶判定启用", false).toBool()) + plcResult = "2"; + } + + + if (data->service->_paramSyncManager->get("通用设置","强制OK", false).toBool()) + plcResult = "1"; + + QByteArray cameraThreadStr = getCameraIndex(QString::fromStdString(data->cameraKeyName)); + if (address.triggerValue == 2) { + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.resultAddr.toInt() + 1) + QByteArray(_detParams->lastResultIsNg == true ? "_2" : "_1") + cameraThreadStr); + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.resultAddr.toInt() + 2) + "_" + plcResult + cameraThreadStr); + data->service->_triggerManager->writeShort("D" + address.resultAddr + QByteArray(_detParams->lastResultIsNg == true || plcResult == "2" ? "_2" : "_1") + cameraThreadStr); + _detParams->lastResultIsNg = false; + } + else if (address.triggerValue == 4) { + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.resultAddr.toInt() + 3) + QByteArray(_detParams->lastResultIsNg == true ? "_2" : "_1") + cameraThreadStr); + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.resultAddr.toInt() + 4) + "_" + plcResult + cameraThreadStr); + data->service->_triggerManager->writeShort("D" + address.resultAddr + QByteArray(_detParams->lastResultIsNg == true || plcResult == "2" ? "_2" : "_1") + cameraThreadStr); + _detParams->lastResultIsNg = false; + } + else { + if (plcResult == "2") + _detParams->lastResultIsNg = true; + } + textPainter.excusePaintJobs(Paint); + textPainter2.excusePaintJobs(Paint); + data->insertResultImg(Paint); + return true; + } + CATCH_EXCEPTIONS + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + exceptionResume(data, _detParams, address, "检测失败"); + return false; +} + +mission* createMission() { + return new _581_Ruanlianjie_dianjiao_tiejiao(); +} +void destroyMission(mission* _mission) { + delete _mission; +} diff --git a/src/mission/581_Ruanlianjie_dianjiao_tiejiao/581_Ruanlianjie_dianjiao_tiejiao.h b/src/mission/581_Ruanlianjie_dianjiao_tiejiao/581_Ruanlianjie_dianjiao_tiejiao.h new file mode 100644 index 0000000..a563715 --- /dev/null +++ b/src/mission/581_Ruanlianjie_dianjiao_tiejiao/581_Ruanlianjie_dianjiao_tiejiao.h @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace HDevEngineCpp; +using namespace HalconCpp; +class dianJiaoParams { +public: + cv::Mat lastDetImg; + bool lastResultIsNg = false; + QByteArray cacheResult = "1";//第一/三次的结果需要缓存 + bool batteryIsNg = false; +}; +class tieJiaoParams { +public: + QString productType; + bool lastResultIsNg = false; + QByteArray cacheResult = "1";//第一/三次的结果需要缓存 +}; + +bool DianJiaoJianCe(std::shared_ptr data, dianJiaoParams* _detParams, sx_581_address address); +bool TieJiaoJianCe(std::shared_ptr data, tieJiaoParams* _detParams, sx_581_address address); + + + +class _581_Ruanlianjie_dianjiao_tiejiao : public mission { +public: + + _581_SX_Single_triggerTemplate dianjiao_a_hou_1; + _581_SX_Single_triggerTemplate dianjiao_a_qian_2; + _581_SX_Single_triggerTemplate dianjiao_b_hou_3; + _581_SX_Single_triggerTemplate dianjiao_b_qian_4; + + _581_SX_Single_triggerTemplate tiejiao_a_1; + _581_SX_Single_triggerTemplate tiejiao_b_2; + + std::vector _dianJiaoParams = std::vector(4); + tieJiaoParams tieJiaoParams1; + tieJiaoParams tieJiaoParams2; + bool initOnce = false; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath(""); + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + + if (initOnce == false) { + + initOnce = true; + } + } + bool initCustom() { +#pragma region 注册触发器回调 + dianjiao_a_hou_1.init("Camera1", "点胶检测-A通道-相机1(后)", { + { 110, 1,{124},"112","160",170}, + { 110, 2,{124},"112","160",170}, + { 110, 3,{124},"112","160",170}, + { 110, 4,{124},"112","160",170} }, 1, & _dianJiaoParams[0], _serviceManager, bridge, DianJiaoJianCe, "点胶检测CCD"); + dianjiao_a_qian_2.init("Camera2", "点胶检测-A通道-相机2(前)", { + { 210, 1,{224},"212","260",270}, + { 210, 2,{224},"212","260",270}, + { 210, 3,{224},"212","260",270}, + { 210, 4,{224},"212","260",270} }, 1, & _dianJiaoParams[1], _serviceManager, bridge, DianJiaoJianCe,"点胶检测CCD"); + dianjiao_b_hou_3.init("Camera3", "点胶检测-B通道-相机3(后)", { + { 610, 1,{624},"612","660",670}, + { 610, 2,{624},"612","660",670}, + { 610, 3,{624},"612","660",670}, + { 610, 4,{624},"612","660",670} }, 1, & _dianJiaoParams[2], _serviceManager, bridge, DianJiaoJianCe, "点胶检测CCD"); + dianjiao_b_qian_4.init("Camera4", "点胶检测-B通道-相机4(前)", { + { 710, 1,{724},"712","760",770}, + { 710, 2,{724},"712","760",770}, + { 710, 3,{724},"712","760",770}, + { 710, 4,{724},"712","760",770} }, 1, & _dianJiaoParams[3], _serviceManager, bridge, DianJiaoJianCe,"点胶检测CCD"); + + tiejiao_a_1.init("Camera5", "贴胶检测-A通道-相机1", { + { 310, 1,{324},"312","360",370}, + { 310, 2,{324},"312","360",370}, + { 310, 3,{324},"312","360",370}, + { 310, 4,{324},"312","360",370} }, 1, &tieJiaoParams1, _serviceManager, bridge, TieJiaoJianCe, "贴胶检测CCD"); + tiejiao_b_2.init("Camera6", "贴胶检测-B通道-相机2", { + { 810, 1,{824},"812","860",870}, + { 810, 2,{824},"812","860",870} , + { 810, 3,{824},"812","860",870} , + { 810, 4,{824},"812","860",870} }, 1, &tieJiaoParams2, _serviceManager, bridge, TieJiaoJianCe,"贴胶检测CCD"); +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/602/581_Ruanlianjie_hanqian_hanhou/CMakeLists.txt b/src/mission/581_Ruanlianjie_dianjiao_tiejiao/CMakeLists.txt similarity index 100% rename from src/mission/602/581_Ruanlianjie_hanqian_hanhou/CMakeLists.txt rename to src/mission/581_Ruanlianjie_dianjiao_tiejiao/CMakeLists.txt diff --git a/src/mission/602/ZH/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.cpp b/src/mission/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.cpp similarity index 100% rename from src/mission/602/ZH/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.cpp rename to src/mission/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.cpp diff --git a/src/mission/602/ZH/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h b/src/mission/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h similarity index 55% rename from src/mission/602/ZH/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h rename to src/mission/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h index b938bf5..f813795 100644 --- a/src/mission/602/ZH/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h +++ b/src/mission/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h @@ -6,12 +6,21 @@ #include using namespace HDevEngineCpp; #pragma endregion +struct halconResult { + bool isNG = false; + double upResult = 0.0; + double downResult = 0.0; +}; class zhongHanFanMianTeJiaoParams { public: bool isTong = true; std::string in_Product_Str = "Cu"; }; +void putSnAndDetTime(cv::Mat& Paint, const std::string& sn, int textSize = 30, const std::string& extraText = "") { + TextRendererZH textPainter(Paint.cols, Paint.rows, textSize); + textPainter.putText(Paint, "SN:" + sn + QDateTime::currentDateTime().toString().toStdString() + extraText, cv::Point(0, Paint.rows - textSize), cv::Scalar(0, 255, 0)); +} void GetStringSize(HDC hdc, const char* str, int* w, int* h) { SIZE size; @@ -28,24 +37,20 @@ void DrawRotatedRect2Mat(cv::Mat& img, cv::RotatedRect rotateRect, cv::Scalar co } } -bool halconProcess(cv::Mat& sourceImg, cv::Mat& Paint,std::string produce,const std::string& cameraKeyName) { +//画在结果图上时缩小1/2 +halconResult halconProcess(cv::Mat& sourceImg, TextRendererZH* textPainter, const std::string produce,const std::string& cameraKeyName) { + halconResult result; try { HDevEngineCpp::HDevProcedure proc("_3_Neg_CoverGlue_Inspection"); HDevEngineCpp::HDevProcedureCall procedureCall(proc); - HalconCpp::HObject in_Image;//原始三通道图像 - HalconCpp::HTuple in_Product = HalconCpp::HTuple((char*)produce.c_str());//产品类别, 'Gu':铜 'Al':铝 - HalconCpp::HTuple in_LineType = "602";//线体类别 - HalconCpp::HTuple in_Resolution(0.0192118);//相机精度(mm/pix) - HalconCpp::HTuple in_FilePath(std::string("./halconFiles/ZH_TieJiao_Down/"+ cameraKeyName +"/").c_str());//模板文件路径 - - in_Image = MatToHObject(sourceImg); + HalconCpp::HObject in_Image = MatToHObject(sourceImg); procedureCall.SetInputIconicParamObject("in_Image", in_Image); - procedureCall.SetInputCtrlParamTuple("in_Product", in_Product); - procedureCall.SetInputCtrlParamTuple("in_LineType", in_LineType); - procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); - procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.SetInputCtrlParamTuple("in_Product", produce.c_str()); + procedureCall.SetInputCtrlParamTuple("in_LineType", "602"); + procedureCall.SetInputCtrlParamTuple("in_Resolution", 0.0192118); + procedureCall.SetInputCtrlParamTuple("in_FilePath", ("./halconFiles/ZH_TieJiao_Down/" + cameraKeyName + "/").c_str()); procedureCall.Execute();//执行halcon程序 HalconCpp::HTuple out_Circle;//焊印圆中心坐标(y,x,R) @@ -62,49 +67,45 @@ bool halconProcess(cv::Mat& sourceImg, cv::Mat& Paint,std::string produce,const out_Rectangle = procedureCall.GetOutputCtrlParamTuple("out_Rectangle"); out_NGTails = procedureCall.GetOutputCtrlParamTuple("out_NGTails"); out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); - TextRendererZH textPainter(Paint.cols, Paint.rows, 300); if (out_Flag.D() == 1) { int out_Distanc_Size = out_Distance.Length(); if (out_Distance.Length() > 1) { double distance1 = out_Distance[0].D(); + result.upResult = distance1; if (distance1 <= 12) {//NG - textPainter.putText(Paint, - ("连接片的中心到上极耳胶纸的距离:" + QByteArray::number(distance1) + "mm").toStdString().c_str(), - cv::Point(0, 600), cv::Scalar(0, 255, 0)); + textPainter->appendPaintJob(("连接片的中心到上极耳胶纸的距离:" + QByteArray::number(distance1) + "mm").toStdString().c_str(), + cv::Point(0, 200), cv::Scalar(0, 255, 0)); } else { - textPainter.putText(Paint, - ("连接片的中心到上极耳胶纸的距离:" + QByteArray::number(distance1) + "mm").toStdString().c_str(), - cv::Point(0, 600), cv::Scalar(0, 255, 0)); + textPainter->appendPaintJob(("连接片的中心到上极耳胶纸的距离:" + QByteArray::number(distance1) + "mm").toStdString().c_str(), + cv::Point(0, 200), cv::Scalar(0, 255, 0)); } double distance2 = out_Distance[1].D(); + result.downResult = distance2; if (distance2 <= 12) {//NG - textPainter.putText(Paint, - ("连接片的中心到下极耳胶纸的距离:" + QByteArray::number(distance2) + "mm").toStdString().c_str(), - cv::Point(0, 1050), cv::Scalar(0, 255, 0)); + textPainter->appendPaintJob(("连接片的中心到下极耳胶纸的距离:" + QByteArray::number(distance2) + "mm").toStdString().c_str(), + cv::Point(0, 400), cv::Scalar(0, 255, 0)); } else { - textPainter.putText(Paint, - ("连接片的中心到下极耳胶纸的距离:" + QByteArray::number(distance2) + "mm").toStdString().c_str(), - cv::Point(0, 1050), cv::Scalar(0, 255, 0)); + textPainter->appendPaintJob(("连接片的中心到下极耳胶纸的距离:" + QByteArray::number(distance2) + "mm").toStdString().c_str(), + cv::Point(0, 400), cv::Scalar(0, 255, 0)); } } //画圆心十字 - cv::drawMarker(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), cv::Scalar(0, 255, 0), cv::MARKER_CROSS, 200, 5); + textPainter->appendPaintJob(cv::Point(out_Circle[1].D(), out_Circle[0].D()) / 2, 100, cv::Scalar(0, 255, 0), 5, 1); //画圆 - cv::circle(Paint, - cv::Point(out_Circle[1].D(), out_Circle[0].D()), - out_Circle[2].D(), cv::Scalar(0, 255, 0), 5); + textPainter->appendPaintJob(cv::Point(out_Circle[1].D(), out_Circle[0].D()) / 2, + out_Circle[2].D() / 2, cv::Scalar(0, 255, 0), 5, 0); //画线 if (out_LinePoint.Length() > 3) { for (int i = 0; i < out_LinePoint.Length() / 4; i++) { - cv::line(Paint, - cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4 + 0].D()), - cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), + textPainter->appendPaintJob( + cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4 + 0].D()) / 2, + cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()) / 2, cv::Scalar(0, 255, 0), 5); } } @@ -112,28 +113,29 @@ bool halconProcess(cv::Mat& sourceImg, cv::Mat& Paint,std::string produce,const //画矩形 if (out_Rectangle.Length() > 4) { for (int j = 0; j < out_Rectangle.Length() / 5; j++) { - cv::RotatedRect rRect; - rRect.center.y = out_Rectangle[j * 5 + 0].D(); - rRect.center.x = out_Rectangle[j * 5 + 1].D(); - rRect.angle = out_Rectangle[j * 5 + 2].D(); - rRect.size.width = out_Rectangle[j * 5 + 3].D(); - rRect.size.height = out_Rectangle[j * 5 + 4].D(); + cv::Rect rRect; + rRect.y = out_Rectangle[j * 5 + 0].D() / 2; + rRect.x = out_Rectangle[j * 5 + 1].D() / 2; + rRect.width = out_Rectangle[j * 5 + 3].D() / 2; + rRect.height = out_Rectangle[j * 5 + 4].D() / 2; - DrawRotatedRect2Mat(Paint, rRect, cv::Scalar(0, 255, 0), 3, cv::LINE_4); + textPainter->appendPaintJob(rRect, cv::Scalar(0, 255, 0), 3); } } } else { std::string NgTails = out_NGTails.S().Text();//NG明细 - textPainter.putText(Paint, NgTails.c_str(), cv::Point(0, 550), cv::Scalar(0, 255, 255)); + textPainter->appendPaintJob(NgTails.c_str(), cv::Point(0, 260), cv::Scalar(0, 255, 255)); } if (out_Flag.D() == 1) { - textPainter.putText(Paint,"OK", cv::Point(0, 50), cv::Scalar(0, 255, 0)); - return false; + textPainter->appendPaintJob("OK", cv::Point(0, 0), cv::Scalar(0, 255, 0)); + result.isNG = false; + return result; } else { - textPainter.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); - return true; + textPainter->appendPaintJob("NG", cv::Point(0, 0), cv::Scalar(0, 0, 255)); + result.isNG = true; + return result; } } @@ -151,73 +153,53 @@ bool halconProcess(cv::Mat& sourceImg, cv::Mat& Paint,std::string produce,const qDebug() << "Error Code: " << ex.ErrorCode(); \ qDebug() << "Error Message: " << ex.ErrorMessage(); \ } + result.isNG = true; + return result; } bool dibutiejiao_90(std::shared_ptr data, zhongHanFanMianTeJiaoParams* _detParams, sx_581_address address) { try{ -#if 0 - /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ - cv::Mat resultImage = img2D.clone(); - if (resultImage.channels() == 1) { - cv::cvtColor(resultImage, resultImage, cv::COLOR_GRAY2BGR); - } - QString okng_tag = "OK"; - cv::Mat seg_detectImage; - cv::resize(img2D, seg_detectImage, cv::Size(), 1, 1); - plcResult = "1"; - bool isNG = false; - if (DOGLIVE) { - std::vector>clsImgs; - bool isNG = handleAiProcess(seg_detectImage, resultImage, seg_jierFanZhe, cls_jierFanZhe, clsImgs); - for (int i = 0; i < clsImgs.size(); i++) { - addImgToSaveStruct(clsImgs[i].second, "0", getClsSaveFormat(SN, okng_tag, i, clsImgs[i].first)); - } - } - if (isNG == false)//OK - { - putTextHusky(resultImage, utf8_to_gbk("OK").c_str(), cv::Point(50, 50), cv::Scalar(0, 255, 0), 200); - okng_tag = "OK"; - } - else - { - putTextHusky(resultImage, utf8_to_gbk("NG").c_str(), cv::Point(50, 50), cv::Scalar(0, 0, 255), 200); - plcResult = "2"; - } - cv::resize(resultImage, resultImage, cv::Size(), 0.5, 0.5); - resMat.push_back(resultImage); - if (resMat.size() > 0) - { - addImgToSaveStruct(seg_detectImage, "0", getSegSaveFormat(SN, okng_tag));//存seg图 - addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, okng_tag));//存结果图 - } - addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okng_tag));//存原图图 - - return true; - /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ -#else //存图数据加保存队列,加锁,避免数据访问冲突 QByteArray plcResult = "1"; - cv::Mat sourceImg; - data->getOriImg(0).copyTo(sourceImg); + cv::Mat sourceImg = data->getOriImg(0); + std::vector defects; cv::Mat Paint; if (_detParams->in_Product_Str == "Cu") { cv::rotate(sourceImg, sourceImg, cv::ROTATE_180);//为保证算法一致, } - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) + + if (Paint.channels() == 1) { cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - bool isNG = halconProcess(sourceImg, Paint, _detParams->in_Product_Str,data->cameraKeyName); - TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - if (isNG == true){//OK + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + } + else + cv::resize(sourceImg, Paint, cv::Size(), 0.5, 0.5); + TextRendererZH textPainter(Paint.cols, Paint.rows, 150); + halconResult result = halconProcess(sourceImg, &textPainter, _detParams->in_Product_Str,data->cameraKeyName); + + if (result.isNG == true){//NG data->halconOK = false; plcResult = "2"; + defects.push_back("底部贴胶NG"); } if (!data->service->_paramSyncManager->get("底部贴胶","底部贴胶判定启用", true).toBool()) plcResult = "1";//强制OK - data->insertResultImg(Paint); - sourceImg.release(); + + +#pragma region 发送位置判断结果 + if (data->cameraKeyName == "Camera1")data->service->_triggerManager->writeShort("D5866_" + plcResult); + else if (data->cameraKeyName == "Camera4")data->service->_triggerManager->writeShort("D5867_" + plcResult); + else if (data->cameraKeyName == "Camera7")data->service->_triggerManager->writeShort("D5868_" + plcResult); + else if (data->cameraKeyName == "Camera10")data->service->_triggerManager->writeShort("D5869_" + plcResult); +#pragma endregion + + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(result.upResult) + "," + QByteArray::number(result.downResult));//结果反馈 data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + + putSnAndDetTime(Paint, data->SNcode, 200); + data->insertResultImg(Paint); + data->service->_missionResultHandle->toBarChart(data->SNcode, defects); return true; -#endif + } CATCH_EXCEPTIONS @@ -270,55 +252,16 @@ bool dibutiejiao_90(std::shared_ptr data, zhongHanFanMianTeJiaoParams* //} bool dibutiejiao_45(std::shared_ptr data, zhongHanFanMianTeJiaoParams* _detParams, sx_581_address address) { try { -#if 0 - /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ - cv::Mat resultImage = img2D.clone(); - if (resultImage.channels() == 1) { - cv::cvtColor(resultImage, resultImage, cv::COLOR_GRAY2BGR); - } - QString okng_tag = "OK"; - cv::Mat seg_detectImage; - cv::resize(img2D, seg_detectImage, cv::Size(), 1, 1); - plcResult = "1"; - bool isNG = false; - if (DOGLIVE) { - std::vector>clsImgs; - bool isNG = handleAiProcess(seg_detectImage, resultImage, seg_jierFanZhe, cls_jierFanZhe, clsImgs); - for (int i = 0; i < clsImgs.size(); i++) { - addImgToSaveStruct(clsImgs[i].second, "0", getClsSaveFormat(SN, okng_tag, i, clsImgs[i].first)); - } - } - if (isNG == false)//OK - { - putTextHusky(resultImage, utf8_to_gbk("OK").c_str(), cv::Point(50, 50), cv::Scalar(0, 255, 0), 200); - okng_tag = "OK"; - } - else - { - putTextHusky(resultImage, utf8_to_gbk("NG").c_str(), cv::Point(50, 50), cv::Scalar(0, 0, 255), 200); - plcResult = "2"; - } - cv::resize(resultImage, resultImage, cv::Size(), 0.5, 0.5); - resMat.push_back(resultImage); - if (resMat.size() > 0) - { - addImgToSaveStruct(seg_detectImage, "0", getSegSaveFormat(SN, okng_tag));//存seg图 - addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, okng_tag));//存结果图 - } - addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okng_tag));//存原图图 - return true; - /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ -#else //存图数据加保存队列,加锁,避免数据访问冲突 QByteArray plcResult = "2"; - cv::Mat sourceImg; - data->getOriImg(0).copyTo(sourceImg); + cv::Mat sourceImg = data->getOriImg(0); cv::Mat Paint; - cv::resize(sourceImg, sourceImg, cv::Size(), 0.5, 0.5); - sourceImg.copyTo(Paint); + cv::resize(sourceImg, Paint, cv::Size(), 0.5, 0.5); if (Paint.channels() == 1) cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + + putSnAndDetTime(Paint, data->SNcode, 60); bool isNG = false; //aiEvaluate(sourceImg, Paint, isNG); QString okNgSaveText = "NG"; @@ -335,11 +278,11 @@ bool dibutiejiao_45(std::shared_ptr data, zhongHanFanMianTeJiaoParams* plcResult = "2"; } plcResult = "1";//强制OK - data->insertResultImg(Paint); - sourceImg.release(); data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + + data->insertResultImg(Paint); return true; -#endif + } CATCH_EXCEPTIONS @@ -384,19 +327,19 @@ public: } bool initCustom() { #pragma region 注册触发器回调 - chuizhi_1.init("Camera7", "底部贴胶检测-左-铜-相机1(90°)", { { 5500, 1,{5530},"5502","5504",-1} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_90, "贴胶90度"); - qingxie_2.init("Camera8", "底部贴胶检测-左-铜-相机2(45°)", { { 5510, 1,{5530},"5512","5514",-1 }}, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_45, "贴胶45度"); - qingxie_3.init("Camera9", "底部贴胶检测-左-铜-相机3(45°)", { { 5520, 1,{5530},"5522","5524",-1} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_45, "贴胶45度"); - chuizhi_4.init("Camera10", "底部贴胶检测-左-铝-相机4(90°)", { { 5550, 1,{5530},"5552","5554",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_90, "贴胶90度"); - qingxie_5.init("Camera11", "底部贴胶检测-左-铝-相机5(45°)", { { 5560, 1,{5530},"5562","5564",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_45, "贴胶45度"); - qingxie_6.init("Camera12", "底部贴胶检测-左-铝-相机6(45°)", { { 5570, 1,{5530},"5572","5574",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_45, "贴胶45度"); + chuizhi_1.init("Camera7", "底部贴胶检测-左-铜-相机1(90°)", { { 5500, 1,{5530,5580},"5502","5504",5506} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_90); + qingxie_2.init("Camera8", "底部贴胶检测-左-铜-相机2(45°)", { { 5510, 1,{5530,5580},"5512","5514",-1 }}, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_45); + qingxie_3.init("Camera9", "底部贴胶检测-左-铜-相机3(45°)", { { 5520, 1,{5530,5580},"5522","5524",-1} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_45); + chuizhi_4.init("Camera10", "底部贴胶检测-左-铝-相机4(90°)", { { 5550, 1,{5530,5580},"5552","5554",5556} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_90); + qingxie_5.init("Camera11", "底部贴胶检测-左-铝-相机5(45°)", { { 5560, 1,{5530,5580},"5562","5564",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_45); + qingxie_6.init("Camera12", "底部贴胶检测-左-铝-相机6(45°)", { { 5570, 1,{5530,5580},"5572","5574",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_45); - chuizhi_7.init("Camera1", "底部贴胶检测-右-铜-相机1(90°)", { { 5700, 1,{5730},"5702","5704",-1} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_90, "贴胶90度"); - qingxie_8.init("Camera2", "底部贴胶检测-右-铜-相机2(45°)", { { 5710, 1,{5730},"5712","5714",-1} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_45, "贴胶45度"); - qingxie_9.init("Camera3", "底部贴胶检测-右-铜-相机3(45°)", { { 5720, 1,{5730},"5722","5724",-1} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_45, "贴胶45度"); - chuizhi_10.init("Camera4", "底部贴胶检测-右-铝-相机4(90°)", { { 5750, 1,{5730},"5752","5754",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_90, "贴胶90度"); - qingxie_11.init("Camera5", "底部贴胶检测-右-铝-相机5(45°)", { { 5760, 1,{5730},"5762","5764",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_45, "贴胶45度"); - qingxie_12.init("Camera6", "底部贴胶检测-右-铝-相机6(45°)", { { 5770, 1,{5730},"5772","5774",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_45, "贴胶45度"); + chuizhi_7.init("Camera1", "底部贴胶检测-右-铜-相机1(90°)", { { 5700, 1,{5730,5780},"5702","5704",5706} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_90); + qingxie_8.init("Camera2", "底部贴胶检测-右-铜-相机2(45°)", { { 5710, 1,{5730,5780},"5712","5714",-1} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_45); + qingxie_9.init("Camera3", "底部贴胶检测-右-铜-相机3(45°)", { { 5720, 1,{5730,5780},"5722","5724",-1} }, 1, &tongDetParams, _serviceManager, bridge, dibutiejiao_45); + chuizhi_10.init("Camera4", "底部贴胶检测-右-铝-相机4(90°)", { { 5750, 1,{5730,5780},"5752","5754",5756} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_90); + qingxie_11.init("Camera5", "底部贴胶检测-右-铝-相机5(45°)", { { 5760, 1,{5730,5780},"5762","5764",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_45); + qingxie_12.init("Camera6", "底部贴胶检测-右-铝-相机6(45°)", { { 5770, 1,{5730,5780},"5772","5774",-1} }, 1, &lvDetParams, _serviceManager, bridge, dibutiejiao_45); #pragma endregion return true; } diff --git a/src/mission/602/602_RuanLianJie_dinggai/CMakeLists.txt b/src/mission/581_ZhongHan_dibutiejiao/CMakeLists.txt similarity index 91% rename from src/mission/602/602_RuanLianJie_dinggai/CMakeLists.txt rename to src/mission/581_ZhongHan_dibutiejiao/CMakeLists.txt index 76e9200..599e8f5 100644 --- a/src/mission/602/602_RuanLianJie_dinggai/CMakeLists.txt +++ b/src/mission/581_ZhongHan_dibutiejiao/CMakeLists.txt @@ -40,8 +40,8 @@ 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) +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} @@ -64,6 +64,7 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql ) diff --git a/src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.cpp b/src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.cpp new file mode 100644 index 0000000..661e3be --- /dev/null +++ b/src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.cpp @@ -0,0 +1,215 @@ +#include <581_ZhongHan_tiejiao_dingbu.h> +#include +#include +#include +#include +void putSnAndDetTime(cv::Mat& Paint, const std::string& sn, int textSize = 30, const std::string& extraText = "") { + TextRendererZH textPainter(Paint.cols, Paint.rows, textSize); + textPainter.putText(Paint, "SN:" + sn + QDateTime::currentDateTime().toString().toStdString() + extraText, cv::Point(0, Paint.rows - textSize), cv::Scalar(0, 255, 0)); +} +bool TieJiaoZhengMian90(std::shared_ptr data, ZhongHanTieJiaoParams* _detParams, sx_581_address address) { + try + { + + //存图数据加保存队列,加锁,避免数据访问冲突 + QByteArray plcResult = "1"; + cv::Mat sourceImg; + data->getOriImg(0).copyTo(sourceImg); + //sourceImg = cv::imread("D:\\testimg\\60A01MB5601FAYG170501_Camera1_ORI_0_13-51-14-822.bmp", -1); + if (_detParams->in_Product_Str == "Cu") { + //cv::rotate(sourceImg, sourceImg, cv::ROTATE_180);//为保证算法一致, + cv::flip(sourceImg, sourceImg, 1); + } + cv::Mat Paint; + std::vectordefects; + sourceImg.copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + putSnAndDetTime(Paint,data->SNcode, 200); + HDevEngineCpp::HDevProcedure proc("_3_Pos_CoverGlue_Inspection"); + HDevEngineCpp::HDevProcedureCall procedureCall(proc); + + //vs+halcon联调debug + //HDevEngineCpp::HDevEngine myEngine; + //myEngine.StartDebugServer(); + //procedureCall.SetWaitForDebugConnection(true); + + HalconCpp::HObject in_Image;//原始三通道图像 + HalconCpp::HTuple in_Product = HalconCpp::HTuple((char*)(_detParams->in_Product_Str).c_str());//产品类别, 'Cu':铜 'Al':铝 + HalconCpp::HTuple in_LineType = "602";//线体类别 + HalconCpp::HTuple in_Resolution(0.02292);//相机精度(mm/pix) + HalconCpp::HTuple in_FilePath(std::string("./halconFiles/ZH_TieJiao_Up/"+data->cameraKeyName+"/").c_str());//模板文件路径 + + in_Image = MatToHObject(sourceImg); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_Product", in_Product); + procedureCall.SetInputCtrlParamTuple("in_LineType", in_LineType); + procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); + procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.Execute();//执行halcon程序 + + HalconCpp::HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");//焊印圆中心坐标(y,x,R) + HalconCpp::HTuple out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//线的坐标(y1,x1,y2,x2) + HalconCpp::HTuple out_Rectangle = procedureCall.GetOutputCtrlParamTuple("out_Rectangle");//矩形框,共计两个(y,x,phi,width,height) + HalconCpp::HTuple out_NGTails = procedureCall.GetOutputCtrlParamTuple("out_NGTails");//NG的明细 + HalconCpp::HTuple out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//距离 + HalconCpp::HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//算法的执行结果, 0: 算法检测NG 1: 算法执行成功 + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + if (out_Flag.D() == 1) { + //画圆心十字 + cv::drawMarker(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), cv::Scalar(0, 255, 0), cv::MARKER_CROSS, 200, 5); + + //画圆 + cv::circle(Paint, + cv::Point(out_Circle[1].D(), out_Circle[0].D()), + out_Circle[2].D(), cv::Scalar(0, 255, 0), 5); + + //画线 + if (out_LinePoint.Length() > 3) { + for (int i = 0; i < out_LinePoint.Length() / 4; i++) { + cv::line(Paint, + cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4 + 0].D()), + cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), + cv::Scalar(0, 255, 0), 5); + } + } + + //画矩形 + if (out_Rectangle.Length() > 4) { + for (int j = 0; j < out_Rectangle.Length() / 5; j++) { + cv::RotatedRect rRect; + rRect.center.y = out_Rectangle[j * 5 + 0].D(); + rRect.center.x = out_Rectangle[j * 5 + 1].D(); + rRect.angle = out_Rectangle[j * 5 + 2].D(); + rRect.size.width = out_Rectangle[j * 5 + 3].D(); + rRect.size.height = out_Rectangle[j * 5 + 4].D(); + + DrawRotatedRect2Mat(Paint, rRect, cv::Scalar(0, 255, 0), 3, cv::LINE_4); + } + } + + double distance1 = out_Distance[0].D(); + textPainter.putText(Paint, + ("连接片的中心到上极耳胶纸的距离:" + QByteArray::number(distance1) + "mm").toStdString().c_str(), + cv::Point(0, 400), cv::Scalar(0, 255, 0)); + + double distance2 = out_Distance[1].D(); + textPainter.putText(Paint, + ("连接片的中心到下极耳胶纸的距离:" + QByteArray::number(distance2) + "mm").toStdString().c_str(), + cv::Point(0, 800), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(distance1)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(distance2)); + textPainter.putText(Paint, "OK", cv::Point(0, 50), cv::Scalar(0, 255, 0)); + } + else { + defects.push_back("贴胶NG"); + textPainter.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); + plcResult = "2"; + data->halconOK = false; + std::string NgTails = out_NGTails.ToString().Text();//NG明细 + textPainter.putText(Paint, NgTails, cv::Point(0, 600), cv::Scalar(0, 255, 255)); + } + + if (!data->service->_paramSyncManager->get("顶部贴胶", "顶部贴胶判定启用", true).toBool()) + plcResult = "1"; + + if (data->cameraKeyName == "Camera1")data->service->_triggerManager->writeShort("D5864_" + plcResult); + else if (data->cameraKeyName == "Camera4")data->service->_triggerManager->writeShort("D5865_" + plcResult); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + data->service->_missionResultHandle->toBarChart(data->SNcode, defects); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->insertResultImg(Paint); + + + sourceImg.release(); + return true; + } + CATCH_EXCEPTIONS + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + cv::Mat Paint; + data->getOriImg(0).copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 15); + textPainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->insertResultImg(Paint); + + cv::Mat sourceImg; + data->getOriImg(0).copyTo(sourceImg); + if (_detParams->in_Product_Str == "Cu") { + cv::rotate(sourceImg, sourceImg, cv::ROTATE_180);//为保证算法一致, + } + + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + return true; +} + +bool TieJiaoZhengMian45(std::shared_ptr data, ZhongHanTieJiaoParams* _detParams, sx_581_address address) { + try + { + cv::Mat Paint; + data->getOriImg(0).copyTo(Paint); + putSnAndDetTime(Paint, data->SNcode, 150); + bool isNG = false; + QByteArray plcResult = "1"; + TextRendererZH textainter(Paint.cols, Paint.rows, 300); + if (isNG == true) + { + plcResult = "2"; + textainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + } + else { + textainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + } + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5);//结果图缩放 + data->insertResultImg(Paint); + + plcResult = "1"; + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + return true; + } + CATCH_EXCEPTIONS + + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + cv::Mat Paint; + Paint.copyTo(data->getOriImg(0)); + if (Paint.channels() == 1) { + cv::cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + } + QByteArray plcResult = "2"; + TextRendererZH textainter(Paint.cols, Paint.rows, 300); + textainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->insertResultImg(Paint); + plcResult = "1"; + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + return true; +} + + +void DrawRotatedRect2Mat(cv::Mat& img, cv::RotatedRect rotateRect, cv::Scalar color, int thickness, int linType) +{ + std::vector boxPts(4); + rotateRect.points(boxPts.data()); + for (int mm = 0; mm < 4; mm++) { + cv::line(img, boxPts[mm], boxPts[(mm + 1) % 4], color, thickness, linType); + } +} + + + + + + + + + + + +mission* createMission() { + return new _581_ZhongHan_tiejiao_dingbu(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.h b/src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.h new file mode 100644 index 0000000..9419ca4 --- /dev/null +++ b/src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.h @@ -0,0 +1,60 @@ +#include +#include +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +#pragma endregion +class ZhongHanTieJiaoParams { +public: + std::string in_Product_Str = ""; +}; + + + +void DrawRotatedRect2Mat(cv::Mat& img, cv::RotatedRect rotateRect, cv::Scalar color, int thickness, int linType); +bool TieJiaoZhengMian90(std::shared_ptr data, ZhongHanTieJiaoParams* _detParams, sx_581_address address); +bool TieJiaoZhengMian45(std::shared_ptr data, ZhongHanTieJiaoParams* _detParams, sx_581_address address); + +class _581_ZhongHan_tiejiao_dingbu : public mission { +public: + _581_SX_Single_triggerTemplate< ZhongHanTieJiaoParams> in_tong_90_1; + _581_SX_Single_triggerTemplate< ZhongHanTieJiaoParams> in_tong_45_2; + _581_SX_Single_triggerTemplate< ZhongHanTieJiaoParams> in_tong_45_3; + + _581_SX_Single_triggerTemplate< ZhongHanTieJiaoParams> out_tong_90_4; + _581_SX_Single_triggerTemplate< ZhongHanTieJiaoParams> out_tong_45_5; + _581_SX_Single_triggerTemplate< ZhongHanTieJiaoParams> out_tong_45_6; + + ZhongHanTieJiaoParams tongParams; + ZhongHanTieJiaoParams lvParams; + bool initOnce = false; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + initOnce = true; + + tongParams.in_Product_Str = "Cu"; + lvParams.in_Product_Str = "Al"; + } + bool initCustom() { +#pragma region 注册触发器回调 + in_tong_90_1.init("Camera1", "贴胶检测-内-铜-相机1(90°)", { { 5200, 1,{{5120,5140}},"5202","5204",5206} }, 1, &tongParams, _serviceManager, bridge, TieJiaoZhengMian90); + in_tong_45_2.init("Camera2", "贴胶检测-内-铜-相机2(45°)", { { 5210, 1,{5120,5140},"5212","5214",-1} }, 1, &tongParams, _serviceManager, bridge, TieJiaoZhengMian45); + in_tong_45_3.init("Camera3", "贴胶检测-内-铜-相机3(45°)", { { 5220, 1,{5120,5140},"5222","5224",-1} }, 1, &tongParams, _serviceManager, bridge, TieJiaoZhengMian45); + + out_tong_90_4.init("Camera4", "贴胶检测-外-铝-相机4(90°)", { { 5230, 1,{5120,5140},"5232","5234",5236} }, 1, &lvParams, _serviceManager, bridge, TieJiaoZhengMian90); + out_tong_45_5.init("Camera5", "贴胶检测-外-铝-相机5(45°)", { { 5240, 1,{5120,5140},"5242","5244",-1} }, 1, &lvParams, _serviceManager, bridge, TieJiaoZhengMian45); + out_tong_45_6.init("Camera6", "贴胶检测-外-铝-相机6(45°)", { { 5250, 1,{5120,5140},"5252","5254",-1} }, 1, &lvParams, _serviceManager, bridge, TieJiaoZhengMian45); + +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/602/YH/581_YuHan_hanqian/CMakeLists.txt b/src/mission/581_ZhongHan_tiejiao_dingbu/CMakeLists.txt similarity index 91% rename from src/mission/602/YH/581_YuHan_hanqian/CMakeLists.txt rename to src/mission/581_ZhongHan_tiejiao_dingbu/CMakeLists.txt index 76e9200..599e8f5 100644 --- a/src/mission/602/YH/581_YuHan_hanqian/CMakeLists.txt +++ b/src/mission/581_ZhongHan_tiejiao_dingbu/CMakeLists.txt @@ -40,8 +40,8 @@ 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) +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} @@ -64,6 +64,7 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql ) diff --git a/src/mission/601/601_RLJ_DingGai/601_RLJ_DingGai.cpp b/src/mission/601/601_RLJ_DingGai/601_RLJ_DingGai.cpp index 47a9b83..39cc8bb 100644 --- a/src/mission/601/601_RLJ_DingGai/601_RLJ_DingGai.cpp +++ b/src/mission/601/601_RLJ_DingGai/601_RLJ_DingGai.cpp @@ -1,5 +1,9 @@ #include <601_RLJ_DingGai.h> +struct PanitJob { + std::string str; + cv::Point p; +}; bool ALGO_maJiaReRong(std::shared_ptr data, maJiaParam* _detParams, sx_581_address address) { try { qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; @@ -11,14 +15,14 @@ bool ALGO_maJiaReRong(std::shared_ptr data, maJiaParam* _detParams, sx return false; } auto sourceImg = data->getOriImg(0); - switch (address.triggerValue) { - case 1: - sourceImg = cv::imread("D:\\testImage\\601\\majia (1).bmp", -1); - break; - case 2: - sourceImg = cv::imread("D:\\testImage\\601\\majia (2).bmp", -1); - break; - } + //switch (address.triggerValue) { + //case 1: + // sourceImg = cv::imread("D:\\testImage\\601\\majia (1).bmp", -1); + // break; + //case 2: + // sourceImg = cv::imread("D:\\testImage\\601\\majia (2).bmp", -1); + // break; + //} sourceImg(cv::Rect(1700, 700, 2200, 2200)).copyTo(sourceImg); if (sourceImg.rows == 100) { cv::Mat Paint; @@ -27,6 +31,7 @@ bool ALGO_maJiaReRong(std::shared_ptr data, maJiaParam* _detParams, sx return false; } cv::Mat Paint; + sourceImg.copyTo(Paint); HDevEngineCpp::HDevProcedure proc("MeltingPoint_Inspection_3_1"); HDevEngineCpp::HDevProcedureCall procedureCall(proc); HObject in_Image1, in_Image2, out_DisplayImage; @@ -42,7 +47,7 @@ bool ALGO_maJiaReRong(std::shared_ptr data, maJiaParam* _detParams, sx out_CCDistance = procedureCall.GetOutputCtrlParamTuple("out_CCDistance");//获取输出控制类变量 out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - Paint = HObject2Mat(out_DisplayImage); + int flag = out_Flag.D(); QByteArray plcResult = "1"; @@ -50,6 +55,7 @@ bool ALGO_maJiaReRong(std::shared_ptr data, maJiaParam* _detParams, sx TextRendererZH textPainter(Paint.cols, Paint.rows, 250); if (flag == 1) { + Paint = HObject2Mat(out_DisplayImage); int Area1 = out_PointArea[0].D(); int Area2 = out_PointArea[1].D(); int Area3 = out_PointArea[2].D(); @@ -94,15 +100,16 @@ bool ALGO_maJiaReRong(std::shared_ptr data, maJiaParam* _detParams, sx plcResult = "4"; else if (isNG == false && _detParams->lastResult == "2")//第一次NG plcResult = "2"; - else if (isNG == true && _detParams->lastResult == "2")//第二次NG + else if (isNG == true && _detParams->lastResult == "1")//第二次NG plcResult = "3"; else if (isNG == false && _detParams->lastResult == "1")//均OK plcResult = "1"; + else + plcResult = "2"; _detParams->lastResult = "1";//复位结果 data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//发送结果 } - plcResult = "2"; if (plcResult == "1") data->service->_missionResultHandle->toBarChart(data->SNcode, { }); else @@ -120,7 +127,7 @@ bool ALGO_maJiaReRong(std::shared_ptr data, maJiaParam* _detParams, sx bool ALGO_hanQianDingWei(std::shared_ptr data, detParams* _detParams, sx_581_address address) { try { qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - + data->service->_triggerManager->writeShort("D100_1_1"); ///////////////////取图//处理////////////////// if (data->getOriImgSize() < 1) { @@ -128,7 +135,7 @@ bool ALGO_hanQianDingWei(std::shared_ptr data, detParams* _detParams, return false; } auto sourceImg = data->getOriImg(0); - //sourceImg = cv::imread("D:\\testImage\\601\\hanqian.bmp", -1); + sourceImg = cv::imread("D:\\testImage\\601\\hanqian.bmp", -1); if (sourceImg.rows == 100) { cv::Mat Paint; sourceImg.copyTo(Paint); @@ -136,6 +143,7 @@ bool ALGO_hanQianDingWei(std::shared_ptr data, detParams* _detParams, return false; } cv::Mat Paint; + sourceImg.copyTo(Paint); HDevEngineCpp::HDevProcedure proc("HQDW_Color_Inspection"); HDevEngineCpp::HDevProcedureCall procedureCall(proc); @@ -167,7 +175,7 @@ bool ALGO_hanQianDingWei(std::shared_ptr data, detParams* _detParams, //正确的应该左边铝 右边铜 - QByteArray plcResult; + QByteArray plcResult = "1"; TextRendererZH textPainter(Paint.cols, Paint.rows, 300); if (flag == 1) { @@ -176,9 +184,9 @@ bool ALGO_hanQianDingWei(std::shared_ptr data, detParams* _detParams, int HeightRightFlag = 1; int AlgelFlag = 1; Paint = HObject2Mat(out_DisplayImage); - - textPainter.putText(Paint, "膜上边到注液孔:" + std::to_string(out_Distance[0].D()), cv::Point(800, 50), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "膜下边到注液孔:" + std::to_string(out_Distance[1].D()), cv::Point(800, 350), cv::Scalar(0, 255, 0)); + textPainter.appendPaintJob("膜上边到注液孔:" + std::to_string(out_Distance[0].D()), cv::Point(800, 50), cv::Scalar(0, 255, 0)); + textPainter.appendPaintJob("膜下边到注液孔:" + std::to_string(out_Distance[1].D()), cv::Point(800, 350), cv::Scalar(0, 255, 0)); + textPainter.excusePaintJobs(Paint); if (out_Height[0].D() > HeightLeft_jsonvlaue) { HeightLeftFlag = 2; @@ -221,6 +229,7 @@ bool ALGO_hanQianDingWei(std::shared_ptr data, detParams* _detParams, textPainter.putText(Paint, "NG", cv::Point(100, 150), cv::Scalar(0, 0, 255)); plcResult = "2"; + data->halconOK = false; } else{ @@ -234,12 +243,12 @@ bool ALGO_hanQianDingWei(std::shared_ptr data, detParams* _detParams, plcResult = "2"; } - if(plcResult == "2") + + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//发送异常结果 + if (plcResult == "2") data->service->_missionResultHandle->toBarChart(data->SNcode, { "焊前NG" }); else data->service->_missionResultHandle->toBarChart(data->SNcode, { }); - //data2 = QByteArray::number(out_CCDistance.D()); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送异常结果 cv::resize(Paint, Paint, cv::Size(), 0.25, 0.25); data->insertResultImg(Paint); @@ -386,6 +395,10 @@ bool ALGO_dingGaiKeMa(std::shared_ptr data, keMaParam* _detParams, sx_ } else if (address.triggerValue == 3)//极柱 { + //极柱不判断直接发 节省CT + plcResult = _detParams->keMaResult; + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//发送结果 + Paint = cv::Mat(_detParams->TP1IMG.rows, _detParams->TP1IMG.cols * 3, CV_8UC1); _detParams->TP1IMG.copyTo(Paint(cv::Rect(0, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows))); sourceImg.copyTo(Paint(cv::Rect(_detParams->TP1IMG.cols, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows))); @@ -451,22 +464,25 @@ bool ALGO_dingGaiKeMa(std::shared_ptr data, keMaParam* _detParams, sx_ text = text.substr(0, text.find(".") + 4) + "mm"; textPainter.putText(PaintPart2, text, cv::Point(50, 300), cv::Scalar(0, 255, 0)); } - plcResult = _detParams->keMaResult; - } else { resTextPainter.putText(Paint, "NG1", cv::Point(0, 50), cv::Scalar(0, 0, 255)); + data->halconOK = false; } + cv::resize(Paint, Paint, cv::Size(), 0.25, 0.25); data->insertResultImg(Paint); + if (plcResult == "2") { + data->service->_missionResultHandle->toBarChart(data->SNcode, { "刻码NG" }); + data->halconOK = false; + } + else + data->service->_missionResultHandle->toBarChart(data->SNcode, { }); } - if (plcResult == "2") - data->service->_missionResultHandle->toBarChart(data->SNcode, { "刻码NG" }); - else - data->service->_missionResultHandle->toBarChart(data->SNcode, { }); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//发送结果 + + return true; } CATCH_EXCEPTIONS diff --git a/src/mission/601/601_RLJ_DingGai/601_RLJ_DingGai.h b/src/mission/601/601_RLJ_DingGai/601_RLJ_DingGai.h index 513f5c9..38bfe4f 100644 --- a/src/mission/601/601_RLJ_DingGai/601_RLJ_DingGai.h +++ b/src/mission/601/601_RLJ_DingGai/601_RLJ_DingGai.h @@ -107,7 +107,7 @@ public: HDevEngineCpp::HDevEngine myEngine; myEngine.UnloadAllProcedures(); myEngine.SetProcedurePath(""); - myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_628_1.hdpl"); + myEngine.SetProcedurePath("./halconFilesAlgo/AlgoLibrary_628_1.hdpl"); if (initOnce == false) { initOnce = true; @@ -115,13 +115,13 @@ public: } bool initCustom() { #pragma region 注册触发器回调 - hanQianDingWei.init("Camera1", "焊前定位", { { 4900, 1,{4910},"4902","4906"} }, 1, &_detParams, _serviceManager, bridge, ALGO_hanQianDingWei); + hanQianDingWei.init("Camera1", "焊前定位", { { 4900, 1,{4910},"4902","4904"} }, 1, &_detParams, _serviceManager, bridge, ALGO_hanQianDingWei,"焊前定位"); - maJia1.init("Camera2", "马甲热熔-相机1", { { 5200, 1,{5210},"5202","5204",5206},{ 5200, 2,{5210},"5202","5204",5206} }, 1, &_maJiaParam1, _serviceManager, bridge, ALGO_maJiaReRong); - maJia2.init("Camera3", "马甲热熔-相机2", { { 5300, 1,{5310},"5302","5304",5306},{ 5300, 2,{5310},"5302","5304",5306} }, 1, &_maJiaParam2, _serviceManager, bridge, ALGO_maJiaReRong); + maJia1.init("Camera2", "马甲热熔-相机1", { { 5200, 1,{5210},"5202","5204",5206},{ 5200, 2,{5210},"5202","5204",5206} }, 1, &_maJiaParam1, _serviceManager, bridge, ALGO_maJiaReRong, "马甲热熔"); + maJia2.init("Camera3", "马甲热熔-相机2", { { 5300, 1,{5310},"5302","5304",5306},{ 5300, 2,{5310},"5302","5304",5306} }, 1, &_maJiaParam2, _serviceManager, bridge, ALGO_maJiaReRong, "马甲热熔"); - kema1.init("Camera4", "防爆阀-相机1", { { 5000, 1,{5010},"5002","5004"},{ 5000, 2,{5010},"5002","5004"},{ 5000, 3,{5010},"5002","5004"} }, 1, &_keMaParam1, _serviceManager, bridge, ALGO_dingGaiKeMa); - kema2.init("Camera5", "防爆阀-相机2", { { 5100, 1,{5110},"5102","5104"},{ 5100, 2,{5110},"5102","5104"},{ 5100, 3,{5110},"5102","5104"} }, 1, &_keMaParam2, _serviceManager, bridge, ALGO_dingGaiKeMa); + kema1.init("Camera4", "防爆阀-相机1", { { 5000, 1,{5010},"5002","5004"},{ 5000, 2,{5010},"5002","5004"},{ 5000, 3,{5010},"5002","5004"} }, 1, &_keMaParam1, _serviceManager, bridge, ALGO_dingGaiKeMa, "顶盖刻码"); + kema2.init("Camera5", "防爆阀-相机2", { { 5100, 1,{5110},"5102","5104"},{ 5100, 2,{5110},"5102","5104"},{ 5100, 3,{5110},"5102","5104"} }, 1, &_keMaParam2, _serviceManager, bridge, ALGO_dingGaiKeMa, "顶盖刻码"); diff --git a/src/mission/601/601_RLJ_DingGai/CMakeLists.txt b/src/mission/601/601_RLJ_DingGai/CMakeLists.txt index 76e9200..599e8f5 100644 --- a/src/mission/601/601_RLJ_DingGai/CMakeLists.txt +++ b/src/mission/601/601_RLJ_DingGai/CMakeLists.txt @@ -40,8 +40,8 @@ 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) +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} @@ -64,6 +64,7 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql ) diff --git a/src/mission/601/601_RLJ_HH/601_RLJ_HH.cpp b/src/mission/601/601_RLJ_HH/601_RLJ_HH.cpp index 3acaa68..27c0c17 100644 --- a/src/mission/601/601_RLJ_HH/601_RLJ_HH.cpp +++ b/src/mission/601/601_RLJ_HH/601_RLJ_HH.cpp @@ -1,6 +1,6 @@ #include <601_RLJ_HH.h> -void halconEvaluate(cv::Mat sourceImg, cv::Mat segImg, cv::Mat& Paint, bool& isNg, QByteArray& hanHouTongXingDu, int times, std::shared_ptr data, hanHou2dParam* _detParams) { +void halconEvaluate(cv::Mat sourceImg, cv::Mat segImg, TextRendererZH* textPainter, bool& isNg, QByteArray& hanHouTongXingDu, int times, std::shared_ptr data, hanHou2dParam* _detParams) { HDevEngineCpp::HDevProcedure proc("Cal_HY_CC_Distance_3_1"); HDevEngineCpp::HDevProcedureCall procedureCall(proc); HObject in_Image = MatToHObject(sourceImg); @@ -17,31 +17,31 @@ void halconEvaluate(cv::Mat sourceImg, cv::Mat segImg, cv::Mat& Paint, bool& isN out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 int flag = out_Flag.D(); isNg = false; - TextRendererZH textPainter(Paint.cols, Paint.rows, 600); + if (flag == 1){ double CCDistance = out_CCDistance.D(); hanHouTongXingDu = QByteArray::number(CCDistance); - textPainter.putText(Paint, "焊印同心度:" + std::to_string(CCDistance), cv::Point(0, 50), cv::Scalar(0, 255, 0)); + textPainter->appendPaintJob("焊印同心度:" + std::to_string(CCDistance), cv::Point(0, 0), cv::Scalar(0, 255, 0)); - cv::circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 15); - cv::circle(Paint, cv::Point(out_Circle[4].D(), out_Circle[3].D()), out_Circle[5].D(), cv::Scalar(0, 255, 0), 15); + textPainter->appendPaintJob(cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 15,0); + textPainter->appendPaintJob(cv::Point(out_Circle[4].D(), out_Circle[3].D()), out_Circle[5].D(), cv::Scalar(0, 255, 0), 15,0); if (CCDistance > 3) { - textPainter.putText(Paint, "同心度NG" + std::to_string(CCDistance), cv::Point(0, 150), cv::Scalar(0, 0, 255)); + textPainter->appendPaintJob("同心度NG", cv::Point(0, 300), cv::Scalar(0, 0, 255)); isNg = true; } } else{ - textPainter.putText(Paint, "焊印抓取NG", cv::Point(0, 150), cv::Scalar(0, 0, 255)); + textPainter->appendPaintJob("焊印抓取NG", cv::Point(0, 300), cv::Scalar(0, 0, 255)); isNg = true; } } -void HandleAIEvaluate(cv::Mat sourceImg, cv::Mat& Paint, bool& isNg, int times, std::shared_ptr data, hanHou2dParam* _detParams) { +void HandleAIEvaluate(cv::Mat sourceImg, TextRendererZH* textPainter, bool& isNg, int times, std::shared_ptr data, handdleAI::pSegmentation*seg,handdleAI::pClassification* cls) { isNg = false; cv::Mat forSeg; cv::resize(sourceImg, forSeg, cv::Size(), 0.5, 0.5); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - cv::Mat segImg = ~_detParams->seg_rljHanZha->Evaluate(forSeg); + //cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + cv::Mat segImg = ~seg->Evaluate(forSeg); std::vector>contours;//点集 cv::findContours(segImg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); // 寻找白色区域并储存为点集 std::vector> clsImgs; @@ -50,7 +50,7 @@ void HandleAIEvaluate(cv::Mat sourceImg, cv::Mat& Paint, bool& isNg, int times, if (rect.height > 30 || rect.width > 30) {// 过滤 只有都大于10像素才进检测 cv::Mat clsImage = cutImg2Cls(rect, forSeg);//切图 - int clsResult = _detParams->cls_rljHanZha->Evaluate(clsImage);//cls检测 得出的是int型 从0开始 + int clsResult = cls->Evaluate(clsImage);//cls检测 得出的是int型 从0开始 if (clsResult == 0){ //rectangle(Paint,cv::Rect{ rect,x,rect .y,rect .width,rect .height}, cv::Scalar(0, 0, 255), 2, 8, 0); @@ -59,19 +59,19 @@ void HandleAIEvaluate(cv::Mat sourceImg, cv::Mat& Paint, bool& isNg, int times, else { //isNg = true; - rectangle(Paint, cv::Rect{ rect.x,rect.y,rect.width,rect.height }, cv::Scalar(0, 0, 255), 2, 8, 0); - drawContours(Paint, contours, i, cv::Scalar(0, 0, 255, 1)); + textPainter->appendPaintJob(cv::Rect{ rect.x * 2,rect.y * 2,rect.width * 2,rect.height * 2}, cv::Scalar(0, 0, 255), 2); + //textPainter->appendPaintJob(contours, i, cv::Scalar(0, 0, 255, 1)); } clsImgs.push_back({ std::to_string(clsResult),clsImage }); } } data->insertClsOriginImg(clsImgs); - cv::resize(Paint, Paint, cv::Size(), 2, 2); + //cv::resize(Paint, Paint, cv::Size(), 2, 2); } bool hanhou2D(std::shared_ptr data, hanHou2dParam* _detParams, sx_581_address address) { try { qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - + std::vectordefects; ///////////////////取图//处理////////////////// if (data->getOriImgSize() < 2) { @@ -80,8 +80,8 @@ bool hanhou2D(std::shared_ptr data, hanHou2dParam* _detParams, sx_581_ } auto img2D1 = data->getOriImg(0); auto img2D2 = data->getOriImg(1); - img2D1 = cv::imread("D:\\testImage\\601\\ORI_T.bmp", -1); - img2D2 = cv::imread("D:\\testImage\\601\\ORI_L.bmp", -1); + //img2D1 = cv::imread("D:\\testImage\\601\\ORI_T.bmp", -1); + //img2D2 = cv::imread("D:\\testImage\\601\\ORI_L.bmp", -1); cv::Mat Paint1, Paint2; img2D1.copyTo(Paint1); img2D2.copyTo(Paint2); @@ -98,36 +98,33 @@ bool hanhou2D(std::shared_ptr data, hanHou2dParam* _detParams, sx_581_ cv::Mat forSeg1, forSeg2; double resizeRate = 0.25; cv::resize(img2D1, forSeg1, cv::Size(), resizeRate, resizeRate); - //cv::Mat seg1 = _detParams->seg_rljHanYinZhuaQu->Evaluate(forSeg1); - cv::Mat seg1 = cv::imread("D:\\testImage\\601\\SEG_T.bmp", -1); + cv::Mat seg1 = _detParams->seg_rljHanYinZhuaQu->Evaluate(forSeg1); + //cv::Mat seg1 = cv::imread("D:\\testImage\\601\\SEG_T.bmp", -1); data->insertSegOriginImg(seg1); data->insertSegOriginImg(forSeg1); cv::resize(img2D2, forSeg2, cv::Size(), resizeRate, resizeRate); - //cv::Mat seg2 = _detParams->seg_rljHanYinZhuaQu->Evaluate(forSeg2); - cv::Mat seg2 = cv::imread("D:\\testImage\\601\\SEG_L.bmp", -1); + cv::Mat seg2 = _detParams->seg_rljHanYinZhuaQu->Evaluate(forSeg2); + //cv::Mat seg2 = cv::imread("D:\\testImage\\601\\SEG_L.bmp", -1); data->insertSegOriginImg(seg2); data->insertSegOriginImg(forSeg2); qDebug() << "h start"; + TextRendererZH textPainter1(Paint1.cols, Paint1.rows, 400), textPainter2(Paint1.cols, Paint1.rows, 400); auto futrue1 = std::async(std::launch::async, &halconEvaluate, - img2D1, seg1, std::ref(Paint1), std::ref(isNg1), std::ref(hanHouTongXingDu1), 0, data, _detParams); + img2D1, seg1, &textPainter1, std::ref(isNg1), std::ref(hanHouTongXingDu1), 0, data, _detParams); auto futrue2 = std::async(std::launch::async, &halconEvaluate, - img2D2, seg2, std::ref(Paint2), std::ref(isNg2), std::ref(hanHouTongXingDu2), 2, data, _detParams); + img2D2, seg2, &textPainter2, std::ref(isNg2), std::ref(hanHouTongXingDu2), 2, data, _detParams); + + auto futrue3 = std::async(std::launch::async, &HandleAIEvaluate, + img2D1, &textPainter1, std::ref(isNg3), 0, data, _detParams->seg_rljHanZha1, _detParams->cls_rljHanZha1); + auto futrue4 = std::async(std::launch::async, &HandleAIEvaluate, + img2D2, &textPainter2, std::ref(isNg4), 2, data, _detParams->seg_rljHanZha2, _detParams->cls_rljHanZha2); + futrue1.wait(); futrue2.wait(); - qDebug() << "hz Start"; - //auto futrue3 = std::async(std::launch::async, &HandleAIEvaluate, - // img2D1, std::ref(Paint1), std::ref(isNg3), 0, data, _detParams); - //auto futrue4 = std::async(std::launch::async, &HandleAIEvaluate, - // img2D2, std::ref(Paint2), std::ref(isNg4), 2, data, _detParams); - //futrue3.wait(); - //futrue4.wait(); - cv::Mat PaintSum; - cv::vconcat(Paint1, Paint2, PaintSum); - qDebug() << "hz End"; + if (isNg1 == false && isNg2 == false) {//都OK发1 plcResult = "1"; - imgSaveText = "OK"; } else if (isNg1 == true && isNg2 == false)//第一次NG发2 plcResult = "2"; @@ -137,12 +134,26 @@ bool hanhou2D(std::shared_ptr data, hanHou2dParam* _detParams, sx_581_ plcResult = "4"; else//为了DEBUG plcResult = "5"; + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//发送结果 + + if (plcResult != "1") { + defects.push_back("焊后NG"); + data->halconOK = false; + } + data->service->_missionResultHandle->toBarChart(data->SNcode, defects); + futrue3.wait(); + futrue4.wait(); + textPainter1.excusePaintJobs(Paint1); + textPainter2.excusePaintJobs(Paint2); + cv::Mat PaintSum; + cv::vconcat(Paint1, Paint2, PaintSum); + data->insertResultImg(PaintSum); return true; } CATCH_EXCEPTIONS - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送异常结果 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送异常结果 return false; } diff --git a/src/mission/601/601_RLJ_HH/601_RLJ_HH.h b/src/mission/601/601_RLJ_HH/601_RLJ_HH.h index 0b81570..a886093 100644 --- a/src/mission/601/601_RLJ_HH/601_RLJ_HH.h +++ b/src/mission/601/601_RLJ_HH/601_RLJ_HH.h @@ -10,8 +10,11 @@ using namespace HDevEngineCpp; struct hanHou2dParam { handdleAI::pSegmentation* seg_rljHanYinZhuaQu; - handdleAI::pSegmentation* seg_rljHanZha; - handdleAI::pClassification* cls_rljHanZha; + handdleAI::pSegmentation* seg_rljHanZha1; + handdleAI::pClassification* cls_rljHanZha1; + + handdleAI::pSegmentation* seg_rljHanZha2; + handdleAI::pClassification* cls_rljHanZha2; }; bool hanhou2D(std::shared_ptr data, hanHou2dParam* _detParams, sx_581_address address); @@ -32,24 +35,27 @@ public: HDevEngineCpp::HDevEngine myEngine; myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_628_1.hdpl"); if (initOnce == false) { - /*_hanHou2dParam1.seg_rljHanYinZhuaQu = handdleAI::CreateSegObjS("./model/seg-rljHanYinZhuaQu.BHD", 16, 0); - _hanHou2dParam1.seg_rljHanZha = handdleAI::CreateSegObjS("./model/seg_rljHanZha.BHD", 16, 0); - _hanHou2dParam1.cls_rljHanZha = handdleAI::CreateClsObjV3("./model/cls_rljHanZha.BHD.BHD", 0, 1); - - _hanHou2dParam2.seg_rljHanYinZhuaQu = handdleAI::CreateSegObjS("./model/seg-rljHanYinZhuaQu.BHD", 16, 0); - _hanHou2dParam2.seg_rljHanZha = handdleAI::CreateSegObjS("./model/seg_rljHanZha.BHD", 16, 0); - _hanHou2dParam2.cls_rljHanZha = handdleAI::CreateClsObjV3("./model/cls_rljHanZha.BHD.BHD", 0, 1);*/ - - initOnce = true; + //_hanHou2dParam1.seg_rljHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/seg-rljHanYinZhuaQu.BHD", 1, 0); + //_hanHou2dParam1.seg_rljHanZha1 = handdleAI::CreateSegObjS("./handleaiModels/seg_rljHanZha.BHD", 1, 0); + //_hanHou2dParam1.cls_rljHanZha1 = handdleAI::CreateClsObjV3("./handleaiModels/cls_rljHanZha.BHD", 0, 1); + //_hanHou2dParam1.seg_rljHanZha2 = handdleAI::CreateSegObjS("./handleaiModels/seg_rljHanZha.BHD", 1, 0); + //_hanHou2dParam1.cls_rljHanZha2 = handdleAI::CreateClsObjV3("./handleaiModels/cls_rljHanZha.BHD", 0, 1); + // + //_hanHou2dParam2.seg_rljHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/seg-rljHanYinZhuaQu.BHD", 1, 0); + //_hanHou2dParam2.seg_rljHanZha1 = handdleAI::CreateSegObjS("./handleaiModels/seg_rljHanZha.BHD", 1, 0); + //_hanHou2dParam2.cls_rljHanZha1 = handdleAI::CreateClsObjV3("./handleaiModels/cls_rljHanZha.BHD", 0, 1); + //_hanHou2dParam2.seg_rljHanZha2 = handdleAI::CreateSegObjS("./handleaiModels/seg_rljHanZha.BHD", 1, 0); + //_hanHou2dParam2.cls_rljHanZha2 = handdleAI::CreateClsObjV3("./handleaiModels/cls_rljHanZha.BHD", 0, 1); + //initOnce = true; } } bool initCustom() { #pragma region 注册触发器回调 - hanhou_2d_1.init("Camera1", "焊后2D-相机1", { { 5400, 1,{5410},"5402","5404"} }, 2, &_hanHou2dParam1, _serviceManager, bridge, hanhou2D); - hanhou_2d_2.init("Camera2", "焊后2D-相机2", { { 5500, 1,{5510},"5502","5504"} }, 2, &_hanHou2dParam2, _serviceManager, bridge, hanhou2D); + hanhou_2d_1.init("Camera1", "焊后2D-相机1", { { 5400, 1,{5410},"5402","5404"},{ 5400, 2,{5410},"5402","5404"} }, 2, &_hanHou2dParam1, _serviceManager, bridge, hanhou2D); + hanhou_3d_1.init("Camera3", "焊后3D-相机1", { { 5500, 1,{5410},"5502","5504"}, { 5500, 2,{5410},"5502","5504"} }, 4, &_detParams, _serviceManager, bridge, generalAlgoTest); - hanhou_3d_1.init("Camera3", "焊后3D-相机1", { { 5600, 1,{5610},"5602","5504"} }, 1, &_detParams, _serviceManager, bridge, generalAlgoTest); - hanhou_3d_2.init("Camera4", "焊后3D-相机2", { { 5700, 1,{5710},"5702","5534"} }, 1, &_detParams, _serviceManager, bridge, generalAlgoTest); + hanhou_2d_2.init("Camera2", "焊后2D-相机2", { { 5600, 1,{5610},"5602","5604"},{ 5600, 2,{5610},"5602","5604"} }, 2, &_hanHou2dParam2, _serviceManager, bridge, hanhou2D); + hanhou_3d_2.init("Camera4", "焊后3D-相机2", { { 5700, 1,{5610},"5702","5704"}, { 5700, 2,{5610},"5702","5704"} }, 4, &_detParams, _serviceManager, bridge, generalAlgoTest); #pragma endregion return true; diff --git a/src/mission/601/601_RLJ_HH/CMakeLists.txt b/src/mission/601/601_RLJ_HH/CMakeLists.txt index 76e9200..599e8f5 100644 --- a/src/mission/601/601_RLJ_HH/CMakeLists.txt +++ b/src/mission/601/601_RLJ_HH/CMakeLists.txt @@ -40,8 +40,8 @@ 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) +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} @@ -64,6 +64,7 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql ) diff --git a/src/mission/601/601_ZH_Dibu/CMakeLists.txt b/src/mission/601/601_ZH_Dibu/CMakeLists.txt index 76e9200..599e8f5 100644 --- a/src/mission/601/601_ZH_Dibu/CMakeLists.txt +++ b/src/mission/601/601_ZH_Dibu/CMakeLists.txt @@ -40,8 +40,8 @@ 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) +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} @@ -64,6 +64,7 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql ) diff --git a/src/mission/602/581_Ruanlianjie_hanqian_hanhou/581_Ruanlianjie_hanqian_hanhou.cpp b/src/mission/602/581_Ruanlianjie_hanqian_hanhou/581_Ruanlianjie_hanqian_hanhou.cpp deleted file mode 100644 index 683b212..0000000 --- a/src/mission/602/581_Ruanlianjie_hanqian_hanhou/581_Ruanlianjie_hanqian_hanhou.cpp +++ /dev/null @@ -1,487 +0,0 @@ -#include <581_Ruanlianjie_hanqian_hanhou.h> -void exceptionResume(std::shared_ptr data, hanHouJianCe* _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");//结果反馈 - -} -void exceptionResume(std::shared_ptr data, hanQianDingWeiParams* _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 HanQianDingWei(std::shared_ptr data, hanQianDingWeiParams* _detParams, sx_581_address address){ - try - { - bool zuoLJPtoGaiBanEnable = data->service->_paramSyncManager->get("焊前定位", "左侧连接片和盖板距离判定启用", false).toBool(); - double zuoLJPtoGaiBanMaxThreshold = data->service->_paramSyncManager->get("焊前定位", "左侧连接片和盖板距离(MAX)", 1.8).toDouble(); - double zuoLJPtoGaiBanMinThreshold = data->service->_paramSyncManager->get("焊前定位", "左侧连接片和盖板距离(MIN)", 0.0).toDouble(); - - bool youLJPtoGaiBanEnable = data->service->_paramSyncManager->get("焊前定位", "右侧连接片和盖板距离判定启用", false).toBool(); - double youLJPtoGaiBanMaxThreshold = data->service->_paramSyncManager->get("焊前定位", "右侧连接片和盖板距离(MAX)", 1.8).toDouble(); - double youLJPtoGaiBanMinThreshold = data->service->_paramSyncManager->get("焊前定位", "右侧连接片和盖板距离(MIN)", 0.0).toDouble(); - - QByteArray plcResult = "1"; - //data->getOriImg(0) = cv::imread("D://testImage//hqdw.bmp",-1); - cv::Mat sourceImg = data->getOriImg(0); - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - HDevEngineCpp::HDevProcedure proc("_3_HQDW_Inspection"); - HDevEngineCpp::HDevProcedureCall procedureCall(proc); - - HTuple in_Resolution(0.0349425), in_FilePath("./halconFiles/"); - HObject inputImage = MatToHObject(sourceImg); - - procedureCall.SetInputIconicParamObject("in_Image", inputImage); - procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); - procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); - procedureCall.Execute();//执行halcon程序 - HTuple out_ColorType; - HTuple out_Distance; - HTuple out_CCDistance; - HTuple make; - HObject out_DisplayImage; - //out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 - out_ColorType = procedureCall.GetOutputCtrlParamTuple("out_ColorType");//获取输出控制类变量 - //out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");//获取输出控制类变量 - out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量 - out_CCDistance = procedureCall.GetOutputCtrlParamTuple("out_CCDistance");//获取输出控制类变量 - make = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - out_DisplayImage = procedureCall.GetOutputIconicParamObject("out_DisplayImage");//获取输出控制类变量 - int flag = make.D(); - - // Output(HTuple): out_ColorType, 1, 铜; 2,铝 - - //正确的应该左边铝 右边铜 - double value1_1 = 0, value1_2 = 0, value2_1 = 0, value2_2 = 0; - bool jiXingEnable = data->service->_paramSyncManager->get("焊前定位", "焊前极性判定启用", false).toBool(); - if (flag == 1) - { - //circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 5); - //for (int i = 0; i < 2 ; i++) - //{ - // cv::line(Paint, cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4].D()), - // cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), - // cv::Scalar(0, 255, 0), 10); - //} - bool isNg = false; - TextRendererZH textPainter(Paint.cols, Paint.rows, 200); - Paint = HObject2Mat(out_DisplayImage); - int l = out_Distance.Length(); - if (out_Distance.Length() >= 3) { - value1_1 = out_Distance[1].D(); - value1_2 = out_Distance[2].D(); - textPainter.putText(Paint, "线段夹角:" + std::to_string(out_Distance[3].D()) + "°", cv::Point(0, 10), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铜极+铝极连接片中心距离:" + std::to_string(out_Distance[0].D()) + "mm", cv::Point(0, sourceImg.rows - 950), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "电芯上水平边缘和注液孔的中心圆的距离:" + std::to_string(out_Distance[1].D()) + "mm", cv::Point(0, sourceImg.rows - 750), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "电芯下水平边缘和注液孔的中心圆的距离:" + std::to_string(out_Distance[2].D()) + "mm", cv::Point(0, sourceImg.rows - 550), cv::Scalar(0, 255, 0)); - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(out_Distance[0].D())); - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr+2) + "_" + QByteArray::number(out_Distance[1].D())); - - data->sqlVec.insert({ "电芯上水平边缘和注液孔的中心圆的距离", out_Distance[1].D() }); - data->sqlVec.insert({ "电芯下水平边缘和注液孔的中心圆的距离", out_Distance[2].D() }); - } - if (out_CCDistance.Length() == 2) { - value2_1 = out_CCDistance[0].D(); - if (zuoLJPtoGaiBanMaxThreshold < value2_1 || zuoLJPtoGaiBanMinThreshold > value2_1) {//NG - textPainter.putText(Paint, "左侧连接片圆心和盖板圆心的距离:" + std::to_string(value2_1) + "mm", cv::Point(0, sourceImg.rows - 350), cv::Scalar(0, 0, 255)); - if (zuoLJPtoGaiBanEnable == true) - isNg = true; - } - else//OK - textPainter.putText(Paint, "左侧连接片圆心和盖板圆心的距离:" + std::to_string(value2_1) + "mm", cv::Point(0, sourceImg.rows - 350), cv::Scalar(0, 255, 0)); - - value2_2 = out_CCDistance[1].D(); - if (youLJPtoGaiBanMaxThreshold < value2_2 || youLJPtoGaiBanMinThreshold > value2_2) {//NG - textPainter.putText(Paint, "右侧连接片圆心和盖板圆心的距离:" + std::to_string(value2_2) + "mm", cv::Point(0, sourceImg.rows - 150), cv::Scalar(0, 0, 255)); - if(youLJPtoGaiBanEnable == true) - isNg = true; - } - else - textPainter.putText(Paint, "右侧连接片圆心和盖板圆心的距离:" + std::to_string(value2_2) + "mm", cv::Point(0, sourceImg.rows - 150), cv::Scalar(0, 255, 0)); - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(out_CCDistance[0].D())); - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_" + QByteArray::number(out_Distance[1].D())); - - data->sqlVec.insert({ "左侧连接片圆心和盖板圆心的距离", out_CCDistance[0].D() }); - data->sqlVec.insert({ "右侧连接片圆心和盖板圆心的距离", out_CCDistance[1].D() }); - } - - TextRendererZH textPainter2(Paint.cols, Paint.rows, 600); - int left = out_ColorType[0].D(); - //结果判定,铜在左边,铝在右边 - if (left == 2) - textPainter2.putText(Paint,"铜",cv::Point(0, 1500), cv::Scalar(0, 255, 0)); - else if (left == 1) - textPainter2.putText(Paint,"铝",cv::Point(0, 1500), cv::Scalar(0, 0, 255)); - else - textPainter2.putText(Paint,"异常",cv::Point(0, 1500), cv::Scalar(0, 0, 255)); - - int right = out_ColorType[1].D(); - if (right == 2) - textPainter2.putText(Paint,"铜",cv::Point(Paint.cols - 600, 1500), cv::Scalar(0, 0, 255)); - else if (right == 1) - textPainter2.putText(Paint,"铝",cv::Point(Paint.cols - 600, 1500), cv::Scalar(0, 255, 0)); - else - textPainter2.putText(Paint,"异常",cv::Point(Paint.cols - 600, 1500), cv::Scalar(0, 0, 255)); - - if ((left == 1 || right == 2) && jiXingEnable) - isNg = true; - - TextRendererZH textPainter3(Paint.cols, Paint.rows, 800); - if(isNg == true){ - textPainter3.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); - plcResult = "2"; - data->halconOK = false; - } - else { - textPainter3.putText(Paint, "OK", cv::Point(0, 50), cv::Scalar(0, 255, 0)); - } - } - else - { - TextRendererZH textPainter4(Paint.cols, Paint.rows, 500); - textPainter4.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255));//调机 - plcResult = "2"; - data->halconOK = false; - } - if (data->service->_paramSyncManager->get("通用设置","强制OK", false).toBool()) - plcResult = "1"; - data->insertResultImg(Paint); - sourceImg.release(); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - return true; - } - CATCH_EXCEPTIONS - exceptionResume(data, _detParams, address, "检测失败"); - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - return false; -} - -bool HanHou2D_halconEvaluate(std::shared_ptr data, const cv::Mat& sourceImg,const cv::Mat& segImg, cv::Mat& Paint, double& hanHouTongXingDu, int times,QMutex* mutex) { - double tongXingDuLimitHigh = data->service->_paramSyncManager->get("焊后", "焊后同心度mm(上限)", 1.8).toDouble(); - double tongXingDuLimitLow = data->service->_paramSyncManager->get("焊后", "焊后同心度mm(下限)", 0).toDouble(); - bool tongXingDuLimitEnable = data->service->_paramSyncManager->get("焊后", "焊后同心度判定启用", true).toBool(); - HDevEngineCpp::HDevProcedure proc("_3_Cal_HY_CC_Distance"); - HDevEngineCpp::HDevProcedureCall procedureCall(proc); - - HObject in_Image = MatToHObject(sourceImg); - HObject in_ImageSeg = MatToHObject(segImg); - double resolution = 0.013736; - HalconCpp::HTuple in_FliePath("./halconFiles/"), in_Resolution(resolution); - procedureCall.SetInputIconicParamObject("in_Image", in_Image); - procedureCall.SetInputIconicParamObject("in_ImageSeg", in_ImageSeg); - procedureCall.SetInputCtrlParamTuple("in_FliePath", in_FliePath); - procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); - procedureCall.Execute();//执行halcon程序 - HalconCpp::HTuple out_CCDistance = procedureCall.GetOutputCtrlParamTuple("out_CCDistance");//获取输出控制类变量 - HalconCpp::HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");//获取输出控制类变量 - HalconCpp::HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - HalconCpp::HTuple out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails");//获取输出控制类变量 - HalconCpp::HTuple InnerCircle_offset = procedureCall.GetOutputCtrlParamTuple("InnerCircle_offset");//获取输出控制类变量 - HalconCpp::HTuple OuterCircle_offset = procedureCall.GetOutputCtrlParamTuple("OuterCircle_offset");//外圆偏移(X向偏移,Y向偏移) - int flag = out_Flag.D(); - bool isNg = false; - TextRendererZH textPainter(Paint.cols, Paint.rows, 200); - QMutexLocker locker(mutex); - if (flag == 1){ - - - double CCDistance = out_CCDistance.D(); - textPainter.putText(Paint, "焊印同心度:" + std::to_string(CCDistance), cv::Point(0, 50), cv::Scalar(0, 255, 0)); - - std::string x1Text = std::to_string(InnerCircle_offset[0].D()); - x1Text = x1Text.substr(0, x1Text.find(".") + 4); - std::string y1Text = std::to_string(InnerCircle_offset[1].D()); - y1Text = y1Text.substr(0, y1Text.find(".") + 4); - textPainter.putText(Paint, "内圆偏移X:" + x1Text + "mm Y:" + y1Text + "mm", cv::Point(0, 250), cv::Scalar(0, 255, 0)); - - std::string x2Text = std::to_string(OuterCircle_offset[0].D()); - x2Text = x2Text.substr(0, x2Text.find(".") + 4); - std::string y2Text = std::to_string(OuterCircle_offset[1].D()); - y2Text = y2Text.substr(0, y2Text.find(".") + 4); - textPainter.putText(Paint, "外圆偏移X:" + x2Text + "mm Y:" + y2Text + "mm", cv::Point(0, 450), cv::Scalar(0, 255, 0)); - - for (int i = 0; i < out_Circle.Length() / 3; i++) { - cv::circle(Paint, cv::Point(out_Circle[i * 3 + 1].D(), out_Circle[i * 3].D()), out_Circle[i * 3 + 2].D(), cv::Scalar(0, 255, 0), 15); - } - if (CCDistance > tongXingDuLimitHigh || CCDistance < tongXingDuLimitLow){ - textPainter.putText(Paint, "同心度NG", cv::Point(10, 650), cv::Scalar(0, 0, 255)); - data->halconOK = false; - if(tongXingDuLimitEnable == true) - isNg = true; - } - } - else{ - textPainter.putText(Paint, "焊印抓取NG", cv::Point(10, 50), cv::Scalar(0, 0, 255)); - textPainter.putText(Paint, gbkToUtf8(out_NgTails.ToString().Text()), cv::Point(10, 450), cv::Scalar(0, 0, 255)); - if (tongXingDuLimitEnable == true) - isNg = true; - data->halconOK = false; - } - return isNg; -} -bool HanHou2D_handleAiEvaluate(std::shared_ptr data, hanHouJianCe* _detParams,const cv::Mat& sourceImg, cv::Mat& Paint,QMutex* mutex) { - double hanZhaFillterWidth = data->service->_paramSyncManager->get("焊后", "焊渣过滤值宽mm(上限)", 0.1).toDouble()/ 0.013736; - double hanZhaFillterHeight = data->service->_paramSyncManager->get("焊后", "焊渣过滤值高mm(上限)", 0.1).toDouble()/ 0.013736; - bool hanZhaEnable = data->service->_paramSyncManager->get("焊后", "焊渣判定启用", false).toBool(); - - cv::Mat forSeg; - sourceImg.copyTo(forSeg); - cv::resize(sourceImg, forSeg, cv::Size(), 0.5, 0.5); - - cv::Mat SegResult = ~_detParams->seg_rljHanZha->Evaluate(forSeg); - std::vector> contours; - cv::findContours(SegResult, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); - std::vector PaintRects; - std::vector>clsImgTmp; - bool isNg = false;; - for (int i = 0; i < contours.size(); i++) { - cv::Rect rect = cv::boundingRect(contours[i]); - if (rect.width > hanZhaFillterWidth || rect.height > hanZhaFillterHeight) { - cv::Mat img = cutImg2Cls(rect, forSeg); - bool clsIsNg = false; - int clsRes = _detParams->cls_rljHanZha->Evaluate(img); - if (clsRes == 1) - clsIsNg = true; - if (clsIsNg == true) { - rect.x *= 2; rect.y *= 2; rect.width *= 2; rect.height *= 2; - PaintRects.push_back(rect); - isNg = true; - } - clsImgTmp.push_back({ clsIsNg == true ? "NG" : "OK",img }); - } - } - QMutexLocker locker(mutex); - for (auto& rect : PaintRects) { - cv::rectangle(Paint, cv::Rect(rect.x + rect.width / 2 -64, rect.y + rect.height / 2 -64, 128, 128), cv::Scalar(0, 0, 255), 3); - } - data->insertClsOriginImg(clsImgTmp); - return isNg; -} -QByteArray getHanHouJianCe2DSendResult(bool isNg1,bool isNg2) { - if (isNg1 == false && isNg2 == false) //都OK发1 - return "1"; - else if (isNg1 == true && isNg2 == false)//第一次NG发2 - return "2"; - else if (isNg1 == false && isNg2 == true)//第二次NG发3 - return "3"; - else if (isNg1 == true && isNg2 == true)//两次都NG发4 - return "4"; - else//为了DEBUG - return "5"; -} -bool HanHouJianCe2D(std::shared_ptr data, hanHouJianCe* _detParams, sx_581_address address){ - try - { - //data->SNcode = "test"; - //data->oriImgs.clear(); - //data->oriImgs.push_back(cv::imread("D:\\testImage\\T.bmp",-1)); - //data->oriImgs.push_back(cv::imread("D:\\testImage\\L_OK.bmp", -1)); -#pragma region 错误处理 - - if (data->getOriImgSize() < 2) { - exceptionResume(data, _detParams, address, "图片数量不满足"); - return true; - } - if (data->getOriImg(0).cols == 200 || (data->getOriImg(1).cols == 200)) { - data->halconOK = false; - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) { - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - } - TextRendererZH textPainter(Paint.cols, Paint.rows, 40); - textPainter.putText(Paint, "图片数量不满足", cv::Point(0, 0), cv::Scalar(0, 255, 0)); - data->insertResultImg(Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_4");//结果反馈 - return true; - } -#pragma endregion - cv::Mat Paint1, Paint2; - data->getOriImg(0).copyTo(Paint1); - data->getOriImg(1).copyTo(Paint2); - if (Paint1.channels() == 1) { - cvtColor(Paint1, Paint1, cv::COLOR_GRAY2BGR); - } - if (Paint2.channels() == 1) { - cvtColor(Paint2, Paint2, cv::COLOR_GRAY2BGR); - } - TextRendererZH textPainter(Paint1.cols, Paint1.rows, 150); - QByteArray plcResult = "1"; - double hanHouTongXingDu1 = -1; - double hanHouTongXingDu2 = -1; - cv::Mat forSeg1, forSeg2; - double resizeRate = 0.25; - bool isNg1 = false, isNg2 = false; - QMutex mutex1, mutex2; - - cv::resize(data->getOriImg(0), forSeg1, cv::Size(), resizeRate, resizeRate); - cv::Mat seg1 = _detParams->seg_rljHanYinZhuaQu->Evaluate(forSeg1); - data->insertSegOriginImg(seg1); - cv::Rect tongRect = findMaxAreaContour(~seg1); - if (tongRect.width < 100 || tongRect.height < 100) { - isNg1 = true; - } - - cv::resize(data->getOriImg(1), forSeg2, cv::Size(), resizeRate, resizeRate); - cv::Mat seg2 = _detParams->seg_rljHanYinZhuaQu->Evaluate(forSeg2); - data->insertSegOriginImg(seg2); - cv::Rect lvRect = findMaxAreaContour(~seg2); - if (lvRect.width < 100 || lvRect.height < 100) { - isNg2 = true; - } - - //判斷焊印結果 - if (isNg1 == true || isNg2 == true) {//判断存图 - data->halconOK = false; - plcResult = getHanHouJianCe2DSendResult(isNg1, isNg2); - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - plcResult = "1"; - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult); - if (isNg1 == true) textPainter.putText(Paint1, "焊印抓取失败", cv::Point(0, 0), cv::Scalar(0, 0, 255)); - if (isNg2 == true) textPainter.putText(Paint2, "焊印抓取失败", cv::Point(0, 0), cv::Scalar(0, 0, 255)); - cv::Mat PaintSum; - cv::vconcat(Paint1, Paint2, PaintSum); - data->insertResultImg(PaintSum); - return true; - } - - auto futrue1 = std::async(std::launch::async, &HanHou2D_halconEvaluate, data, data->getOriImg(0), seg1, std::ref(Paint1), std::ref(hanHouTongXingDu1), 0, &mutex1); - auto futrue2 = std::async(std::launch::async, &HanHou2D_halconEvaluate, data, data->getOriImg(1), seg2, std::ref(Paint2), std::ref(hanHouTongXingDu2), 2, &mutex2); - - futrue1.wait(); - futrue2.wait(); - isNg1 = futrue1.get(); - isNg2 = futrue2.get(); - - auto futrue3 = std::async(std::launch::async, &HanHou2D_handleAiEvaluate, data, _detParams, data->getOriImg(0), std::ref(Paint1), &mutex1); - auto futrue4 = std::async(std::launch::async, &HanHou2D_handleAiEvaluate, data, _detParams, data->getOriImg(1), std::ref(Paint2), &mutex2); - - futrue3.wait(); - futrue4.wait(); - - futrue3.get(); - futrue4.get(); - - std::vector> hanYinClsImg; - - int tongClsRes = 0, lvClsRes = 0; - - { - auto tongClsImg = cutImg2Cls(tongRect, forSeg1, cv::Size(256, 256)); - tongClsRes = _detParams->cls_hanYinLv->Evaluate(tongClsImg); - double prob = _detParams->cls_hanYinLv->getProbability(); - hanYinClsImg.push_back({ "tongHY_Res" + std::to_string(tongClsRes) + "_prob" + std::to_string(prob),tongClsImg }); - } - - { - auto lvClsImg = cutImg2Cls(lvRect, forSeg2, cv::Size(256, 256)); - lvClsRes = _detParams->cls_hanYinLv->Evaluate(lvClsImg); - double prob = _detParams->cls_hanYinLv->getProbability(); - hanYinClsImg.push_back({ "lvHY" + std::to_string(tongClsRes) + "_prob" + std::to_string(prob),lvClsImg }); - } - - if (lvClsRes == 1) { - textPainter.putText(Paint2, "焊印CLS-NG", cv::Point(0, 650), cv::Scalar(0, 0, 255)); - if (data->service->_paramSyncManager->get("焊后", "焊印CLS判定启用", true).toBool()) { - isNg2 = true; - } - } - else - textPainter.putText(Paint2, "焊印CLS-OK", cv::Point(0, 650), cv::Scalar(0, 255, 0)); - - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(hanHouTongXingDu1)); - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(hanHouTongXingDu2)); - - - - if (isNg1 == true || isNg2 == true) {//判断存图 - data->halconOK = false; - } - - plcResult = getHanHouJianCe2DSendResult(isNg1, isNg2); - - //拼装结果图 - cv::Mat PaintSum; - cv::vconcat(Paint1, Paint2, PaintSum); - data->insertResultImg(PaintSum); - if (data->service->_paramSyncManager->get("通用设置","强制OK", false).toBool()) - plcResult = "1"; - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult); - return true; - } - CATCH_EXCEPTIONS - exceptionResume(data, _detParams, address, "检测失败"); - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - return false; - -} - -bool HanHouJianCe3D(std::shared_ptr data, hanHouJianCe* _detParams, sx_581_address address) { - try { - qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - std::vector < std::string> defects = { }; - ///////////////////取图//处理////////////////// - if (data->getOriImgSize() < 1) - { - qCritical() << "图片数量不满足要求:" << data->getOriImgSize(); - return false; - } - if (data->getOriImg(0).rows == 100) { - cv::Mat Paint; - data->getOriImg(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->getOriImg(0); - if (src1.channels() != 3) - cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); - else - src1.copyTo(Paint); - - TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - textPainter.putText(Paint, "OK", 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); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - //data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects);//发送图标操作 - data->insertResultImg(Paint); - return true; - } - CATCH_EXCEPTIONS - exceptionResume(data, _detParams, address, "检测失败"); - return false; - - -} - - -mission* createMission() { - return new _581_Ruanlianjie_hanqian_hanhou(); -} -void destroyMission(mission* _mission) { - delete _mission; -} diff --git a/src/mission/602/581_Ruanlianjie_hanqian_hanhou/581_Ruanlianjie_hanqian_hanhou.h b/src/mission/602/581_Ruanlianjie_hanqian_hanhou/581_Ruanlianjie_hanqian_hanhou.h deleted file mode 100644 index 7fd86b8..0000000 --- a/src/mission/602/581_Ruanlianjie_hanqian_hanhou/581_Ruanlianjie_hanqian_hanhou.h +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace HDevEngineCpp; -using namespace HalconCpp; -class hanQianDingWeiParams { - -}; -class hanHouJianCe { -public: - handdleAI::pSegmentation* seg_rljHanYinZhuaQu = nullptr; - handdleAI::pSegmentation* seg_rljHanZha = nullptr; - handdleAI::pClassification* cls_rljHanZha = nullptr; - handdleAI::pClassification* cls_hanYinTong = nullptr; - handdleAI::pClassification* cls_hanYinLv = nullptr; - int ngCnt = 0; -}; - -bool HanQianDingWei(std::shared_ptr data, hanQianDingWeiParams* _detParams, sx_581_address address); -bool HanHouJianCe2D(std::shared_ptr data, hanHouJianCe* _detParams, sx_581_address address); -bool HanHouJianCe3D(std::shared_ptr data, hanHouJianCe* _detParams, sx_581_address address); - -class _581_Ruanlianjie_hanqian_hanhou : public mission { -public: - - _581_SX_Single_triggerTemplate dingwei_1; - _581_SX_Single_triggerTemplate dingwei_2; - - _581_SX_Single_triggerTemplate jiance_2d_1; - _581_SX_Single_triggerTemplate jiance_2d_2; - _581_SX_Single_triggerTemplate jiance_3d_1; - _581_SX_Single_triggerTemplate jiance_3d_2; - - hanQianDingWeiParams hanqiandingweiparams; - std::vectorhanhoujiance2dparams = std::vector(2); - hanHouJianCe hanhoujiance3dparams; - - bool initOnce = false; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath(""); - myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); - - if (initOnce == false) { - - hanhoujiance2dparams[0].seg_rljHanYinZhuaQu = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanYinZhuaQu.BHD", 64, 0); - hanhoujiance2dparams[1].seg_rljHanYinZhuaQu = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanYinZhuaQu.BHD", 64, 1); - - hanhoujiance2dparams[0].seg_rljHanZha = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanZha.BHD", 64, 0); - hanhoujiance2dparams[1].seg_rljHanZha = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanZha.BHD", 64, 1); - - hanhoujiance2dparams[0].cls_rljHanZha = handdleAI::CreateClsObjV3("./handleAiModels/cls_rljHanZha.BHD", 0, 1); - hanhoujiance2dparams[1].cls_rljHanZha = handdleAI::CreateClsObjV3("./handleAiModels/cls_rljHanZha.BHD", 1, 1); - - hanhoujiance2dparams[0].cls_hanYinLv = handdleAI::CreateClsObjV3("./handleAiModels/cls_hanYinTong.BHD", 0, 1); - hanhoujiance2dparams[1].cls_hanYinLv = handdleAI::CreateClsObjV3("./handleAiModels/cls_hanYinTong.BHD", 1, 1); - - hanhoujiance2dparams[0].cls_hanYinLv = handdleAI::CreateClsObjV3("./handleAiModels/cls_hanYinLv.BHD", 0, 1); - hanhoujiance2dparams[1].cls_hanYinLv = handdleAI::CreateClsObjV3("./handleAiModels/cls_hanYinLv.BHD", 1, 1); - initOnce = true; - } - } - bool initCustom() { -#pragma region 注册触发器回调 - dingwei_1.init("Camera1", "焊前定位-相机1(前)", { { 4900, 1,{4910},"4902","4904",4930} }, 1, &hanqiandingweiparams, _serviceManager, bridge, HanQianDingWei,"焊前定位CCD"); - dingwei_2.init("Camera2", "焊前定位-相机2(后)", { { 5800, 1,{5810},"5802","5804",5830} }, 1, &hanqiandingweiparams, _serviceManager, bridge, HanQianDingWei,"焊前定位CCD"); - - jiance_2d_1.init("Camera3", "焊后检测2D-相机1(前)", { { 5400, 1,{5410},"5402","5404",5430} }, 2, &hanhoujiance2dparams[0], _serviceManager, bridge, HanHouJianCe2D, "焊后检测CCD"); - jiance_3d_1.init("Camera4", "焊后检测3D-相机1(前)", { { 5500, 1,{5510},"5502","5504",5530} }, 1, &hanhoujiance3dparams, _serviceManager, bridge, HanHouJianCe3D,"焊后检测CCD"); - jiance_2d_2.init("Camera5", "焊后检测2D-相机2(后)", { { 5600, 1,{5610},"5602","5604",5630} }, 2, &hanhoujiance2dparams[1], _serviceManager, bridge, HanHouJianCe2D, "焊后检测CCD"); - jiance_3d_2.init("Camera6", "焊后检测3D-相机2(后)", { { 5700, 1,{5710},"5702","5704",5730} }, 1, &hanhoujiance3dparams, _serviceManager, bridge, HanHouJianCe3D,"焊后检测CCD"); -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/602/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.cpp b/src/mission/602/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.cpp deleted file mode 100644 index 092a003..0000000 --- a/src/mission/602/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#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 - { - QByteArray plcResult = "1"; - QString detResult = "OK"; - cv::Mat sourceImg = data->getOriImg(0); - //sourceImg = cv::imread("D://readSnEmpty13-12-30-14Camera1_13-12-32-38_Count0.bmp"); - cv::Mat Paint; - sourceImg.copyTo(Paint); - - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - 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->insertSegOriginImg(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, "NG", 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; - } - } - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - data->insertResultImg(Paint); - return true; - } - } - CATCH_EXCEPTIONS - exceptionResume(data, _detParams, address,"检测程序异常"); - return true; -} - -bool erzhuCanYe(std::shared_ptr data, canyeParams* _detParams, sx_581_address address) -{ - QByteArray plcResult = "1"; - QByteArray data1 = "1"; - QByteArray data2 = "1"; - QString detResult = "OK"; - cv::Mat sourceImg = data->getOriImg(0); - 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, detResult.toStdString(), cv::Point(4000, 50), cv::Scalar(0, 255, 0)); - - //数据发送 - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 0) + "_" + data1);//数据1 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + data2);//数据1 - data->aiDetOK = true; - data->insertResultImg(Paint); - - return true; -} - -mission* createMission() { - return new _581_YiCiZhuYe_canye(); -} -void destroyMission(mission* _mission) { - delete _mission; -} - diff --git a/src/mission/602/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.h b/src/mission/602/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.h deleted file mode 100644 index f1b5230..0000000 --- a/src/mission/602/581_YiCiZhuYe_canye/581_YiCiZhuYe_canye.h +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; -#pragma endregion -class canyeParams { -public: - handdleAI::pSegmentation* segDingWei = nullptr; - handdleAI::pSegmentation* segDanYe = 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.segDanYe = 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/602/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.cpp b/src/mission/602/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.cpp deleted file mode 100644 index bc56747..0000000 --- a/src/mission/602/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include <602_RuanLianJie_dinggai.h> - -mission* createMission() { - return new _581_YuHan_hanqian(); -} - -void destroyMission(mission* _mission) { - delete _mission; -} \ No newline at end of file diff --git a/src/mission/602/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.h b/src/mission/602/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.h deleted file mode 100644 index 1c5c8c1..0000000 --- a/src/mission/602/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.h +++ /dev/null @@ -1,427 +0,0 @@ -#include -#include -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; -#pragma endregion -class RuanLianJie_dinnggai { -public: - handdleAI::pSegmentation* segDingwei1 = nullptr; - handdleAI::pSegmentation* seg = nullptr; - handdleAI::pClassification* cls = nullptr; - cv::Mat TP1IMG, TP2Paint; - QByteArray kemaResult = "1"; -}; - -cv::Rect getImageLocateRect(cv::Mat& src, handdleAI::pSegmentation* seg, double bounus = 0.1) { - cv::Mat tmpImg; - cv::resize(src, tmpImg, cv::Size(), bounus, bounus); - cv::Mat ouput = ~seg->Evaluate(tmpImg); - cv::Rect rect = findMaxAreaContour(ouput); - rect.x /= bounus; rect.y /= bounus; - rect.width /= bounus; rect.height /= bounus; - return rect; -} - -bool dinggaijiance(std::shared_ptr data, RuanLianJie_dinnggai* _detParams, sx_581_address address) { - try { -#if 0 - data->getOriImg(0) = cv::imread("D:\\testImage\\QRCODE.bmp", -1); -#endif - //存图数据加保存队列,加锁,避免数据访问冲突 - std::vectordefects; - double Resolution = 0.01424; - cv::Mat sourceImg; - data->getOriImg(0).copyTo(sourceImg); - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - if (address.triggerValue == 2)//kema - { - HDevEngineCpp::HDevProcedure proc("_3_Cal_FBF_Distance");; - HDevEngineCpp::HDevProcedureCall procedureCall(proc); - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, 8); - HObject in_Image = MatToHObject(sourceImg); - HalconCpp::HTuple in_Resolution(Resolution), in_FilePath("./halconFiles/"); - procedureCall.SetInputIconicParamObject("in_Image", in_Image); - procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); - procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); - procedureCall.Execute();//执行halcon程序 - HalconCpp::HTuple out_LinePoint, out_Circle, out_Flag, out_Distance; - out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 - out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");//获取输出控制类变量 - out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量 - double keMaShangBianYuanLimitHigh = data->service->_paramSyncManager->get("刻码检测", "刻码上边缘到防爆阀距离(上限)mm", 5.00).toDouble(); - double keMaShangBianYuanLimitLow = data->service->_paramSyncManager->get("刻码检测", "刻码上边缘到防爆阀距离(下限)mm", 3.00).toDouble(); - bool keMaShangBianYuanEnable= data->service->_paramSyncManager->get("刻码检测", "刻码上边缘到防爆阀距离判定启用", false).toBool(); - - double qrCodeSizeLimitHigh = data->service->_paramSyncManager->get("刻码检测", "二维码尺寸(上限)mm", 9.30).toDouble(); - double qrCodeSizeLimitLow = data->service->_paramSyncManager->get("刻码检测", "二维码尺寸(下限)mm", 8.70).toDouble(); - bool qrCodeSizeEnable = data->service->_paramSyncManager->get("刻码检测", "二维码判定启用", false).toBool(); - - double LimitHigh2 = data->service->_paramSyncManager->get("防爆阀检测", "右边缘到防爆阀圆心(上限)mm", 2.00).toDouble(); - double LimitLow2 = data->service->_paramSyncManager->get("防爆阀检测", "右边缘到防爆阀圆心(下限)mm", 0.00).toDouble(); - bool Enable2 = data->service->_paramSyncManager->get("防爆阀检测", "右边缘到防爆阀圆心判定启用", false).toBool(); - if (out_Flag.D() == 1) - { - int crossLineLength = 50; - TextRendererZH textPainter(Paint.cols, Paint.rows, 140); - for (int i = 0; i < out_LinePoint.Length() / 4; i++) - { - cv::line(Paint, cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4].D()), - cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), - cv::Scalar(0, 255, 0), 10); - } - double distance = out_Distance[0].D(); - //distance -= out_Circle[2].D() * Resolution;//CHEAT!!! - circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 5); - { - std::string text = "二维码右竖直边和防爆阀圆心距离最小距离:" + std::to_string(out_Distance[0].D()); - text = text.substr(0, text.find(".") + 4) + "mm"; - if (distance > LimitHigh2) {//NG - defects.push_back("二维码右距离NG"); - data->halconOK = false; - textPainter.putText(Paint, (text).c_str(), cv::Point(100, 500), cv::Scalar(0, 0, 255)); - if (Enable2 == true) - _detParams->kemaResult = "2"; - } - else {//OK - textPainter.putText(Paint, (text).c_str(), cv::Point(100, 500), cv::Scalar(0, 255, 0)); - } - - } - double distance2 = out_Distance[1].D();//二维码的宽度值 - { - QByteArray::number(distance2); - std::string text = "二维码的上边缘到防爆阀下边缘的距离:" + std::to_string(distance2); - text = text.substr(0, text.find(".") + 4) + "mm"; - if (distance2 > keMaShangBianYuanLimitHigh || distance2 < keMaShangBianYuanLimitLow) {//NG - defects.push_back("二维码上距离NG"); - data->halconOK = false; - textPainter.putText(Paint, (text).c_str(), cv::Point(100, 650), cv::Scalar(0, 0, 255)); - if (keMaShangBianYuanEnable == true) - _detParams->kemaResult = "2"; - } - else {//OK - textPainter.putText(Paint, (text).c_str(), cv::Point(100, 650), cv::Scalar(0, 255, 0)); - } - } - double distance3 = out_Distance[2].D();//二维码下方字符串的宽度值 - { - std::string text = "二维码的宽度值:" + std::to_string(distance3); - text = text.substr(0, text.find(".") + 4) + "mm"; - if (distance3 > qrCodeSizeLimitHigh || distance3 < qrCodeSizeLimitLow) {//NG - defects.push_back("二维码宽度NG"); - data->halconOK = false; - textPainter.putText(Paint, (text).c_str(), cv::Point(100, 800), cv::Scalar(0, 0, 255)); - if (qrCodeSizeEnable == true) - _detParams->kemaResult = "2"; - } - else { - textPainter.putText(Paint, (text).c_str(), cv::Point(100, 800), cv::Scalar(0, 255, 0)); - } - - } - double distance4 = out_Distance[2].D();//二维码下方字符串的宽度值 - { - std::string text = "二维码的高度值:" + std::to_string(distance4); - defects.push_back("二维码高度NG"); - text = text.substr(0, text.find(".") + 4) + "mm"; - if (distance4 > qrCodeSizeLimitHigh || distance4 < qrCodeSizeLimitLow) {//NG - data->halconOK = false; - textPainter.putText(Paint, (text).c_str(), cv::Point(100, 950), cv::Scalar(0, 0, 255)); - if (qrCodeSizeEnable == true) - _detParams->kemaResult = "2"; - } - else { - textPainter.putText(Paint, (text).c_str(), cv::Point(100, 950), cv::Scalar(0, 255, 0)); - } - } - } - else - { - qDebug() << __FUNCTION__ << "line:" << __LINE__ << "二维码error"; - TextRendererZH textPainter2(Paint.cols, Paint.rows, 500); - textPainter2.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); - _detParams->kemaResult = "2";//暫存結果 - data->halconOK = false; - - } - //#endif - Paint.copyTo(_detParams->TP2Paint); - } - - else if (address.triggerValue == 1)//jizhu1 - { - sourceImg.copyTo(_detParams->TP1IMG); - } - - else if (address.triggerValue == 3)//jizhu2 - { - Paint = cv::Mat(_detParams->TP1IMG.rows, _detParams->TP1IMG.cols * 3, CV_8UC1); - _detParams->TP1IMG.copyTo(Paint(cv::Rect(0, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows))); - sourceImg.copyTo(Paint(cv::Rect(_detParams->TP1IMG.cols, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows))); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, 8); - _detParams->TP2Paint.copyTo(Paint(cv::Rect(_detParams->TP1IMG.cols * 2, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows))); - cv::Mat PaintPart2 = Paint(cv::Rect(_detParams->TP1IMG.cols, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows)); - HDevEngineCpp::HDevProcedure proc("_3_Cal_JZ_Distance");; - HDevEngineCpp::HDevProcedureCall procedureCall(proc); - HObject in_Image1, in_Image2; - in_Image1 = MatToHObject(_detParams->TP1IMG); - in_Image2 = MatToHObject(sourceImg); - HalconCpp::HTuple in_FilePath("./halconFiles/"), in_Resolution(Resolution); - procedureCall.SetInputIconicParamObject("in_Image1", in_Image1); - procedureCall.SetInputIconicParamObject("in_Image2", in_Image2); - procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); - procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); - procedureCall.Execute();//执行halcon程序 - HalconCpp::HTuple out_Edgedistance, out_Distance, out_LinePoint, out_Flag; - out_Edgedistance = procedureCall.GetOutputCtrlParamTuple("out_Edgedistance");//获取输出控制类变量 - out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量 - out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 - out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - if (out_Flag.D() == 1) - { - for (int i = 0; i < 4; i++) - { - cv::line(Paint, cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4].D()), - cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), - cv::Scalar(0, 255, 0), 15); - } - for (int i = 4; i < 8; i++) - { - cv::line(PaintPart2, cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4].D()), - cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), - cv::Scalar(0, 255, 0), 15); - } - double Distance = out_Distance.D(); - TextRendererZH textPainter(Paint.cols, Paint.rows, 280); - //Paint - { - std::string text = "垂直间距:" + std::to_string(out_Edgedistance[0].D()); - //data3 = QByteArray::number(out_Edgedistance[0].D()); - text = text.substr(0, text.find(".") + 4) + "mm"; - textPainter.putText(Paint, - (text).c_str(), - cv::Point(50, 50), cv::Scalar(0, 255, 0)); - } - { - //data4 = QByteArray::number(out_Edgedistance[1].D()); - std::string text = "水平间距:" + std::to_string(out_Edgedistance[1].D()); - text = text.substr(0, text.find(".") + 4) + "mm"; - textPainter.putText(Paint, - (text).c_str(), - cv::Point(50, 300), cv::Scalar(0, 255, 0)); - } - { - //data5 = QByteArray::number(out_Edgedistance[2].D()); - std::string text = "垂直间距:" + std::to_string(out_Edgedistance[2].D()); - text = text.substr(0, text.find(".") + 4) + "mm"; - textPainter.putText(PaintPart2, - (text).c_str(), - cv::Point(50, 50), cv::Scalar(0, 255, 0)); - } - { - //data6 = QByteArray::number(out_Edgedistance[3].D()); - std::string text = "水平间距:" + std::to_string(out_Edgedistance[3].D()); - text = text.substr(0, text.find(".") + 4) + "mm"; - textPainter.putText(PaintPart2, - (text).c_str(), - cv::Point(50, 300), cv::Scalar(0, 255, 0)); - } - /*{ - std::string text = "极柱间距:" + std::to_string(Distance); - text = text.substr(0, text.find(".") + 4) + "mm"; - putTextHusky(Paint, - utf8_to_gbk(text).c_str(), - cv::Point(50, 550), cv::Scalar(0, 0, 255), 280); - putTextHusky(PaintPart2, - utf8_to_gbk(text).c_str(), - cv::Point(50, 550), cv::Scalar(0, 0, 255), 280); - }*/ - - } - else - { - data->halconOK = false; - TextRendererZH textPainter1(Paint.cols, Paint.rows, 500); - textPainter1.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); - } - } - sourceImg.release(); - - if (address.triggerValue == 3) { - if (_detParams->kemaResult == "2") - data->halconOK = false; - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - _detParams->kemaResult = "1"; - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + _detParams->kemaResult);//结果反馈 - _detParams->kemaResult = "1";//fuwei - data->insertResultImg(Paint); - } - data->service->_missionResultHandle->toBarChart(data->SNcode, defects); - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 500); - textPainter.putText(Paint, "NG", cv::Point(0, 0), 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");//结果反馈 - return true; -} -bool majiarerong(std::shared_ptr data, RuanLianJie_dinnggai * _detParams, sx_581_address address) { - try { - std::vectordefects; - double areaLimitHigh = data->service->_paramSyncManager->get("马甲热熔", "热熔面积mm²(上限)", 22.5).toDouble(); - double areaLimitLow = data->service->_paramSyncManager->get("马甲热熔", "热熔面积mm²(下限)", 7.5).toDouble(); - //bool maJiaEnable = data->service->_paramSyncManager->get("马甲热熔", "马甲热熔判定启用", false).toBool(); - cv::Mat Paint; - //data->getOriImg(0) = cv::imread("D:\\testImage\\majia2.bmp", -1); - cv::Mat src = data->getOriImg(0); - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - - HDevEngineCpp::HDevProcedure proc("_3_MeltingPoint_Inspection"); - HDevProcedureCall procedureCall(proc); - - HObject in_Image = MatToHObject(src); - procedureCall.SetInputIconicParamObject("in_Image", in_Image); - - procedureCall.SetInputCtrlParamTuple("in_Resolution", 0.0425339); - procedureCall.Execute();//执行halcon程序 - - HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");//获取输出控制类变量 - HTuple out_CCDistance = procedureCall.GetOutputCtrlParamTuple("out_CCDistance");//获取输出控制类变量 - HTuple out_X = procedureCall.GetOutputCtrlParamTuple("out_X");//获取输出控制类变量 - HTuple out_Y = procedureCall.GetOutputCtrlParamTuple("out_Y");//获取输出控制类变量 - HTuple out_Areas = procedureCall.GetOutputCtrlParamTuple("out_Areas");//获取输出控制类变量 - HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出图像类变量 - HTuple out_NgDetails = procedureCall.GetOutputCtrlParamTuple("out_NgDetails");//获取输出图像类变量 - int flag = out_Flag.D(); - bool isAreaNg = false, isCountNg = false; - QByteArray plcResult = "1"; - TextRendererZH textPainter(Paint.cols, Paint.rows, 120); - int l = out_Circle.Length(), l2 = out_X.Length(); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5);//缩小结果图 - - if (flag == 1) { - for (int i = 0; i < out_Circle.Length() / 3 - 1; i++) { - cv::circle(Paint, cv::Point(out_Circle[i * 3 + 1].D(), out_Circle[i * 3].D()) / 2, out_Circle[i * 3 + 2].D() / 2, cv::Scalar(0, 255, 0), 2); - } - for (int i = 0; i < out_X.Length() && i < out_Y.Length(); i++) { - Paint.at(out_Y[i].D() / 2, out_X[i].D() / 2) = cv::Vec3b(0, 0, 255); - } - for (int i = 0; i < out_Areas.Length(); i++) { - double area = out_Areas[i].D(); - std::string valueText = std::to_string(out_Areas[i].D()); - valueText.substr(0, valueText.find(".") + 2); - if (area > areaLimitHigh || area < areaLimitLow) {//NG - textPainter.putText(Paint, "热熔点面积" + std::to_string(i + 1) + ":" + valueText, cv::Point(0, 200 + i * 120), cv::Scalar(0, 0, 255)); - defects.push_back("热熔面积NG"); - data->halconOK = false; - isAreaNg = true; - } - else { - textPainter.putText(Paint, "热熔点面积" + std::to_string(i + 1) + ":" + valueText, cv::Point(0, 200 + i * 120), cv::Scalar(0, 255, 0)); - } - } - } - else { - defects.push_back("热熔不良"); - isCountNg = true; - data->halconOK = false; - textPainter.putText(Paint, gbkToUtf8(out_NgDetails.ToString().Text()), cv::Point(0, 500), cv::Scalar(0, 255, 0)); - } - TextRendererZH textPainter2(Paint.cols, Paint.rows, 500); - - - if (isCountNg == true || isAreaNg == true) { - textPainter2.putText(Paint, "NG", cv::Point(0, 0), cv::Scalar(0, 0, 255)); - data->halconOK = false; - } - else - textPainter.putText(Paint, "OK", cv::Point(0, 0), cv::Scalar(0, 255, 0)); - data->insertResultImg(Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_1");//铜热熔面积 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_1");//铜热熔点数 - - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 4)+ "_1");//铝热熔面积 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_1");//铝热熔点数 - data->service->_missionResultHandle->toBarChart(data->SNcode, defects); - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 500); - textPainter.putText(Paint, "NG", cv::Point(0, 0), cv::Scalar(0, 255, 0)); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(Paint); - QByteArray plcResult ="1"; - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - plcResult = "1"; - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_"+ plcResult);//铜热熔面积 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_1");//铜热熔点数 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_1");//铝热熔面积 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_1");//铝热熔点数 - return true; -} - -class _581_YuHan_hanqian : public mission { -public: - _581_SX_Single_triggerTemplate< RuanLianJie_dinnggai> dibu_1; - _581_SX_Single_triggerTemplate< RuanLianJie_dinnggai> dibu_2; - _581_SX_Single_triggerTemplate< RuanLianJie_dinnggai> dibu_3; - _581_SX_Single_triggerTemplate< RuanLianJie_dinnggai> dibu_4; - - - - RuanLianJie_dinnggai DetParams1; - RuanLianJie_dinnggai DetParams2; - RuanLianJie_dinnggai DetParams3; - RuanLianJie_dinnggai DetParams4; - - - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath(""); - myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); - - } - bool initCustom() { -#pragma region 注册触发器回调 - dibu_1.init("Camera1", "顶盖检测刻码后-相机1", { { 5000, 1,{5010},"5002","5004",-1},{ 5000, 2,{5010},"5002","5004",-1},{ 5000, 3,{5010},"5002","5004",5030} }, 1, &DetParams1, _serviceManager, bridge, dinggaijiance, "防爆阀CCD"); - dibu_2.init("Camera2", "顶盖检测刻码后-相机2", { { 5100, 1,{5110},"5102","5104",-1},{ 5100, 2,{5110},"5102","5104",-1},{ 5100, 3,{5110},"5102","5104",5130} }, 1, &DetParams2, _serviceManager, bridge, dinggaijiance, "防爆阀CCD"); - dibu_3.init("Camera3", "马甲热熔检测-相机1", { { 5200, 1,{5210},"5202","5204",5230 }}, 1, &DetParams3, _serviceManager, bridge, majiarerong, "马甲热熔CCD"); - dibu_4.init("Camera4", "马甲热熔检测-相机2", { { 5300, 1,{5310},"5302","5304",5330} }, 1, &DetParams4, _serviceManager, bridge, majiarerong, "马甲热熔CCD"); -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/602/CMakeLists.txt b/src/mission/602/CMakeLists.txt deleted file mode 100644 index f9a95fd..0000000 --- a/src/mission/602/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# 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 ${}) diff --git a/src/mission/602/YH/581_YuHan_hanhou/581_YuHan_hanhou.cpp b/src/mission/602/YH/581_YuHan_hanhou/581_YuHan_hanhou.cpp deleted file mode 100644 index d275ca3..0000000 --- a/src/mission/602/YH/581_YuHan_hanhou/581_YuHan_hanhou.cpp +++ /dev/null @@ -1,584 +0,0 @@ -#include <581_YuHan_hanhou.h> - -std::string controlAccuracy(float num, int length) { - std::string resultString = std::to_string(num); - resultString = resultString.substr(0, resultString.find(".") + length + 1); - return resultString; -} - -void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint, - bool& silieResult, bool& fanZheResult, - cv::Point offset, handdleAI::pClassification* clsPtr, std::vector>& clsImgs,cv::Size fillter = cv::Size(200,200)) { - - std::vector> contours; - cv::findContours(segRes, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); - int cnt = 0; - for (int i = 0; i < contours.size(); i++) { - cv::Rect originRect = cv::boundingRect(contours[i]); - cv::Rect rect = originRect; - //rect.x += offset.x; - //rect.y += offset.y; - - if (originRect.width < fillter.width || originRect.height < fillter.height) - continue; - std::vector clsImgVec = cutImg2ClsVec(rect, src); - bool isNg = false; - for (auto& clsImg : clsImgVec) { - int Result = clsPtr->Evaluate(clsImg); - double prob = clsPtr->getProbability(); - if (Result == 1 && prob > 0.9)isNg = true; - clsImgs.push_back({ "result" + std::to_string(Result) + "_prob" + std::to_string(prob) ,clsImg }); - } - - if (isNg == true) - { - cv::Scalar color = cv::Scalar(0, 255, 255, 30); - //cv::rectangle(Paint, originRect, color, 4); - drawContours(Paint, contours, i, cv::Scalar(0, 255, 255, 30), 3, cv::LINE_8, cv::noArray(), INT_MAX, cv::Point(offset.x, offset.y)); - //putTextHusky(Paint, utf8_to_gbk("NG").c_str(), cv::Point(originRect.x - originRect.width / 2, originRect.y - originRect.height / 2 - 50), cv::Scalar(0, 255, 0), 50); - silieResult = false; - } - else - { - //drawContours(Paint, contours, i, cv::Scalar(0, 255, 0, 30), 3, LINE_8, noArray(), INT_MAX, cv::Point(offset.x, offset.y)); - } - //if (clsRes == 1) { - // cv::Scalar color = cv::Scalar(0, 0, 255, 30); - // cv::rectangle(Paint, paintRect, color, 4); - // putTextHusky(Paint, utf8_to_gbk("撕裂").c_str(), cv::Point(paintRect.x - paintRect.width / 2, paintRect.y - paintRect.height / 2 - 50), cv::Scalar(0, 255, 0), 50); - // silieResult = false; - //} - //else if (clsRes == 2) { - // cv::Scalar color = cv::Scalar(0, 0, 255, 30); - // cv::rectangle(Paint, paintRect, color, 4); - // putTextHusky(Paint, utf8_to_gbk("翻折").c_str(), cv::Point(paintRect.x - paintRect.width / 2, paintRect.y - paintRect.height / 2 - 50), cv::Scalar(0, 255, 0), 50); - // fanZheResult = false; - //} - } -} -halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegmentation* seg_hanYinZhuaQu, cv::Mat& segResult,double Resolution) {//算法先画 - halconResult result; - cv::Mat forSeg; - cv::resize(img, forSeg, cv::Size(), 0.2, 0.2); - segResult = seg_hanYinZhuaQu->Evaluate(forSeg); - cv::resize(segResult, segResult, cv::Size(), 5, 5); - HObject in_Image1 = MatToHObject(img), in_Image2 = MatToHObject(segResult); - HTuple in_Resolution(Resolution); - - HDevEngineCpp::HDevProcedure proc("_1_Cal_JE_Distance"); - HDevEngineCpp::HDevProcedureCall procedureCall(proc); - procedureCall.SetInputIconicParamObject("in_Image1", in_Image1); - procedureCall.SetInputIconicParamObject("in_Image2", in_Image2); - procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); - procedureCall.Execute(); - HTuple out_LinePoint, out_Distance, out_Flag, out_NgDetails; - out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 - out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量 - out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - out_NgDetails = procedureCall.GetOutputCtrlParamTuple("out_NgDetails");//获取输出控制类变量 - if (out_Flag.D() == 1) - { - for (auto i = 0; i < out_LinePoint.Length(); i += 4) - { - cv::line(Paint, - cv::Point(out_LinePoint[i + 1].D(), out_LinePoint[i].D()), - cv::Point(out_LinePoint[i + 3].D(), out_LinePoint[i + 2].D()), - cv::Scalar(0, 255, 0), 5); - } - - if (out_Distance.Length() > 6) { - double hanYin_Width = out_Distance[0].D();//焊印的宽度 - double hanYin_Height = out_Distance[1].D();//焊印的高度 - double hanYIn_Area = out_Distance[2].D();//焊印的面积 - double jiEr_Width = out_Distance[3].D();//极耳的宽度 - double jiEr_Height = out_Distance[4].D();//极耳的高度 - double hanYin_Distance_Up = out_Distance[5].D();//焊印上边缘到极耳上边缘的距离 - double hanYin_Distance_Down = out_Distance[6].D();//焊印下边缘到极耳下边缘的距离 - - result.jiErWidth = jiEr_Width; - result.jiErHeight = jiEr_Height; - result.hanYin_Width = hanYin_Width; - result.hanYin_Height = hanYin_Height; - result.hanYin_Area = hanYIn_Area; - result.hanYin_Distance_Up = hanYin_Distance_Up; - result.hanYin_Distance_Down = hanYin_Distance_Down; - } - } - else - { - //putTextHusky(Paint, utf8_to_gbk("算法异常").c_str(), cv::Point(0, 500), cv::Scalar(0, 255, 0), 300); - //putTextHusky(Paint, utf8_to_gbk("NG").c_str(), cv::Point(0, 0), cv::Scalar(0, 0, 255), 300); - result.ngStr = gbkToUtf8(out_NgDetails.ToString().Text()); - result.result = false; - return result; - } - return result; -} -bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address) { - QByteArray plcResult = "1"; - try { - //data->getOriImg(0) = cv::imread("D:/testImage/L.bmp", -1); - cv::Mat sourceImg = data->getOriImg(0); - - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - - //HALCON异步处理 - cv::Mat hySegResult; - double resolution = -1; - if (data->cameraKeyName == "Camera1") - resolution = data->service->_paramSyncManager->get("像素精度","铝顶部90度相机精度",0.0159254).toDouble(); - else if (data->cameraKeyName == "Camera3") - resolution = data->service->_paramSyncManager->get("像素精度", "铜顶部90度相机精度", 0.0159837).toDouble(); - auto futrue = std::async(std::launch::async, halconAlgoProcess, sourceImg, Paint, _detParams->segHanYinZhuaQu, std::ref(hySegResult), resolution);//异步执行 - - //handleAI主线程处理 定位极耳 - float resizeRate = 5.0; - cv::Mat matForDingWei; - cv::resize(sourceImg, matForDingWei, cv::Size(), 1 / resizeRate, 1 / resizeRate); - cv::Mat dingWeiResultMat = ~_detParams->segYuHanDingWei->Evaluate(matForDingWei); - cv::Mat structreElement = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); - dilate(dingWeiResultMat, dingWeiResultMat, structreElement, cv::Point(-1, -1), 1); - cv::Rect rect = findMaxAreaContour(dingWeiResultMat); - cv::Mat matDet; - cv::Rect rectCutJier(rect.x * resizeRate - 25, - rect.y * resizeRate - 25, - rect.width * resizeRate + 50, - rect.height * resizeRate + 50); - sourceImg(rectCutJier & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows))).copyTo(matDet); - - //SEG缺陷检测 - cv::Mat SegRes = ~_detParams->segHanHou->Evaluate(matDet); - bool silieOk = true, fanZheOk = true; - std::vector clsImgs; - //handleAiProcess(sourceImg, SegRes, Paint, silieOk, fanZheOk, cv::Point(rectCutJier.x, rectCutJier.y, _detParams->clsHanHou, clsImgs); - - //等待halcon算法完成 - futrue.wait(); - data->insertSegOriginImg(hySegResult); - halconResult halconResult = futrue.get(); - //结果处理 - QString okNgSaveText = "OK"; - QByteArray silieResultText = silieOk == true ? "1" : "2"; - QByteArray fanzheResultText = fanZheOk == true ? "1" : "2"; - TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - if (silieOk == true && fanZheOk == true) {//OK - textPainter.putText(Paint, "缺陷检测OK", cv::Point(4200, 50), cv::Scalar(0, 255, 0)); - } - else { - textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(4200, 50), cv::Scalar(0, 0, 255)); - //plcResult = "2"; - data->aiDetOK = false; - } - - silieResultText = "1"; fanzheResultText = "1"; -#pragma region 判断结果以及储存结果 - double hanyinChangLimitHigh = data->service->_paramSyncManager->get("焊后", "焊印长(上限)", 30.5).toDouble(); - double hanyinChangLimitLow = data->service->_paramSyncManager->get("焊后", "焊印长(下限)", 29.5).toDouble(); - bool hanyinChangEnable = data->service->_paramSyncManager->get("焊后", "焊印长判定启用", false).toBool(); - - double hanyinKuanLimitHigh = data->service->_paramSyncManager->get("焊后", "焊印宽(上限)", 10.5).toDouble(); - double hanyinKuanLimitLow = data->service->_paramSyncManager->get("焊后", "焊印宽(下限)", 9.5).toDouble(); - bool hanyinKuanEnable = data->service->_paramSyncManager->get("焊后", "焊印宽判定启用", false).toBool(); - - double jierChangLimitHigh = data->service->_paramSyncManager->get("焊后", "极耳长度(上限)", 21).toDouble(); - double jierChangLimitLow = data->service->_paramSyncManager->get("焊后", "极耳长度(下限)", 19).toDouble(); - bool jierChangEnable = data->service->_paramSyncManager->get("焊后", "极耳长度判定启用", false).toBool(); - std::string type = _detParams->isTong == true ? "铜" : "铝"; - if (halconResult.hanYin_Width > hanyinChangLimitHigh || halconResult.hanYin_Width < hanyinChangLimitLow) { - textPainter.putText(Paint, type + "焊印长度(mm)" + controlAccuracy(halconResult.hanYin_Width, 4) + "mm", cv::Point(100, 300), cv::Scalar(0, 0, 255));//焊印宽度 - if (hanyinChangEnable == true) - plcResult = "2"; - } - else { - textPainter.putText(Paint, type + "焊印长度(mm)" + controlAccuracy(halconResult.hanYin_Width, 4) + "mm", cv::Point(100, 300), cv::Scalar(0, 255, 0));//焊印宽度 - } - - if (halconResult.hanYin_Height > hanyinKuanLimitHigh || halconResult.hanYin_Height < hanyinKuanLimitLow) { - textPainter.putText(Paint, type + "焊印宽度(mm)" + controlAccuracy(halconResult.hanYin_Height, 4) + "mm", cv::Point(100, 550), cv::Scalar(0, 0, 255));//焊印高度 - if (hanyinKuanEnable == true) - plcResult = "2"; - } - else { - textPainter.putText(Paint, type + "焊印宽度(mm)" + controlAccuracy(halconResult.hanYin_Height, 4) + "mm", cv::Point(100, 550), cv::Scalar(0, 255, 0));//焊印高度 - } - - if (halconResult.jiErHeight > jierChangLimitHigh || halconResult.jiErHeight < jierChangLimitLow) { - textPainter.putText(Paint, type + "极耳长度(mm)" + controlAccuracy(halconResult.jiErHeight, 4) + "mm", cv::Point(100, 50), cv::Scalar(0, 0, 255));//极耳高度 - if (hanyinKuanEnable == true) - plcResult = "2"; - } - else { - textPainter.putText(Paint, type + "极耳长度(mm)" + controlAccuracy(halconResult.jiErHeight, 4) + "mm", cv::Point(100, 50), cv::Scalar(0, 255, 0));//极耳高度 - } - - textPainter.putText(Paint, type + "焊印面积" + controlAccuracy(halconResult.hanYin_Area, 4) + "mm²", cv::Point(100, 2200), cv::Scalar(0, 255, 0));//焊印面积 - textPainter.putText(Paint, "焊印上边缘到极耳上边缘高度" + controlAccuracy(halconResult.hanYin_Distance_Up, 4) + "mm", cv::Point(100, 2450), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, type + "预焊印到芯包顶部间距" + controlAccuracy(halconResult.hanYin_Distance_Down, 4) + "mm", cv::Point(100, 2800), cv::Scalar(0, 255, 0)); - - - if (halconResult.result == false) { - textPainter.putText(Paint, "算法NG", cv::Point(4200, 350), cv::Scalar(0, 0, 255)); - textPainter.putText(Paint, halconResult.ngStr, cv::Point(3800, 650), cv::Scalar(0, 0, 255)); - data->halconOK = false; - plcResult = "2"; - } - - - if (!data->service->_paramSyncManager->get("焊后", "焊后90度正极判断启用", false).toBool()) - plcResult = "1"; - - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - plcResult = "1"; - - data->sqlVec.insert({ {"焊印长度",halconResult.hanYin_Width }, { "焊印宽度",halconResult.hanYin_Height }, { "极耳裁切长度",halconResult.jiErHeight } }); -#pragma endregion - - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_" + silieResultText);//发送数据-撕裂OKNG - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 1) + "_" + fanzheResultText);//发送数据-翻折OKNG - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(halconResult.jiErWidth));//发送数据-极耳宽 - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(halconResult.jiErHeight));//发送数据-极耳高 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_1");//发送数据-焊印位置判定结果 - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 8) + "_" + QByteArray::number(halconResult.hanYin_Distance_Down));//发送数据-芯包顶部到焊印的距离 - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 10) + "_" + QByteArray::number(halconResult.hanYin_Width));//发送数据-极耳宽 - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 12) + "_" + QByteArray::number(halconResult.hanYin_Height));//发送数据-极耳高 - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 14) + "_1");//发送尺寸OK - //textPainter.putText(Paint, "极耳裁切宽度" + std::to_string(halconResult.jiErWidth), cv::Point(100, 50), cv::Scalar(0, 255, 0));//极耳宽度,暂时不显示 - - - - - - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(Paint); - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - 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, "NG", cv::Point(100, 50), cv::Scalar(0, 0, 255)); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(Paint); - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool() == true) - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 - else - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//结果反馈 - return true; -} - -bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address) { - QByteArray plcResult = "2"; - try { - cv::Mat sourceImg = data->getOriImg(0); - //sourceImg = cv::imread("D:\\testImage\\T_NEW.bmp" , -1); - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - - //jier定位 - float resizeRate = 5.0; - cv::Mat matForDingWei; - cv::resize(sourceImg, matForDingWei, cv::Size(), 1 / resizeRate, 1 / resizeRate); - cv::Mat dingWeiResultMat = ~_detParams->segYuHanDingWei->Evaluate(matForDingWei); - cv::Mat structreElement = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); - dilate(dingWeiResultMat, dingWeiResultMat, structreElement, cv::Point(-1, -1), 1); - cv::Rect rect = findMaxAreaContour(dingWeiResultMat); - cv::Mat matDet; - cv::Rect rectCutJier(rect.x * resizeRate - 25, - rect.y * resizeRate - 25, - rect.width * resizeRate + 50, - rect.height * resizeRate + 50); - sourceImg(rectCutJier & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows))).copyTo(matDet); - - //SEG缺陷检测 - if (data->cameraKeyName == "Camera4") { - cv::resize(matDet, matDet, cv::Size(), 0.5, 0.5); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - } - cv::Mat SegRes = ~_detParams->segHanHou->Evaluate(matDet); - data->insertSegOriginImg(matDet); - bool silieOk = true, fanZheOk = true; - std::vector> clsImgs; - if (data->cameraKeyName == "Camera4") { - handleAiProcess(matDet, SegRes, Paint, silieOk, fanZheOk, cv::Point(rectCutJier.x / 2, rectCutJier.y / 2), _detParams->clsHanHou, clsImgs); - } - data->insertClsOriginImg(clsImgs); - /* else if (data->cameraKeyName == "Camera5" || data->cameraKeyName == "Camera7") { - handleAiProcess(matDet, SegRes, Paint, silieOk, fanZheOk, cv::Point(rectCutJier.x, rectCutJier.y), _detParams->clsHanHou, clsImgs); - }*/ - QString okNgSaveText = "OK"; - QByteArray silieResultText = silieOk == true ? "1" : "2"; - QByteArray fanzheResultText = fanZheOk == true ? "1" : "2"; - plcResult = "1"; - if (data->cameraKeyName == "Camera4") { - cv::Rect cutPaintRect = cv::Rect(rectCutJier.x / 2 - 50, rectCutJier.y / 2 - 50, rectCutJier.width / 2 + 100, rectCutJier.height / 2 + 100) & cv::Rect(0, 0, sourceImg.cols, sourceImg.rows); - Paint(cutPaintRect).copyTo(Paint);//裁切结果图,确保界面只显示一个极耳 - } - else { - cv::Rect cutPaintRect = cv::Rect(rectCutJier.x - 100, rectCutJier.y - 100, rectCutJier.width + 200, rectCutJier.height + 200) & cv::Rect(0, 0, sourceImg.cols, sourceImg.rows); - Paint(cutPaintRect).copyTo(Paint);//裁切结果图,确保界面只显示一个极耳 - } - - TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - if (silieOk == true && fanZheOk == true) {//OK - textPainter.putText(Paint, "OK", cv::Point(0, 0), cv::Scalar(0, 255, 0)); - } - else { - textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); - plcResult = "2"; - data->aiDetOK = false; - } - std::vector defects; - if (plcResult == "2")defects.push_back("焊后底部NG"); - data->service->_missionResultHandle->toBarChart(data->SNcode, defects); - - if (!data->service->_paramSyncManager->get("焊后", "焊后90度底部判断启用", true).toBool()) - plcResult = "1"; - - if (data->cameraKeyName != "Camera2" && data->cameraKeyName != "Camera4") - plcResult = "1"; - - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - plcResult = "1"; - - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - if (data->cameraKeyName != "Camera4") { - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - } - data->insertResultImg(Paint); - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - 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, "异常", cv::Point(100, 50), cv::Scalar(0, 0, 255)); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 - return true; -} -bool hanHouTop45(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address) { - QByteArray plcResult = "2"; - try { - std::vector defects; - cv::Mat sourceImg = data->getOriImg(0); - //sourceImg = cv::imread("D:\\testImage\\T_NEW.bmp" , -1); - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - - //jier定位 - float resizeRate = 10.0; - cv::Mat matForDingWei; - cv::resize(sourceImg, matForDingWei, cv::Size(), 1 / resizeRate, 1 / resizeRate); - cv::Mat dingWeiResultMat = ~_detParams->segYuHanDingWei->Evaluate(matForDingWei); - cv::Mat structreElement = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); - dilate(dingWeiResultMat, dingWeiResultMat, structreElement, cv::Point(-1, -1), 1); - cv::Rect rect = findMaxAreaContour(dingWeiResultMat); - cv::Mat matDet; - cv::Rect rectCutJier(rect.x * resizeRate - 25, - rect.y * resizeRate - 25, - rect.width * resizeRate + 50, - rect.height * resizeRate + 50); - sourceImg(rectCutJier & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows))).copyTo(matDet); - cv::resize(matDet, matDet, cv::Size(), 0.5, 0.5); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - bool silieOk = true, fanZheOk = true; - //SEG缺陷检测 - if (data->cameraKeyName == "Camera5" || data->cameraKeyName == "Camera7") { - /* if (matDet.rows > 800) { - silieOk = false; - }*/ - } - cv::Mat SegRes = ~_detParams->segHanHou->Evaluate(matDet); - data->insertSegOriginImg(SegRes); - data->insertSegOriginImg(matDet); - - std::vector clsImgs; - //if (data->cameraKeyName == "Camera4") { - // handleAiProcess(matDet, SegRes, Paint, silieOk, fanZheOk, cv::Point(rectCutJier.x / 2, rectCutJier.y / 2), _detParams->clsHanHou, clsImgs); - //} - ///* else if (data->cameraKeyName == "Camera5" || data->cameraKeyName == "Camera7") { - // handleAiProcess(matDet, SegRes, Paint, silieOk, fanZheOk, cv::Point(rectCutJier.x, rectCutJier.y), _detParams->clsHanHou, clsImgs); - // }*/ - //for (auto& img : clsImgs) - // data->clsOriginImgs.push_back({ "cls",img }); - QString okNgSaveText = "OK"; - QByteArray silieResultText = silieOk == true ? "1" : "2"; - QByteArray fanzheResultText = fanZheOk == true ? "1" : "2"; - plcResult = "1"; - - cv::Rect cutPaintRect = cv::Rect(rectCutJier.x / 2 - 50, rectCutJier.y / 2 - 50, rectCutJier.width / 2 + 100, rectCutJier.height / 2 + 100) & cv::Rect(0, 0, sourceImg.cols, sourceImg.rows); - Paint(cutPaintRect).copyTo(Paint);//裁切结果图,确保界面只显示一个极耳 - - - TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - if (silieOk == true && fanZheOk == true) {//OK - textPainter.putText(Paint, "OK", cv::Point(0, 0), cv::Scalar(0, 255, 0)); - } - else { - textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); - plcResult = "2"; - data->aiDetOK = false; - } - - - if (plcResult == "2")defects.push_back("焊后45度相机NG"); - data->service->_missionResultHandle->toBarChart(data->SNcode, defects); - - if (!data->service->_paramSyncManager->get("焊后", "焊后45度顶部判断启用", true).toBool()) - plcResult = "1"; - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - plcResult = "1"; - - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - if (data->cameraKeyName != "Camera4") { - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - } - data->insertResultImg(Paint); - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - 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, "异常", cv::Point(100, 50), cv::Scalar(0, 0, 255)); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 - return true; -} -bool hanHouDown_test(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address) { - QByteArray plcResult = "2"; - try { - std::vector defects; - cv::Mat sourceImg = data->getOriImg(0); - //sourceImg = cv::imread("D:\\testImage\\T_NEW.bmp" , -1); - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - - //jier定位 - float resizeRate = 5.0; - cv::Mat matForDingWei; - cv::resize(sourceImg, matForDingWei, cv::Size(), 1 / resizeRate, 1 / resizeRate); - cv::Mat dingWeiResultMat = ~_detParams->segYuHanDingWei->Evaluate(matForDingWei); - cv::Mat structreElement = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); - dilate(dingWeiResultMat, dingWeiResultMat, structreElement, cv::Point(-1, -1), 1); - cv::Rect rect = findMaxAreaContour(dingWeiResultMat); - cv::Mat matDet; - cv::Rect rectCutJier(rect.x * resizeRate - 10, - rect.y * resizeRate - 10, - rect.width * resizeRate + 20, - rect.height * resizeRate + 20); - sourceImg(rectCutJier & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows))).copyTo(matDet); - - //SEG缺陷检测 - if (data->cameraKeyName == "Camera2") { - cv::resize(matDet, matDet, cv::Size(), 0.5, 0.5); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertSegOriginImg(matDet); - } - else{ - cv::Mat save; - cv::resize(matDet, save, cv::Size(), 0.5, 0.5); - data->insertSegOriginImg(save); - cv::resize(matDet, matDet, cv::Size(), 0.8, 0.8); - cv::resize(Paint, Paint, cv::Size(), 0.8, 0.8); - } - - cv::Mat SegRes = ~_detParams->segHanHou->Evaluate(matDet); - data->insertSegOriginImg(SegRes); - bool silieOk = true, fanZheOk = true; - std::vector> clsImgs; - if (data->cameraKeyName == "Camera2") { - handleAiProcess(matDet, SegRes, Paint, silieOk, fanZheOk, cv::Point(rectCutJier.x * 0.5, rectCutJier.y * 0.5), _detParams->clsHanHou, clsImgs, cv::Size(300, 200)); - - QString okNgSaveText = "OK"; - QByteArray silieResultText = silieOk == true ? "1" : "2"; - QByteArray fanzheResultText = fanZheOk == true ? "1" : "2"; - plcResult = "1"; - - cv::Rect cutPaintRect = cv::Rect(rectCutJier.x * 0.5 - 50, rectCutJier.y * 0.5 - 50, rectCutJier.width * 0.5 + 100, rectCutJier.height * 0.5 + 100) & cv::Rect(0, 0, sourceImg.cols, sourceImg.rows); - Paint(cutPaintRect).copyTo(Paint);//裁切结果图,确保界面只显示一个极耳 - } - else { - handleAiProcess(matDet, SegRes, Paint, silieOk, fanZheOk, cv::Point(rectCutJier.x * 0.8, rectCutJier.y * 0.8), _detParams->clsHanHou, clsImgs, cv::Size(200, 200)); - - QString okNgSaveText = "OK"; - QByteArray silieResultText = silieOk == true ? "1" : "2"; - QByteArray fanzheResultText = fanZheOk == true ? "1" : "2"; - plcResult = "1"; - - cv::Rect cutPaintRect = cv::Rect(rectCutJier.x * 0.8 - 50, rectCutJier.y * 0.8 - 50, rectCutJier.width * 0.8 + 100, rectCutJier.height * 0.8 + 100) & cv::Rect(0, 0, sourceImg.cols, sourceImg.rows); - Paint(cutPaintRect).copyTo(Paint);//裁切结果图,确保界面只显示一个极耳 - } - data->insertClsOriginImg(clsImgs); - TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - if (silieOk == true && fanZheOk == true) {//OK - textPainter.putText(Paint, "OK", cv::Point(0, 0), cv::Scalar(0, 255, 0)); - } - else { - textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); - plcResult = "2"; - data->aiDetOK = false; - } - if (!data->service->_paramSyncManager->get("焊后", "焊后90度负极判断启用", true).toBool()) - plcResult = "1"; - - //if (data->cameraKeyName != "Camera4") - // plcResult = "1"; - - if (plcResult == "2")defects.push_back("焊后NG"); - data->service->_missionResultHandle->toBarChart(data->SNcode, defects); - - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - plcResult = "1"; - - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - data->insertResultImg(Paint); - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - 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, "异常", cv::Point(100, 50), cv::Scalar(0, 0, 255)); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 - return true; -} - - - -mission* createMission() { - return new _581_YuHan_hanqian(); -} -void destroyMission(mission* _mission) { - delete _mission; -} \ No newline at end of file diff --git a/src/mission/602/YH/581_YuHan_hanhou/581_YuHan_hanhou.h b/src/mission/602/YH/581_YuHan_hanhou/581_YuHan_hanhou.h deleted file mode 100644 index a06a723..0000000 --- a/src/mission/602/YH/581_YuHan_hanhou/581_YuHan_hanhou.h +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; -#pragma endregion -class yuHanHanHouParams { -public: - handdleAI::pSegmentation* segHanYinZhuaQu = nullptr; - handdleAI::pSegmentation* segYuHanDingWei = nullptr; - handdleAI::pSegmentation* segHanHou = nullptr; - handdleAI::pClassification* clsHanHou = nullptr; - int cameraIndex = 1; - bool isTong = false; -}; -struct halconResult { - bool result = true; - double hanYin_Width = -1;//焊印宽度 - double hanYin_Height = -1;//焊印高度 - double hanYin_Area = -1;//焊印面积 - double jiErWidth = -1;//极耳的宽度 - double jiErHeight = -1;//极耳的高度 - double hanYin_Distance_Up = -1;//焊印上边缘到极耳上边缘的距离 - double hanYin_Distance_Down = -1;//焊印下边缘到极耳下边缘的距离 - std::string ngStr = ""; -}; -void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint, - bool& silieResult, bool& fanZheResult, - cv::Point offset, handdleAI::pClassification* clsPtr, std::vector& clsImgs,int sgin); -halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegmentation* seg_hanYinZhuaQu, cv::Mat& segResult,double); -bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); -bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); -bool hanHouTop45(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); -bool hanHouDown_test(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); -class _581_YuHan_hanqian : public mission { -public: - _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_top90_1; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_down90_2; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_top90_3; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_down90_4; - - _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_top45_5; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_down45_6; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_top45_7; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_down45_8; - - //std::vector < yuHanHanHouParams> tongDetParams; - //std::vector < yuHanHanHouParams> lvDetParams; - - std::vector < yuHanHanHouParams> tong_90_DetParams; - std::vector < yuHanHanHouParams> lv_90_DetParams; - - std::vector < yuHanHanHouParams> dibu_45_tong_DetParams; - std::vector < yuHanHanHouParams> dingbu_45_tong_DetParams; - - std::vector < yuHanHanHouParams> dibu_45_lv_DetParams; - std::vector < yuHanHanHouParams> dingbu_45_lv_DetParams; - bool initOnce = false; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath(""); - myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl"); - if (initOnce == false) { - for (int i = 0; i < 2; i++) - { - yuHanHanHouParams tong_90; - tong_90.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/yuHanDingWei-90-T-seg.BHD", 16, 0); - tong_90.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanYinZhuaQu/seg-hanYinZhuaQu-T.BHD", 64, 0); - tong_90.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/seg-yuHanhanHou-T.BHD", 1, 0); - tong_90.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/cls-yuHanhanHou-T.BHD", 0, 1); - tong_90.isTong = true; - tong_90_DetParams.push_back(tong_90); - - yuHanHanHouParams lv_90; - lv_90.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/yuHanDingWei-90-L-seg.BHD", 64, 1); - lv_90.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanYinZhuaQu/seg-hanYinZhuaQu-L.BHD", 64, 1); - lv_90.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/seg-yuHanhanHou-L.BHD", 16, 1); - lv_90.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/cls-yuHanhanHou-L.BHD", 1, 1); - lv_90_DetParams.push_back(lv_90); - - } - - yuHanHanHouParams dibu_45_lv; - dibu_45_lv.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/yuHanDingWei-90-L-seg.BHD", 16, 1); - dibu_45_lv.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanYinZhuaQu/seg-hanYinZhuaQu-L.BHD", 64, 1); - dibu_45_lv.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou45/yuHanhanHou-dibu-45-L-seg.BHD", 64, 1); - dibu_45_lv.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuhan_hanhou45/yuHanhanHou-dibu-45-L-cls.BHD", 1, 1); - dibu_45_lv_DetParams.push_back(dibu_45_lv); - - yuHanHanHouParams dibu_45_tong; - dibu_45_tong.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/yuHanDingWei-90-T-seg.BHD", 16, 0); - dibu_45_tong.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanYinZhuaQu/seg-hanYinZhuaQu-T.BHD", 64, 0); - dibu_45_tong.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/seg-yuHanhanHou-T.BHD", 64, 0); - dibu_45_tong.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuhan_hanhou90/cls-yuHanhanHou-T.BHD", 0, 1); - dibu_45_tong.isTong = true; - dibu_45_tong_DetParams.push_back(dibu_45_tong); - - yuHanHanHouParams dingbu_45_lv; - dingbu_45_lv.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou45/yuHanDingWei-45-L-seg.BHD", 16, 1); - dingbu_45_lv.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanYinZhuaQu/seg-hanYinZhuaQu-L.BHD", 64, 1); - dingbu_45_lv.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou45/yuHanhanHou-dingbu-45-L-seg.BHD", 64, 1); - dingbu_45_lv.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuhan_hanhou45/yuHanhanHou-dingbu-45-L-cls.BHD", 1, 1);//未更新 - dingbu_45_lv_DetParams.push_back(dingbu_45_lv); - - yuHanHanHouParams dingbu_45_tong; - dingbu_45_tong.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou45/yuHanDingWei-45-T-seg.BHD", 16, 0); - dingbu_45_tong.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanYinZhuaQu/seg-hanYinZhuaQu-T.BHD", 64, 0); - dingbu_45_tong.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuhan_hanhou45/yuHanhanHou-dingbu-45-T-seg.BHD", 64, 0); - dingbu_45_tong.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuhan_hanhou45/yuHanhanHou-dingbu-45-T-cls.BHD", 0, 1); - dingbu_45_tong.isTong = true; - dingbu_45_tong_DetParams.push_back(dingbu_45_tong); - - initOnce = true; - } - - - lv_90_DetParams[0].cameraIndex = 1; - lv_90_DetParams[1].cameraIndex = 2; - tong_90_DetParams[0].cameraIndex = 3; - tong_90_DetParams[1].cameraIndex = 4; - - dingbu_45_lv_DetParams[0].cameraIndex = 5; - dibu_45_lv_DetParams[0].cameraIndex = 6; - dingbu_45_tong_DetParams[0].cameraIndex = 7; - dibu_45_tong_DetParams[0].cameraIndex = 8; - - } - bool initCustom() { -#pragma region 注册触发器回调 - if (_serviceManager->_paramSyncManager->get("焊后", "hanhou","OUT") == "OUT") { - lv_top90_1.init("Camera1", "极耳尺寸-外-铝-相机1(顶部90°)", { { 522, 1,{540},"523","530",820} }, 1, &lv_90_DetParams[0], _serviceManager, bridge, hanHouCeLiang); - lv_down90_2.init("Camera2", "极耳尺寸-外-铝-相机2(底部90°)", { { 524, 1,{540},"525","532",-1} }, 1, &lv_90_DetParams[1], _serviceManager, bridge, hanHouDown_test); - tong_top90_3.init("Camera3", "极耳尺寸-外-铜-相机3(顶部90°)", { { 526,1,{540},"527","534",800} }, 1, &tong_90_DetParams[0], _serviceManager, bridge, hanHouCeLiang); - tong_down90_4.init("Camera4", "极耳尺寸-外-铜-相机4(底部90°)", { { 528, 1,{540},"529","536",-1} }, 1, &tong_90_DetParams[1], _serviceManager, bridge, hanHouDown_test); - - lv_top45_5.init("Camera5", "底部撕裂-外-铝-相机5(顶部45°)", { { 562,1,{540},"563","570",-1} }, 1, &dingbu_45_lv_DetParams[0], _serviceManager, bridge, hanHouTop45); - lv_down45_6.init("Camera6", "底部撕裂-外-铝-相机6(底部45°)", { { 564, 1,{540},"565","572",-1} }, 1, &dibu_45_lv_DetParams[0], _serviceManager, bridge, hanHouDown); - tong_top45_7.init("Camera7", "底部撕裂-外-铜-相机7(顶部45°)", { { 566, 1,{540},"567","574",-1} }, 1, &dingbu_45_tong_DetParams[0], _serviceManager, bridge, hanHouTop45); - tong_down45_8.init("Camera8", "底部撕裂-外-铜-相机8(底部45°)", { { 568, 1,{540},"569","576",-1} }, 1, &dibu_45_tong_DetParams[0], _serviceManager, bridge, hanHouDown); - } - else { - lv_top90_1.init("Camera1", "极耳尺寸-内-铝-相机1(顶部90°)", { { 602, 1,{580},"603","610",860} }, 1, &lv_90_DetParams[0], _serviceManager, bridge, hanHouCeLiang); - lv_down90_2.init("Camera2", "极耳尺寸-内-铝-相机2(底部90°)", { { 604, 1,{580},"605","612",-1} }, 1, &lv_90_DetParams[1], _serviceManager, bridge, hanHouDown_test); - tong_top90_3.init("Camera3", "极耳尺寸-内-铜-相机3(顶部90°)", { { 606,1,{580},"607","614",840} }, 1, &tong_90_DetParams[0], _serviceManager, bridge, hanHouCeLiang); - tong_down90_4.init("Camera4", "极耳尺寸-内-铜-相机4(底部90°)", { { 608, 1,{580},"609","616",-1} }, 1, &tong_90_DetParams[1], _serviceManager, bridge, hanHouDown_test); - - lv_top45_5.init("Camera5", "底部撕裂-内-铝-相机5(顶部45°)", { { 642,1,{580},"643","650",-1} }, 1, &dingbu_45_lv_DetParams[0], _serviceManager, bridge, hanHouTop45); - lv_down45_6.init("Camera6", "底部撕裂-内-铝-相机6(底部45°)", { { 644, 1,{580},"645","652",-1} }, 1, &dibu_45_lv_DetParams[0], _serviceManager, bridge, hanHouDown); - tong_top45_7.init("Camera7", "底部撕裂-内-铜-相机7(顶部45°)", { { 646, 1,{580},"647","654",-1} }, 1, &dingbu_45_tong_DetParams[0], _serviceManager, bridge, hanHouTop45); - tong_down45_8.init("Camera8", "底部撕裂-内-铜-相机8(底部45°)", { { 648, 1,{580},"649","656",-1} }, 1, &dibu_45_tong_DetParams[0], _serviceManager, bridge, hanHouDown); - } -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/602/YH/581_YuHan_hanqian/581_YuHan_hanqian.cpp b/src/mission/602/YH/581_YuHan_hanqian/581_YuHan_hanqian.cpp deleted file mode 100644 index 3874af8..0000000 --- a/src/mission/602/YH/581_YuHan_hanqian/581_YuHan_hanqian.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include <581_YuHan_hanqian.h> - -mission* createMission() { - return new _581_YuHan_hanqian(); -} -void destroyMission(mission* _mission) { - delete _mission; -} \ No newline at end of file diff --git a/src/mission/602/YH/581_YuHan_hanqian/581_YuHan_hanqian.h b/src/mission/602/YH/581_YuHan_hanqian/581_YuHan_hanqian.h deleted file mode 100644 index 939cdf5..0000000 --- a/src/mission/602/YH/581_YuHan_hanqian/581_YuHan_hanqian.h +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; -#pragma endregion -class yuHanHanQianParams { -public: - handdleAI::pSegmentation* segDingWei = nullptr; - - handdleAI::pSegmentation* segJiErFanZhe = nullptr; - handdleAI::pClassification* clsJiErFanZhe = nullptr; - bool isTong = true; -}; -void halconProcess(cv::Mat& sourceImg, cv::Mat& Paint) { - try { - HDevEngineCpp::HDevProcedure proc("Inspection_YH_JE"); - HDevEngineCpp::HDevProcedureCall procedureCall(proc); - HObject in_Image = MatToHObject(sourceImg); - procedureCall.SetInputIconicParamObject("in_Image", in_Image);//设置输入图像类变量 - procedureCall.Execute();//执行halcon程序 - HTuple out_X, out_Y, out_Flag; - out_X = procedureCall.GetOutputCtrlParamTuple("out_X"); - out_Y = procedureCall.GetOutputCtrlParamTuple("out_Y"); - out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); - if (out_Flag.D() == 0) { - for (int i = 0; i < out_X.Length(); i++) - Paint.at(out_X[i].D(), out_Y[i].D()) = { 255,255,0 }; - } - } - catch (HDevEngineCpp::HDevEngineException& ex) { - - std::cout << "HDevEngineException: " << ex.Message() << std::endl; \ - qDebug() << "HDevEngineException: " << ex.Message(); \ - } - catch (HalconCpp::HException& ex) { - - std::cout << "Halcon Exception Caught!" << std::endl; \ - std::cout << "Error Code: " << ex.ErrorCode() << std::endl; \ - std::cout << "Error Message: " << ex.ErrorMessage() << std::endl; \ - qDebug() << "Halcon Exception Caught!"; \ - qDebug() << "Error Code: " << ex.ErrorCode(); \ - qDebug() << "Error Message: " << ex.ErrorMessage(); \ - } -} -cv::Rect getImageLocateRect(cv::Mat& src, handdleAI::pSegmentation* seg, double bounus = 0.1) { - cv::Mat tmpImg; - cv::resize(src, tmpImg, cv::Size(), bounus, bounus); - cv::Mat ouput = ~seg->Evaluate(tmpImg); - auto rect = findMaxAreaContour(ouput); - rect.x /= bounus; rect.y /= bounus; - rect.width /= bounus; rect.height /= bounus; - return rect; -} -bool handleAiProcess(cv::Mat& seg_detImg, cv::Mat& seg_Paint, - handdleAI::pSegmentation* segPtr, handdleAI::pClassification* clsPtr, - std::vector< std::pair >& clsImgs){ - cv::Mat segResizeImg; - float resizeRate = 1.0; - cv::resize(seg_detImg, segResizeImg, cv::Size(), 1.0 / resizeRate, 1.0 / resizeRate); - cv::Mat seg_ResultImg = ~segPtr->Evaluate(segResizeImg); - cv::resize(seg_ResultImg, seg_ResultImg, cv::Size(), resizeRate, resizeRate); - std::vector> contours; - cv::findContours(seg_ResultImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); - bool finalNg = false; - for (int i = 0; i < contours.size(); i++) - { - cv::Rect cls_rect = cv::boundingRect(contours[i]); - if (cls_rect.width < 600 || cls_rect.height < 600 || (cls_rect.y < 550) ) - continue; -#if 1 - std::vector clsImgVec = cutImg2ClsVec(cls_rect, seg_detImg); - std::vector clsRes;//true ok - bool isNg = false; - for (auto& cls : clsImgVec) { - cv::resize(cls, cls, cv::Size(128, 128));//根据需要设定大小 - int Result = clsPtr->Evaluate(cls); - if (Result != 0)isNg = true; - clsRes.push_back(Result); - clsImgs.push_back({ std::to_string(Result) ,cls }); - } - if (isNg == true) { - cv::Scalar color = cv::Scalar(0, 255, 255, 30); - cv::rectangle(seg_Paint, cls_rect, color, 4); - drawContours(seg_Paint, contours, i, cv::Scalar(0, 0, 255, 30), 3); - finalNg = true; - } - else { - //drawContours(seg_Paint, contours, i, cv::Scalar(0, 255, 0, 30), 3); - } -#else - bool isNg = false; - cv::Mat clsImage = cutLabelImg(seg_detImg, 200, 200, cls_rect, 0, 1, 1); - int Result = clsPtr->Evaluate(clsImage); - if (Result != 0) { - isNg = true; - cv::Scalar color = cv::Scalar(0, 255, 255, 30); - cv::rectangle(seg_Paint, cls_rect, color, 4); - drawContours(seg_Paint, contours, i, cv::Scalar(0, 0, 255, 30), 3); - finalNg = true; - } - else { - - } - clsImgs.push_back({ Result , clsImage }); -#endif - } - return finalNg; -} -bool jiErFanZhe(std::shared_ptr data, yuHanHanQianParams* _detParams, sx_581_address address) { - try{ -#if 0 - /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ - cv::Mat resultImage = img2D.clone(); - if (resultImage.channels() == 1) { - cv::cvtColor(resultImage, resultImage, cv::COLOR_GRAY2BGR); - } - QString okng_tag = "OK"; - cv::Mat seg_detectImage; - cv::resize(img2D, seg_detectImage, cv::Size(), 1, 1); - plcResult = "1"; - bool isNG = false; - if (DOGLIVE) { - std::vector>clsImgs; - bool isNG = handleAiProcess(seg_detectImage, resultImage, seg_jierFanZhe, cls_jierFanZhe, clsImgs); - for (int i = 0; i < clsImgs.size(); i++) { - addImgToSaveStruct(clsImgs[i].second, "0", getClsSaveFormat(SN, okng_tag, i, clsImgs[i].first)); - } - } - if (isNG == false)//OK - { - putTextHusky(resultImage, utf8_to_gbk("OK").c_str(), cv::Point(50, 50), cv::Scalar(0, 255, 0), 200); - okng_tag = "OK"; - } - else - { - putTextHusky(resultImage, utf8_to_gbk("NG").c_str(), cv::Point(50, 50), cv::Scalar(0, 0, 255), 200); - plcResult = "2"; - } - cv::resize(resultImage, resultImage, cv::Size(), 0.5, 0.5); - resMat.push_back(resultImage); - if (resMat.size() > 0) - { - addImgToSaveStruct(seg_detectImage, "0", getSegSaveFormat(SN, okng_tag));//存seg图 - addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, okng_tag));//存结果图 - } - addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okng_tag));//存原图图 - - return true; - /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ -#else - //存图数据加保存队列,加锁,避免数据访问冲突 - QByteArray plcResult = "1"; - cv::Mat sourceImg; - data->getOriImg(0).copyTo(sourceImg); - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - //halconProcess(sourceImg, Paint); - float resizeRate = 5.0; - auto rect = getImageLocateRect(sourceImg, _detParams->segDingWei, 1.0 / resizeRate);//定位 - rect = rect & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows));//防止越界 - bool isNG = false; - cv::Mat seg_CutImg,seg_LocateImg; - sourceImg(rect).copyTo(seg_CutImg); - cv::resize(sourceImg, seg_LocateImg, cv::Size(), 0.2, 0.2); - std::vector< std::pair > clsImgs; - if (rect.height > 1600) { - cv::rectangle(Paint, rect, cv::Scalar(0, 0, 255), 3); - isNG = true; - } - else if (rect.width > 500 || rect.height > 500) { - isNG = handleAiProcess(sourceImg(rect), Paint(rect), _detParams->segJiErFanZhe, _detParams->clsJiErFanZhe, clsImgs); - cv::rectangle(Paint, rect, cv::Scalar(0, 255, 255), 3); - data->insertClsOriginImg(clsImgs); - } - else { - isNG = true; - } - TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - if (isNG == false)//OK - { - textPainter.putText(Paint, "OK", cv::Point(100, 50), cv::Scalar(0, 255, 0)); - } - else - { - textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 0, 255)); - data->aiDetOK = false; - if (data->cameraKeyName == "Camera1" || data->cameraKeyName == "Camera3" || data->cameraKeyName == "Camera5" || data->cameraKeyName == "Camera7") { - if (data->service->_paramSyncManager->get("极耳翻折", "极耳翻折正极判定启用", false).toBool() == true) - plcResult = "2"; - } - else { - if (data->service->_paramSyncManager->get("极耳翻折", "极耳翻折负极判定启用", false).toBool() == true) - plcResult = "2"; - } - } - std::vector defects; - if (plcResult == "2")defects.push_back("焊前NG"); - data->service->_missionResultHandle->toBarChart(data->SNcode, defects); - if(data->service->_paramSyncManager->get("通用设置","强制OK", false).toBool() == true) - plcResult = "1";//强制OK - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - cv::Mat save; - cv::resize(seg_CutImg, save, cv::Size(), 0.5, 0.5); - data->insertSegOriginImg(save); - data->insertSegOriginImg(seg_LocateImg); - data->insertResultImg(Paint); - return true; -#endif - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode); - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "NG", cv::Point(1000, 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 + "_2");//结果反馈 - return true; -} -class _581_YuHan_hanqian : public mission { -public: - _581_SX_Single_triggerTemplate< yuHanHanQianParams> in_lv_top_1; - _581_SX_Single_triggerTemplate< yuHanHanQianParams> in_lv_down_2; - _581_SX_Single_triggerTemplate< yuHanHanQianParams> in_tong_top_3; - _581_SX_Single_triggerTemplate< yuHanHanQianParams> in_tong_down_4; - - _581_SX_Single_triggerTemplate< yuHanHanQianParams> out_lv_top_5; - _581_SX_Single_triggerTemplate< yuHanHanQianParams> out_lv_down_6; - _581_SX_Single_triggerTemplate< yuHanHanQianParams> out_tong_top_7; - _581_SX_Single_triggerTemplate< yuHanHanQianParams> out_tong_down_8; - std::vector < yuHanHanQianParams> tongDetParams = std::vector < yuHanHanQianParams>(4); - std::vector < yuHanHanQianParams> lvDetParams = std::vector < yuHanHanQianParams>(4); - bool initOnce = false; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_628_1.hdpl"); - - if (initOnce == false) { - for (auto& params : tongDetParams) { - params.segDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/hanqian_dingwei_seg.BHD", 16, 0); - params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/hanqian_T-seg.BHD", 64, 0); - params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/hanqian_T-cls.BHD", 0, 1); - } - for (auto& params : lvDetParams) { - params.segDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/hanqian_dingwei_seg.BHD", 16, 1); - params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/hanqian_L-seg.BHD", 64, 1); - params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/hanqian_L-cls.BHD", 1, 1); - params.isTong = false; - } - initOnce = true; - } - } - bool initCustom() { -#pragma region 注册触发器回调 - in_lv_top_1.init("Camera1", "极耳翻折-铝-内-相机1(顶部)", { { 682, 1,{760},"683","670",-1} }, 1, &lvDetParams[0], _serviceManager, bridge, jiErFanZhe); - in_lv_down_2.init("Camera2", "极耳翻折-铝-内-相机2(底部)", { { 684, 1,{760},"685","672",-1} }, 1, &lvDetParams[1], _serviceManager, bridge, jiErFanZhe); - in_tong_top_3.init("Camera3", "极耳翻折-铜-内-相机3(顶部)", { { 686,1,{760},"687","674",-1} }, 1, &tongDetParams[0], _serviceManager, bridge, jiErFanZhe); - in_tong_down_4.init("Camera4", "极耳翻折-铜-内-相机4(底部)", { { 688, 1,{760},"689","676",-1} }, 1, &tongDetParams[1], _serviceManager, bridge, jiErFanZhe); - - out_lv_top_5.init("Camera5", "极耳翻折-铝-外-相机5(顶部)", { { 702,1,{720},"703","710",-1} }, 1, &lvDetParams[2], _serviceManager, bridge, jiErFanZhe); - out_lv_down_6.init("Camera6", "极耳翻折-铝-外-相机6(底部)", { { 704, 1,{720},"705","712",-1} }, 1, &lvDetParams[3], _serviceManager, bridge, jiErFanZhe); - out_tong_top_7.init("Camera7", "极耳翻折-铜-外-相机7(顶部)", { { 706, 1,{720},"707","714",-1} }, 1, &tongDetParams[2], _serviceManager, bridge, jiErFanZhe); - out_tong_down_8.init("Camera8", "极耳翻折-铜-外-相机8(底部)", { { 708, 1,{720},"709","716",-1} }, 1, &tongDetParams[3], _serviceManager, bridge, jiErFanZhe); -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/602/YH/581_YuHan_jixing/581_YuHan_jixing.h b/src/mission/602/YH/581_YuHan_jixing/581_YuHan_jixing.h deleted file mode 100644 index 55f9004..0000000 --- a/src/mission/602/YH/581_YuHan_jixing/581_YuHan_jixing.h +++ /dev/null @@ -1,177 +0,0 @@ -#include -#include -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; -#pragma endregion -class yuHanParams { -public: - - bool isTong = true; -}; -bool halconProcess(cv::Mat& sourceImg, cv::Mat& Paint) { - try { - HDevEngineCpp::HDevProcedure proc("YH_Color_Inspection"); - HDevEngineCpp::HDevProcedureCall procedureCall(proc); - HObject in_Image = MatToHObject(sourceImg); - procedureCall.SetInputIconicParamObject("in_Image", in_Image);//设置输入图像类变量 - procedureCall.Execute();//执行halcon程序 - HTuple out_ColorType; - HTuple out_Flag; - out_ColorType = procedureCall.GetOutputCtrlParamTuple("out_ColorType");//获取输出图像类变量 - out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - //相机2 OK为铜 NG为铝 - if (out_Flag.D() == 1) - { - if (out_ColorType.D() == 1)//铜 - { - //cv::putText(Paint, "OK", cv::Point(0, 550), 2, 10, cv::Scalar(0, 255, 0), 10); - return true; - } - else//铝 - { - //cv::putText(Paint, "NG", cv::Point(0, 550), 2, 10, cv::Scalar(0, 0, 255), 10); - return false; - } - } - else - { - //cv::putText(Paint, "NG", cv::Point(0, 550), 2, 10, cv::Scalar(0, 0, 255), 10); - return false; - } - } - catch (HDevEngineCpp::HDevEngineException& ex) { - - std::cout << "HDevEngineException: " << ex.Message() << std::endl; \ - qDebug() << "HDevEngineException: " << ex.Message(); \ - } - catch (HalconCpp::HException& ex) { - - std::cout << "Halcon Exception Caught!" << std::endl; \ - std::cout << "Error Code: " << ex.ErrorCode() << std::endl; \ - std::cout << "Error Message: " << ex.ErrorMessage() << std::endl; \ - qDebug() << "Halcon Exception Caught!"; \ - qDebug() << "Error Code: " << ex.ErrorCode(); \ - qDebug() << "Error Message: " << ex.ErrorMessage(); \ - } -} -bool jixingjiance(std::shared_ptr data, yuHanParams* detParams, sx_581_address address) { - try{ -#if 0 - /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ - cv::Mat resultImage = img2D.clone(); - if (resultImage.channels() == 1) { - cv::cvtColor(resultImage, resultImage, cv::COLOR_GRAY2BGR); - } - QString okng_tag = "OK"; - cv::Mat seg_detectImage; - cv::resize(img2D, seg_detectImage, cv::Size(), 1, 1); - plcResult = "1"; - bool isNG = false; - if (DOGLIVE) { - std::vector>clsImgs; - bool isNG = handleAiProcess(seg_detectImage, resultImage, seg_jierFanZhe, cls_jierFanZhe, clsImgs); - for (int i = 0; i < clsImgs.size(); i++) { - addImgToSaveStruct(clsImgs[i].second, "0", getClsSaveFormat(SN, okng_tag, i, clsImgs[i].first)); - } - } - if (isNG == false)//OK - { - putTextHusky(resultImage, utf8_to_gbk("OK").c_str(), cv::Point(50, 50), cv::Scalar(0, 255, 0), 200); - okng_tag = "OK"; - } - else - { - putTextHusky(resultImage, utf8_to_gbk("NG").c_str(), cv::Point(50, 50), cv::Scalar(0, 0, 255), 200); - plcResult = "2"; - } - cv::resize(resultImage, resultImage, cv::Size(), 0.5, 0.5); - resMat.push_back(resultImage); - if (resMat.size() > 0) - { - addImgToSaveStruct(seg_detectImage, "0", getSegSaveFormat(SN, okng_tag));//存seg图 - addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, okng_tag));//存结果图 - } - addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okng_tag));//存原图图 - - return true; - /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ -#else - //存图数据加保存队列,加锁,避免数据访问冲突 - bool jiXingEnable = data->service->_paramSyncManager->get("极性", "极性判定启用", true).toBool(); - QByteArray plcResult = "1"; - cv::Mat sourceImg; - data->getOriImg(0).copyTo(sourceImg); - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - bool isNG = halconProcess(sourceImg, Paint); - - TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - if (isNG)//OK - { - textPainter.putText(Paint, "OK", cv::Point(100, 50), cv::Scalar(0, 255, 0)); - } - else - { - textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 0, 255)); - data->halconOK = false; - if(jiXingEnable == true) - plcResult = "2"; - } - if (jiXingEnable == false) - plcResult = "1";//强制OK - data->insertResultImg(Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - return true; -#endif - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "NG", cv::Point(1000, 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");//结果反馈 - return true; -} -class _581_YuHan_hanqian : public mission { -public: - _581_SX_Single_triggerTemplate< yuHanParams> in_lv_top_1; - _581_SX_Single_triggerTemplate< yuHanParams> in_lv_down_2; - _581_SX_Single_triggerTemplate< yuHanParams> in_tong_top_3; - _581_SX_Single_triggerTemplate< yuHanParams> in_tong_down_4; - - yuHanParams tongDetParams; - yuHanParams lvDetParams; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); - - lvDetParams.isTong = false; - } - bool initCustom() { -#pragma region 注册触发器回调 - in_lv_top_1.init("Camera1", "极性检测-相机1", { { 400, 1,{410},"401","402",-1} }, 1, &lvDetParams, _serviceManager, bridge, jixingjiance); - in_lv_down_2.init("Camera2", "极性检测-相机2", { { 430, 1,{440},"431","432",-1 }}, 1, & lvDetParams, _serviceManager, bridge, jixingjiance); - in_tong_top_3.init("Camera3", "极性检测-相机3", { { 460,1,{470},"461","462",-1} }, 1, &tongDetParams, _serviceManager, bridge, jixingjiance); - in_tong_down_4.init("Camera4", "极性检测-相机4", { { 490, 1,{500},"491","492",-1 }}, 1, & tongDetParams, _serviceManager, bridge, jixingjiance); - -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/602/YH/581_YuHan_jixing/CMakeLists.txt b/src/mission/602/YH/581_YuHan_jixing/CMakeLists.txt deleted file mode 100644 index 76e9200..0000000 --- a/src/mission/602/YH/581_YuHan_jixing/CMakeLists.txt +++ /dev/null @@ -1,77 +0,0 @@ -# 获取获取当前目录名 -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/602/YH/CMakeLists.txt b/src/mission/602/YH/CMakeLists.txt deleted file mode 100644 index f9a95fd..0000000 --- a/src/mission/602/YH/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# 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 ${}) diff --git a/src/mission/602/ZH/581_ZhongHan_dibutiejiao/CMakeLists.txt b/src/mission/602/ZH/581_ZhongHan_dibutiejiao/CMakeLists.txt deleted file mode 100644 index 76e9200..0000000 --- a/src/mission/602/ZH/581_ZhongHan_dibutiejiao/CMakeLists.txt +++ /dev/null @@ -1,77 +0,0 @@ -# 获取获取当前目录名 -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/602/ZH/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp b/src/mission/602/ZH/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp deleted file mode 100644 index 6b58c7a..0000000 --- a/src/mission/602/ZH/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp +++ /dev/null @@ -1,470 +0,0 @@ -#include <581_ZhongHan_hanhou.h> - -void exceptionResume(std::shared_ptr data, zhongHan3DParams* _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); - 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");//结果反馈 -} -void exceptionResume(std::shared_ptr data, zhongHan2dCeLiangParams* _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); - 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");//结果反馈 -} -void exceptionResume(std::shared_ptr data, zhongHan2dCeMianParams* _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); - 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");//结果反馈 -} -cv::Scalar judgement(const double& value, const double& limitHigh, const double& limitLow, const bool&enable,QByteArray& result) { - if (value > limitHigh || value < limitLow) { - if (enable == true) - result = "2"; - return cv::Scalar(0, 0, 255); - } - return cv::Scalar(0, 255, 0); -} -bool zhongHan_hanHouCeLiang(std::shared_ptr data, zhongHan2dCeLiangParams* _detParams, sx_581_address address) { - try - { - - QByteArray plcResult = "1"; - double hanYinDingBuDaoXinBaoLimitHigh = data->service->_paramSyncManager->get("焊后检测", "芯包顶部-焊印上水平边mm(上限)", 11.00).toDouble(); - double hanYinDingBuDaoXinBaoLimitLow = data->service->_paramSyncManager->get("焊后检测", "芯包顶部-焊印上水平边mm(下限)", 9.00).toDouble(); - double hanYinDingBuDaoXinBaoLimitEnable = data->service->_paramSyncManager->get("焊后检测", "芯包顶部-焊印上水平边判定启用", true).toBool(); - - //75~119 - double hanYinMianJiLimitHigh, hanYinMianJiLimitLow, hanYinMianJiLimitEnable; - double hanYinChangLimitHigh, hanYinChangLimitLow, hanYinChangLimitEnable; - double hanYinKuanLimitHigh, hanYinKuanLimitLow, hanYinKuanLimitEnable; - if (_detParams->isTong == true) { - hanYinMianJiLimitHigh = data->service->_paramSyncManager->get("焊后检测", "铜焊印面积mm²(上限)", 119.00).toDouble(); - hanYinMianJiLimitLow = data->service->_paramSyncManager->get("焊后检测", "铜焊印面积mm²(下限)", 75.00).toDouble(); - hanYinMianJiLimitEnable = data->service->_paramSyncManager->get("焊后检测", "铜焊印面积判定启用", true).toBool(); - hanYinChangLimitHigh = data->service->_paramSyncManager->get("焊后检测", "铜焊印长mm(上限)", 100.0).toDouble(); - hanYinChangLimitLow = data->service->_paramSyncManager->get("焊后检测", "铜焊印长mm(下限)", 0.0).toDouble(); - hanYinChangLimitEnable = data->service->_paramSyncManager->get("焊后检测", "铜焊印长判定启用", true).toBool(); - hanYinKuanLimitHigh = data->service->_paramSyncManager->get("焊后检测", "铜焊印宽mm(上限)", 100.0).toDouble(); - hanYinKuanLimitLow = data->service->_paramSyncManager->get("焊后检测", "铜焊印宽mm(下限)", 0.0).toDouble(); - hanYinKuanLimitEnable = data->service->_paramSyncManager->get("焊后检测", "铜焊印宽判定启用", true).toBool(); - } - else { - hanYinMianJiLimitHigh = data->service->_paramSyncManager->get("焊后检测", "铝焊印面积mm²(上限)", 119.00).toDouble(); - hanYinMianJiLimitLow = data->service->_paramSyncManager->get("焊后检测", "铝焊印面积mm²(下限)", 75).toDouble(); - hanYinMianJiLimitEnable = data->service->_paramSyncManager->get("焊后检测", "铝焊印面积判定启用", true).toBool(); - hanYinChangLimitHigh = data->service->_paramSyncManager->get("焊后检测", "铝焊印长mm(上限)", 100.0).toDouble(); - hanYinChangLimitLow = data->service->_paramSyncManager->get("焊后检测", "铝焊印长mm(下限)", 0.0).toDouble(); - hanYinChangLimitEnable = data->service->_paramSyncManager->get("焊后检测", "铝焊印长判定启用", true).toBool(); - hanYinKuanLimitHigh = data->service->_paramSyncManager->get("焊后检测", "铝焊印宽mm(上限)", 100.0).toDouble(); - hanYinKuanLimitLow = data->service->_paramSyncManager->get("焊后检测", "铝焊印宽mm(下限)", 0.0).toDouble(); - hanYinKuanLimitEnable = data->service->_paramSyncManager->get("焊后检测", "铝焊印宽判定启用", true).toBool(); - } - -#if 0 - if (_detParams->isTong == true) - data->getOriImg(0) = cv::imread("D:\\testImage\\T.bmp", -1); - else - data->getOriImg(0) = cv::imread("D:\\testImage\\L.bmp", -1); -#endif - cv::Mat sourceImg = data->getOriImg(0); - cv::Rect cutRect; - if (_detParams->isTong == true) { - cutRect = cv::Rect(2000, 0, 3000, 3648); - } - if (_detParams->isTong == false) { - cutRect = cv::Rect(400, 0, 3000, 3648); - } - cv::Mat cutImage = sourceImg(cutRect & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows))); - //if (_detParams->isTong == false) { - // cv::rotate(cutImage, cutImage, cv::ROTATE_180); - //} - cv::Mat Paint; - cutImage.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - cv::Mat segProcessMat; - float resizeRate = 5.0; - cv::resize(cutImage, segProcessMat, cv::Size(), 1 / resizeRate, 1 / resizeRate); - cv::Mat segResult = _detParams->seg_hanHouDingWei->Evaluate(segProcessMat); - data->insertSegOriginImg(segProcessMat); - data->insertSegOriginImg(cutImage); - data->insertSegOriginImg(segResult); - - HDevEngineCpp::HDevProcedure proc("_2_Cal_Welding_Distance"); - HDevEngineCpp::HDevProcedureCall procedureCall(proc); - HalconCpp::HObject in_Image = MatToHObject(cutImage); - HalconCpp::HObject in_ImageSeg = MatToHObject(segResult); - - HTuple in_Resolution(data->cameraKeyName == "Camera1" ? 0.0316699 : 0.0340699); - HTuple in_FilePath("./halconFiles/"); - procedureCall.SetInputIconicParamObject("in_Image", in_Image); - procedureCall.SetInputIconicParamObject("in_ImageSeg", in_ImageSeg); - procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); - procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); - procedureCall.Execute(); - HTuple out_BaseLineCor; - HTuple out_LineCor; - HTuple out_Distance1; - HTuple out_Distance2; - HTuple out_HYValues1; - HTuple out_HYValues2; - HTuple out_ColorType; - HTuple out_Flag; - HTuple out_NgTails; - //out_BaseLineCor = procedureCall.GetOutputCtrlParamTuple("out_BaseLineCor"); - out_LineCor = procedureCall.GetOutputCtrlParamTuple("out_LineCor"); - out_Distance1 = procedureCall.GetOutputCtrlParamTuple("out_Distance1"); - out_Distance2 = procedureCall.GetOutputCtrlParamTuple("out_Distance2"); - out_HYValues1 = procedureCall.GetOutputCtrlParamTuple("out_HYValues1"); - out_HYValues2 = procedureCall.GetOutputCtrlParamTuple("out_HYValues2"); - out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); - out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails"); - double xingBaoDingBuDaoHanYinJianJu; - TextRendererZH textPainter(Paint.cols, Paint.rows, 100); - if (out_Flag.D() == 1) - { - { - /*int out_BaseLineCor_L = out_BaseLineCor.Length(); - for (auto i = 0; i < out_BaseLineCor_L / 4; i++) - cv::line(Paint, cv::Point(out_BaseLineCor[i * 4 + 1].D(), out_BaseLineCor[i * 4].D()), - cv::Point(out_BaseLineCor[i * 4 + 3].D(), out_BaseLineCor[i * 4 + 2].D()), - cv::Scalar(0, 255, 0), 20);*/ - - int out_LineCor_L = out_LineCor.Length(); - for (auto i = 0; i < out_LineCor_L / 4; i++) - cv::line(Paint, cv::Point(out_LineCor[i * 4 + 1].D(), out_LineCor[i * 4].D()), - cv::Point(out_LineCor[i * 4 + 3].D(), out_LineCor[i * 4 + 2].D()), - cv::Scalar(0, 255, 0), 20); - } - //1 - { - textPainter.putText(Paint, "上焊印下边缘到连接片圆心水平间距:" + QString::number(out_Distance1[0].D(),'f', 3).toStdString() + "mm", cv::Point(50, 0), cv::Scalar(0, 255, 0)); - if(data->cameraKeyName == "Camera1") { - textPainter.putText(Paint, "上焊印左边缘圆心竖直间距:" + QString::number(out_Distance1[1].D(), 'f', 3).toStdString() + "mm", cv::Point(50, 100), cv::Scalar(0, 255, 0)); - } - else { - textPainter.putText(Paint, "上焊印右边缘圆心竖直间距:" + QString::number(out_Distance1[1].D(), 'f', 3).toStdString() + "mm", cv::Point(50, 100), cv::Scalar(0, 255, 0)); - } - - double hanYinDingBuDaoXinBao = out_Distance1[2].D(); - cv::Scalar scalar = judgement(hanYinDingBuDaoXinBao, hanYinDingBuDaoXinBaoLimitHigh, hanYinDingBuDaoXinBaoLimitLow, hanYinDingBuDaoXinBaoLimitEnable, plcResult); - textPainter.putText(Paint, "上焊印上边缘到芯包间距:" + QString::number(out_Distance1[2].D(), 'f', 3).toStdString() + "mm", cv::Point(50, 200), scalar); - - double hanYinChang = out_HYValues1[0].D(); - scalar = judgement(hanYinChang, hanYinChangLimitHigh, hanYinChangLimitLow, hanYinChangLimitEnable, plcResult); - textPainter.putText(Paint, "上焊印长:" + QString::number(out_HYValues1[0].D(),'f', 3).toStdString() + "mm", cv::Point(50, 300), scalar); - - double hanYinDingKuan = out_HYValues1[1].D(); - scalar = judgement(hanYinDingKuan, hanYinKuanLimitHigh, hanYinKuanLimitLow, hanYinKuanLimitEnable, plcResult); - textPainter.putText(Paint, "上焊印宽:" + QString::number(out_HYValues1[1].D(),'f', 3).toStdString() + "mm", cv::Point(50, 400), scalar); - - double tongHanYinMianJi = out_HYValues1[2].D(); - scalar = judgement(tongHanYinMianJi, hanYinMianJiLimitHigh, hanYinMianJiLimitLow, hanYinMianJiLimitEnable, plcResult); - textPainter.putText(Paint, "上焊印面积:" + QString::number(out_HYValues1[2].D(), 'f', 3).toStdString() + "mm²", cv::Point(50, 500), scalar); - - double jiErToLJPShangBianYuan = out_Distance1[3].D(); - scalar = cv::Scalar(0, 255, 0);//judgement(tongHanYinMianJi, hanYinMianJiLimitHigh, hanYinMianJiLimitLow, hanYinMianJiLimitEnable, plcResult); - textPainter.putText(Paint, "极耳边缘+连接片上边缘距离:" + QString::number(out_Distance1[3].D(), 'f', 3).toStdString() + "mm", cv::Point(50, 600), scalar); - - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(out_Distance1[2].D())); - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(out_Distance1[2].D())); - } - //2 - { - double jiErToLJPShangBianYuan = out_Distance2[3].D(); - cv::Scalar scalar(0, 255, 0);//judgement(tongHanYinMianJi, hanYinMianJiLimitHigh, hanYinMianJiLimitLow, hanYinMianJiLimitEnable, plcResult); - textPainter.putText(Paint, "极耳边缘+连接片下边缘距离:" + QString::number(out_Distance2[3].D(), 'f', 3).toStdString() + "mm", cv::Point(50, cutImage.rows - 750), scalar); - - double tongHanYinMianJi = out_HYValues2[2].D(); - scalar = judgement(tongHanYinMianJi, hanYinMianJiLimitHigh, hanYinMianJiLimitLow, hanYinMianJiLimitEnable, plcResult); - textPainter.putText(Paint, "下焊印面积:" + QString::number(out_HYValues2[2].D(), 'f', 3).toStdString() + "mm²", cv::Point(50, cutImage.rows - 650), scalar); - - double hanYinDingKuan = out_HYValues2[1].D(); - scalar = judgement(hanYinDingKuan, hanYinKuanLimitHigh, hanYinKuanLimitLow, hanYinKuanLimitEnable, plcResult); - textPainter.putText(Paint, "下焊印宽:" + QString::number(out_HYValues2[1].D(), 'f', 3).toStdString() + "mm", cv::Point(50, cutImage.rows - 550), scalar); - - double hanYinChang = out_HYValues2[0].D(); - scalar = judgement(hanYinChang, hanYinChangLimitHigh, hanYinChangLimitLow, hanYinChangLimitEnable, plcResult); - textPainter.putText(Paint, "下焊印长:" + QString::number(out_HYValues2[0].D(), 'f', 3).toStdString() + "mm", cv::Point(50, cutImage.rows - 450), scalar); - - - double hanYinDingBuDaoXinBao = out_Distance2[2].D(); - scalar = judgement(hanYinDingBuDaoXinBao, hanYinDingBuDaoXinBaoLimitHigh, hanYinDingBuDaoXinBaoLimitLow, hanYinDingBuDaoXinBaoLimitEnable, plcResult); - textPainter.putText(Paint, "下焊印下边缘到芯包间距:" + QString::number(out_Distance2[2].D(), 'f', 3).toStdString() + "mm", cv::Point(50, cutImage.rows - 350), scalar); - - textPainter.putText(Paint, "下焊印上边缘到连接片圆心水平间距:" + QString::number(out_Distance2[0].D(), 'f', 3).toStdString() + "mm", cv::Point(50, cutImage.rows - 250), cv::Scalar(0, 255, 0)); - if (data->cameraKeyName == "Camera1") { - textPainter.putText(Paint, "下焊印左边缘到连接片圆心竖直间距:" + QString::number(out_Distance2[1].D(), 'f', 3).toStdString() + "mm", cv::Point(50, cutImage.rows - 150), cv::Scalar(0, 255, 0)); - } - else { - textPainter.putText(Paint, "下焊印右边缘到连接片圆心竖直间距:" + QString::number(out_Distance2[1].D(), 'f', 3).toStdString() + "mm", cv::Point(50, cutImage.rows - 150), cv::Scalar(0, 255, 0)); - } - - - - if (data->cameraKeyName == "Camera1") { - data->service->_triggerManager->writeFloat("D5800_" + QByteArray::number(out_Distance1[2].D())); - data->service->_triggerManager->writeFloat("D5804_" + QByteArray::number(out_Distance2[2].D())); - - data->service->_triggerManager->writeFloat("D5820_" + QByteArray::number(out_Distance1[0].D())); - data->service->_triggerManager->writeFloat("D5822_" + QByteArray::number(out_Distance2[0].D())); - - data->service->_triggerManager->writeFloat("D5824_" + QByteArray::number(out_Distance1[1].D())); - data->service->_triggerManager->writeFloat("D5826_" + QByteArray::number(out_Distance2[1].D())); - } - else { - data->service->_triggerManager->writeFloat("D5808_" + QByteArray::number(out_Distance1[2].D())); - data->service->_triggerManager->writeFloat("D5812_" + QByteArray::number(out_Distance2[2].D())); - - data->service->_triggerManager->writeFloat("D5828_" + QByteArray::number(out_Distance1[0].D())); - data->service->_triggerManager->writeFloat("D5830_" + QByteArray::number(out_Distance2[0].D())); - - data->service->_triggerManager->writeFloat("D5832_" + QByteArray::number(out_Distance1[1].D())); - data->service->_triggerManager->writeFloat("D5834_" + QByteArray::number(out_Distance2[1].D())); - } - } - } - else - { - textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 255, 0)); - data->halconOK = false; - plcResult = "2"; - } - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - plcResult = "1";//强制OK - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(Paint); - sourceImg.release(); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - return true; - } - CATCH_EXCEPTIONS - exceptionResume(data, _detParams, address, "ERROR"); - return true; -} -std::vector aiEvaluate(cv::Mat input, cv::Mat& Paint, bool& isNG, zhongHan2dCeMianParams* _detParams) -{ - std::vector clsImgs; - cv::Mat forSeg; - input.copyTo(forSeg); - cv::Mat segRes = ~_detParams->seg_ceMian->Evaluate(forSeg); - std::vector>contours; - cv::findContours(segRes, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); - int clsIndex = 0; - TextRendererZH textPainter(Paint.cols, Paint.rows, 50); - for (auto& contour : contours) { - clsIndex++; - cv::Rect rect = cv::boundingRect(contour); - if (rect.width < 200 || rect.height < 200) - continue; - cv::Mat clsImg = cutImg2Cls(rect, input); - //cv::Mat clsImg = cutLabelImg(input, 128, 128, rect, 0, 1, 0); - int claResult = _detParams->cls_ceMian->Evaluate(clsImg); - clsImgs.push_back(clsImg); - switch (claResult) - { - case 0://OK - cv::rectangle(Paint, rect, cv::Scalar(0, 255, 0), 3); - break; - case 1://NG - cv::rectangle(Paint, rect, cv::Scalar(0, 0, 255), 3); - cv::drawContours(Paint, contours, clsIndex - 1, cv::Scalar(0, 0, 255),2); - textPainter.putText(Paint, "NG" , cv::Point(rect.x, rect.y), cv::Scalar(0, 0, 255)); - isNG = true; - break; - case 2:// - textPainter.putText(Paint, "撕裂", cv::Point(rect.x, rect.y), cv::Scalar(0, 0, 255)); - cv::rectangle(Paint, rect, cv::Scalar(0, 0, 255), 3); - isNG = true; - break; - } - - } - return clsImgs; -} -bool zhongHan_hanHouCeMian(std::shared_ptr data, zhongHan2dCeMianParams* _detParams, sx_581_address address) -{ - try - { - - cv::Mat segImage, cutImage, img2D = data->getOriImg(0); - cv::resize(data->getOriImg(0), segImage, cv::Size(), 0.2, 0.2); - segImage = ~_detParams->seg_JiErDIngWei->Evaluate(segImage); - std::vector> contours; - cv::findContours(segImage, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); - if (contours.size() != 0) { - int maxIndex = 0; - double maxArea = cv::contourArea(contours[0]); - for (int i = 0; i < contours.size(); i++) { - double area = cv::contourArea(contours[i]); - if (area > maxArea) { - maxIndex = i; - maxArea = area; - } - } - cv::Rect ROI = cv::boundingRect(contours[maxIndex]); - ROI.x = ROI.x * 5 - 30; - ROI.y = ROI.y * 5 - 30; - ROI.width = ROI.width * 5 + 60; - ROI.height = ROI.height * 5 + 60; - ROI = ROI & (cv::Rect(0, 0, img2D.cols, img2D.rows)); - img2D(ROI).copyTo(cutImage); - } - - cv::Mat Paint; - cutImage.copyTo(Paint); - bool isNG = false; - - std::vector clsImgs; - clsImgs.resize(0); - - //调机时屏蔽,跑料打开 - clsImgs = aiEvaluate(cutImage, Paint, isNG,_detParams); - TextRendererZH textPainter(Paint.cols, Paint.rows, 120); - - if (isNG == true) { - textPainter.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); - } - else { - textPainter.putText(Paint, "OK", cv::Point(0, 50), cv::Scalar(0, 255, 0)); - } - //for (int i = 0; i < clsImgs.size(); i++) { - // data->clsOriginImgs.push_back({ std::to_string(i),clsImgs[i] }); - //} - data->insertResultImg(Paint); - data->insertSegOriginImg(cutImage); - - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 - } - CATCH_EXCEPTIONS - exceptionResume(data, _detParams, address, "ERROR"); - return true; - -} -halconResult halconProcess(const cv::Mat& imageH, const cv::Mat& imageG, int cnt, handdleAI::pSegmentation* ptr) -{ - halconResult hResult; - imageG.copyTo(hResult.Paint); - if (hResult.Paint.channels() == 1) - cvtColor(hResult.Paint, hResult.Paint, cv::COLOR_GRAY2BGR); - try - { - HDevEngineCpp::HDevProcedure proc("_2_FinalWelding_HY_Height"); - HDevProcedureCall procedureCall(proc); - - HObject in_ImageH, in_ImageG, in_ImageSeg; - - in_ImageH = MatToHObject(imageH); - in_ImageG = MatToHObject(imageG); - hResult.segResult = ptr->Evaluate(imageG); - in_ImageSeg = MatToHObject(hResult.segResult); - procedureCall.SetInputIconicParamObject("in_ImageH", in_ImageH); - procedureCall.SetInputIconicParamObject("in_ImageG", in_ImageG); - procedureCall.SetInputIconicParamObject("in_ImageSeg", in_ImageSeg); - - - procedureCall.SetInputCtrlParamTuple("in_xResolution", 0.004); - procedureCall.SetInputCtrlParamTuple("in_yResolution", 0.0125); - procedureCall.SetInputCtrlParamTuple("in_zResolution", 0.0008); - procedureCall.Execute();//执行halcon程序 - - HTuple out_HYNumber = procedureCall.GetOutputCtrlParamTuple("out_HYNumber");//获取输出控制类变量 - HTuple out_HYPointX = procedureCall.GetOutputCtrlParamTuple("out_HYPointX");//获取输出控制类变量 - HTuple out_HYPointY = procedureCall.GetOutputCtrlParamTuple("out_HYPointY");//获取输出控制类变量 - HTuple out_HYHeightValue = procedureCall.GetOutputCtrlParamTuple("out_HYHeightValue");//获取输出控制类变量 - HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出图像类变量 - HTuple out_NgDetails = procedureCall.GetOutputCtrlParamTuple("out_NgDetails");//获取输出图像类变量 - - int flag = out_Flag.D(); - TextRendererZH textPainter(hResult.Paint.cols, hResult.Paint.rows, 120); - if (flag == 1) { - hResult.hyCount = (int)out_HYNumber[0].D() + (int)out_HYNumber[1].D(); - textPainter.putText(hResult.Paint, "上焊印数量:" + std::to_string((int)out_HYNumber[0].D()), cv::Point(0, 50), cv::Scalar(0, 255, 0)); - textPainter.putText(hResult.Paint, "下焊印数量:" + std::to_string((int)out_HYNumber[1].D()), cv::Point(0, 150), cv::Scalar(0, 255, 0)); - - hResult.data.topHanYinCount = (int)out_HYNumber[0].D(); - hResult.data.bottomHanYinCount = (int)out_HYNumber[1].D(); - std::vector data; - for (int i = 0; i < out_HYPointX.Length() && i < out_HYPointY.Length() && i < out_HYHeightValue.Length(); i++) - { - Cross(hResult.Paint, cv::Point(out_HYPointX[i].D(), out_HYPointY[i].D()), 5, 2, cv::Scalar(0, 255, 0)); - putText(hResult.Paint, - std::to_string(out_HYHeightValue[i].D()), - cv::Point(out_HYPointX[i].D() - 30, out_HYPointY[i].D() - 15), - 1, 1, cv::Scalar(0, 255, 0), 1); - data.push_back(out_HYHeightValue[i].D()); - } - - } - else { - textPainter.putText(hResult.Paint, out_NgDetails.ToString().Text(), cv::Point(0, 250), cv::Scalar(0, 255, 0)); - hResult.result = false; - } - } - CATCH_EXCEPTIONS - return hResult; -} -bool zhongHan_hanHou3D(std::shared_ptr data, zhongHan3DParams* _detParams, sx_581_address address) -{ - try - { - //data->getOriImg(0) = cv::imread("D:\\testImage\\G.tiff", -1); - //data->oriImgs[1] = cv::imread("D:\\testImage\\H.tiff", -1); - cv::Mat imageG = data->getOriImg(0), imageH = data->getOriImg(0); - halconResult result1 = halconProcess(imageH, imageG, 0, _detParams->seg_3dHanYinDingWei); - data->insertSegOriginImg(result1.segResult); - - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_1");//结果反馈 - data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 1) + "_1");//结果反馈 - - //cv::Mat PaintSum(result1.Paint.rows, result1.Paint.cols + result2.Paint.cols, CV_8UC3); - //result1.Paint.copyTo(PaintSum(cv::Rect(0, 0, result1.Paint.cols, result1.Paint.rows))); - //result2.Paint.copyTo(PaintSum(cv::Rect(result1.Paint.cols, 0, result1.Paint.cols, result1.Paint.rows))); - data->insertResultImg(result1.Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 - return true; - } - CATCH_EXCEPTIONS - exceptionResume(data, _detParams, address,"ERROR"); - return true; - -} - -mission* createMission() { - return new _581_ZhongHan_hanhou(); -} -void destroyMission(mission* _mission) { - delete _mission; -} \ No newline at end of file diff --git a/src/mission/602/ZH/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h b/src/mission/602/ZH/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h deleted file mode 100644 index a3bafac..0000000 --- a/src/mission/602/ZH/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; -#pragma endregion -class zhongHan2dCeLiangParams { -public: - handdleAI::pSegmentation* seg_hanHouDingWei = nullptr; - bool isTong = true; -}; -class zhongHan2dCeMianParams { -public: - handdleAI::pSegmentation* seg_JiErDIngWei = nullptr; - handdleAI::pSegmentation* seg_ceMian = nullptr; - handdleAI::pClassification* cls_ceMian = nullptr; - bool isTong = true; -}; -class zhongHan3DParams { -public: - handdleAI::pSegmentation* seg_3dHanYinDingWei = nullptr; - bool isTong = true; -}; - -struct halconResult { - struct halconData { - int topHanYinCount = 0; - int bottomHanYinCount = 0; - double avgHanYinDepth = 0; - double maxHanYinDepth = 0; - double minHanYinDepth = 0; - bool detResultIsOk = true; - }; - cv::Mat Paint; - int hyCount; - cv::Mat segResult; - bool result; - halconData data; -}; - -bool zhongHan_hanHouCeLiang(std::shared_ptr data, zhongHan2dCeLiangParams* _detParams, sx_581_address address); -std::vector aiEvaluate(cv::Mat input, cv::Mat& Paint, bool& isNG, zhongHan2dCeMianParams* _detParams); -bool zhongHan_hanHouCeMian(std::shared_ptr data, zhongHan2dCeMianParams* _detParams, sx_581_address address); -halconResult halconProcess(const cv::Mat& imageH, const cv::Mat& imageG, int cnt, handdleAI::pSegmentation* ptr); -bool zhongHan_hanHou3D(std::shared_ptr data, zhongHan3DParams* _detParams, sx_581_address address); - -class _581_ZhongHan_hanhou : public mission { -public: - _581_SX_Single_triggerTemplate< zhongHan2dCeLiangParams> lv_top_1; - _581_SX_Single_triggerTemplate< zhongHan2dCeMianParams> lv_left45_2; - _581_SX_Single_triggerTemplate< zhongHan2dCeMianParams> lv_right45_3; - _581_SX_Single_triggerTemplate< zhongHan3DParams> _3D_1; - - _581_SX_Single_triggerTemplate< zhongHan2dCeLiangParams> tong_top_5; - _581_SX_Single_triggerTemplate< zhongHan2dCeMianParams> tong_left45_6; - _581_SX_Single_triggerTemplate< zhongHan2dCeMianParams> tong_right45_7; - _581_SX_Single_triggerTemplate< zhongHan3DParams> _3D_2; - zhongHan2dCeLiangParams tongZhongHan2dCeLiangParams; - zhongHan2dCeLiangParams lvZhongHan2dCeLiangParams; - std::vector< zhongHan2dCeMianParams> tongZhongHan2dCeMianParams = std::vector< zhongHan2dCeMianParams>(2); - std::vector< zhongHan2dCeMianParams> lvZhongHan2dCeMianParams = std::vector< zhongHan2dCeMianParams>(2); - zhongHan3DParams tongZhongHan3DParams; - zhongHan3DParams lvZhongHan3DParams; - bool initOnce = false; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); - - if (initOnce == false) { - tongZhongHan2dCeLiangParams.seg_hanHouDingWei = handdleAI::CreateSegObjS("./handleAiModels/seg-hanHouDingWei.BHD", 64, 0); - lvZhongHan2dCeLiangParams.seg_hanHouDingWei = handdleAI::CreateSegObjS("./handleAiModels/seg-hanHouDingWei.BHD", 64, 1); - - tongZhongHan2dCeMianParams[0].seg_JiErDIngWei = handdleAI::CreateSegObjS("./handleAiModels/pSeg_JiErDingWei_45_T_GPU0.BHD", 64, 0); - tongZhongHan2dCeMianParams[0].seg_ceMian = handdleAI::CreateSegObjS("./handleAiModels/seg_ZhongHan_HanHou_45_T_GPU0.BHD", 64, 0); - tongZhongHan2dCeMianParams[0].cls_ceMian = handdleAI::CreateClsObjV3("./handleAiModels/cls_ZhongHan_HanHou_45_T_GPU0.BHD", 0, 1); - - tongZhongHan2dCeMianParams[1].seg_JiErDIngWei = handdleAI::CreateSegObjS("./handleAiModels/pSeg_JiErDingWei_45_T_GPU0.BHD", 64, 0); - tongZhongHan2dCeMianParams[1].seg_ceMian = handdleAI::CreateSegObjS("./handleAiModels/seg_ZhongHan_HanHou_45_T_GPU0.BHD", 64, 0); - tongZhongHan2dCeMianParams[1].cls_ceMian = handdleAI::CreateClsObjV3("./handleAiModels/cls_ZhongHan_HanHou_45_T_GPU0.BHD", 0, 1); - - lvZhongHan2dCeMianParams[0].seg_JiErDIngWei = handdleAI::CreateSegObjS("./handleAiModels/pSeg_JiErDingWei_45_L_GPU1.BHD", 64, 1); - lvZhongHan2dCeMianParams[0].seg_ceMian = handdleAI::CreateSegObjS("./handleAiModels/seg_ZhongHan_HanHou_45_L_GPU1.BHD", 64, 1); - lvZhongHan2dCeMianParams[0].cls_ceMian = handdleAI::CreateClsObjV3("./handleAiModels/cls_ZhongHan_HanHou_45_L_GPU1.BHD", 1, 1); - - lvZhongHan2dCeMianParams[1].seg_JiErDIngWei = handdleAI::CreateSegObjS("./handleAiModels/pSeg_JiErDingWei_45_L_GPU1.BHD", 64, 1); - lvZhongHan2dCeMianParams[1].seg_ceMian = handdleAI::CreateSegObjS("./handleAiModels/seg_ZhongHan_HanHou_45_L_GPU1.BHD", 64, 1); - lvZhongHan2dCeMianParams[1].cls_ceMian = handdleAI::CreateClsObjV3("./handleAiModels/cls_ZhongHan_HanHou_45_L_GPU1.BHD", 1, 1); - - lvZhongHan2dCeLiangParams.isTong = false; - - tongZhongHan3DParams.seg_3dHanYinDingWei = handdleAI::CreateSegObjS("./handleAiModels/seg_3dHanYin.BHD", 16, 0); - lvZhongHan3DParams.seg_3dHanYinDingWei = handdleAI::CreateSegObjS("./handleAiModels/seg_3dHanYin.BHD", 16, 1); - - initOnce = true; - } - } - bool initCustom() { -#pragma region 注册触发器回调 - lv_top_1.init("Camera1", "焊印检测-内-铜-相机1(90°)", { { 5360, 1,{5340,5420},"5362","5364",5800} }, 1, &tongZhongHan2dCeLiangParams, _serviceManager, bridge, zhongHan_hanHouCeLiang, "90°存图"); - lv_left45_2.init("Camera2", "翻折撕裂-内-铜-相机2(45°)", { { 5370, 1,{5340,5420},"5372","5374",-1} }, 1, &tongZhongHan2dCeMianParams[0], _serviceManager, bridge, zhongHan_hanHouCeMian,"45°存图"); - lv_right45_3.init("Camera3", "翻折撕裂-内-铜-相机3(45°)", { { 5380,1,{5340,5420},"5382","5384",5406} }, 1, &tongZhongHan2dCeMianParams[1], _serviceManager, bridge, zhongHan_hanHouCeMian, "45°存图"); - _3D_1.init("Camera4", "焊后检测-3D相机2(右)" , { { 5400, 1,{5340,5420},"5402","5404",-1} }, 1, &tongZhongHan3DParams, _serviceManager, bridge, zhongHan_hanHou3D,"3D存图"); - - tong_top_5.init("Camera5", "焊印检测-外-铝-相机5(90°)", { { 5440, 1,{5340,5420},"5442","5444",5804} }, 1, &lvZhongHan2dCeLiangParams, _serviceManager, bridge, zhongHan_hanHouCeLiang, "90°存图"); - tong_left45_6.init("Camera6", "翻折撕裂-外-铝-相机6(45°)", { { 5450,1,{5340,5420},"5452","5454",-1} }, 1, &lvZhongHan2dCeMianParams[0], _serviceManager, bridge, zhongHan_hanHouCeMian, "45°存图"); - tong_right45_7.init("Camera7", "翻折撕裂-外-铝-相机7(45°)", { { 5460, 1,{5340,5420},"5462","5464",5486} }, 1, &lvZhongHan2dCeMianParams[1], _serviceManager, bridge, zhongHan_hanHouCeMian, "45°存图"); - _3D_2.init("Camera8", "焊后检测-3D相机1(左)", { { 5480, 1,{5340,5420},"5482","5484",-1} }, 1, &lvZhongHan3DParams, _serviceManager, bridge, zhongHan_hanHou3D, "3D存图"); -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/602/ZH/581_ZhongHan_hanhou/CMakeLists.txt b/src/mission/602/ZH/581_ZhongHan_hanhou/CMakeLists.txt deleted file mode 100644 index 76e9200..0000000 --- a/src/mission/602/ZH/581_ZhongHan_hanhou/CMakeLists.txt +++ /dev/null @@ -1,77 +0,0 @@ -# 获取获取当前目录名 -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/602/ZH/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp b/src/mission/602/ZH/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp deleted file mode 100644 index 2ffa3c3..0000000 --- a/src/mission/602/ZH/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include <581_ZhongHan_hanqian.h> - -mission* createMission() { - return new _581_YuHan_hanqian(); -} -void destroyMission(mission* _mission) { - delete _mission; -} \ No newline at end of file diff --git a/src/mission/602/ZH/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h b/src/mission/602/ZH/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h deleted file mode 100644 index 7e80184..0000000 --- a/src/mission/602/ZH/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h +++ /dev/null @@ -1,399 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace HDevEngineCpp; -using namespace HalconCpp; -struct hanQianDingWeiSubresult { - double Out_Vale_L_1 = -1;//铝(负)极的包膜距离(mm) - double Out_Vale_L_2 = -1;//铝(负)极连接片中心的和上极耳电芯边缘距离(mm) - double Out_Vale_L_3 = -1;//铝(负)极连接片中心的和下极耳电芯边缘距离(mm) - double Out_Vale_L_4 = -1;//铝(负)极连接片中心的和上极耳水平边缘距离(mm) - double Out_Vale_L_5 = -1;//铝(负)极连接片中心的和下极耳水平边缘距离(mm) - double Out_Vale_L_6 = -1;//铝(负)极连接片上边缘的和上极耳下边缘距离(mm) - double Out_Vale_L_7 = -1;//铝(负)极连接片下边缘的和下极耳上边缘距离(mm) - double extremum_Value = -1; - - cv::Point circleCenter; - double radius = 1; - std::vector lines; - - bool algoFailed = false; -}; -class zhongHanHanQianParams { -public: - QMutex* mutex = new QMutex(); - QQueue resultQueue; - QQueue mats; - ~zhongHanHanQianParams() { - delete mutex; - } - - int waitMs = 3000; - void insertImg(HObject& input) { - QMutexLocker locker(mutex); - if (mats.size() > 0) { - qWarning() << "焊前定位有遗留的图像,已清除"; - mats.clear(); - } - mats.enqueue(input);//发送检测数据到主线程 - } - bool waitImage(HObject& out) { - int cnt = 0; - while (mats.size() == 0 && cnt < waitMs) { - QThread::msleep(2); - cnt += 2; - } - if (mats.size() != 0) { - QMutexLocker locker(mutex); - out = mats.dequeue(); - return true; - } - return false; - } - void insertResult(hanQianDingWeiSubresult input) { - QMutexLocker locker(mutex); - if (resultQueue.size() > 0) { - qWarning() << "焊前定位有遗留的结果,已清除"; - resultQueue.clear(); - } - resultQueue.enqueue(input);//发送检测数据到主线程 - } - bool waitResult(hanQianDingWeiSubresult& out) { - int cnt = 0; - while (resultQueue.size() == 0 && cnt < waitMs) { - QThread::msleep(2); - cnt += 2; - } - if (resultQueue.size() != 0) { - QMutexLocker locker(mutex); - out = resultQueue.dequeue(); - resultQueue.clear(); - return true; - } - return false; - } -}; - -bool hanQianCeLiang_Main(std::shared_ptr data, zhongHanHanQianParams* _detParams, sx_581_address address) { - try{ - QByteArray plcResult = "1"; -#if 0 - data->getOriImg(0) = cv::imread("D:\\testImage\\T.bmp", -1); -#endif - double xinBaoJianJuLimitHigh = data->service->_paramSyncManager->get("焊前检测","芯包间距(上限)", 72.00).toDouble(); - double xinBaoJianJuLimitLow = data->service->_paramSyncManager->get("焊前检测", "芯包间距(下限)", 68.00).toDouble(); - bool xinBaoJianJuLimitEnable = data->service->_paramSyncManager->get("焊前检测", "芯包间距判定启用", true).toBool(); - - double xinBaoDingBuDaoYuanXinLimitHigh = data->service->_paramSyncManager->get("焊前检测", "芯包顶部到圆心距离(上限)", 35.00).toDouble(); - double xinBaoDingBuDaoYuanXinLimitLow = data->service->_paramSyncManager->get("焊前检测", "芯包顶部到圆心距离(下限)", 33.00).toDouble(); - bool xinBaoDingBuDaoYuanXinLimitEnable = data->service->_paramSyncManager->get("焊前检测", "芯包顶部到圆心距离判定启用", true).toBool(); - - double lianJiePianJianJuLimitHigh = data->service->_paramSyncManager->get("焊前检测", "连接片间距(上限)", 124.00).toDouble(); - double lianJiePianJianJuLimitLow = data->service->_paramSyncManager->get("焊前检测", "连接片间距(下限)", 122.00).toDouble(); - bool lianJiePianJianJuLimitEnable = data->service->_paramSyncManager->get("焊前检测", "连接片间距判定启用", true).toBool(); - - cv::Mat sourceImg = data->getOriImg(0); - sourceImg(cv::Rect(2400, 0, 3000, 3648)).copyTo(sourceImg); - data->insertSegOriginImg(sourceImg); - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - - HDevEngineCpp::HDevProcedure proc("_2_Cal_ZH_LJP_Distance"); - HDevProcedureCall procedureCall(proc); - - //vs+halcon联调debug - /*myEngine.StartDebugServer(); - procedureCall.SetWaitForDebugConnection(true);*/ - - HalconCpp::HObject ho_Image_T; - HalconCpp::HObject ho_Image_L; - HalconCpp::HTuple in_Resolution = 0.032594099; - HalconCpp::HTuple in_FilePath = "./halconFiles/ZH_HanYin/"; - HalconCpp::HTuple in_LineType = "602"; - ho_Image_T = MatToHObject(sourceImg); - //等待副线程传入图像 - bool getImgResult = _detParams->waitImage(ho_Image_L); - - procedureCall.SetInputIconicParamObject("in_Image1", ho_Image_T); - procedureCall.SetInputIconicParamObject("in_Image2", ho_Image_L); - procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); - procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); - procedureCall.SetInputCtrlParamTuple("in_LineType", in_LineType); - procedureCall.Execute();//执行halcon程序 - - HalconCpp::HTuple out_Distance; - HalconCpp::HTuple out_LinePoint; - HalconCpp::HTuple out_Circle; - HalconCpp::HTuple out_Flag; - HalconCpp::HTuple out_NGTails; - out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量 - out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 - out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");//获取输出控制类变量 - out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - out_NGTails = procedureCall.GetOutputCtrlParamTuple("out_NGTails"); - - int flag = out_Flag.D(); - TextRendererZH textPainter(Paint.cols, Paint.rows, 90); - if (flag == 1) - { - double Out_Vale_T_1 = out_Distance[0].D();//铜(正)极的包膜距离(mm) - double Out_Vale_T_2 = out_Distance[1].D();//铜(正)极连接片中心的和上极耳电芯边缘距离(mm) - double Out_Vale_T_3 = out_Distance[2].D();//铜(正)极连接片中心的和下极耳电芯边缘距离(mm) - double Out_Vale_T_4 = out_Distance[3].D();//铜(正)极连接片中心的和上极耳水平边缘距离(mm) - double Out_Vale_T_5 = out_Distance[4].D();//铜(正)极连接片中心的和下极耳水平边缘距离(mm) - double Out_Vale_T_6 = out_Distance[5].D();//铜(正)极连接片上边缘的和上极耳下边缘距离(mm) - double Out_Vale_T_7 = out_Distance[6].D();//铜(正)极连接片下边缘的和下极耳上边缘距离(mm) - - double Out_Vale_L_1 = out_Distance[7].D();//铝(负)极的包膜距离(mm) - double Out_Vale_L_2 = out_Distance[8].D();//铝(负)极连接片中心的和上极耳电芯边缘距离(mm) - double Out_Vale_L_3 = out_Distance[9].D();//铝(负)极连接片中心的和下极耳电芯边缘距离(mm) - double Out_Vale_L_4 = out_Distance[10].D();//铝(负)极连接片中心的和上极耳水平边缘距离(mm) - double Out_Vale_L_5 = out_Distance[11].D();//铝(负)极连接片中心的和下极耳水平边缘距离(mm) - double Out_Vale_L_6 = out_Distance[12].D();//铝(负)极连接片上边缘的和上极耳下边缘距离(mm) - double Out_Vale_L_7 = out_Distance[13].D();//铝(负)极连接片下边缘的和下极耳上边缘距离(mm) - - double extremum_Value = out_Distance[14].D();//铜(正)极和铝(负)极的中心距离(mm) - - //发送到另一算法线程 - hanQianDingWeiSubresult _calResult; - _calResult.Out_Vale_L_1 = Out_Vale_L_1; - _calResult.Out_Vale_L_2 = Out_Vale_L_2; - _calResult.Out_Vale_L_3 = Out_Vale_L_3; - _calResult.Out_Vale_L_4 = Out_Vale_L_4; - _calResult.Out_Vale_L_5 = Out_Vale_L_5; - _calResult.Out_Vale_L_6 = Out_Vale_L_6; - _calResult.Out_Vale_L_7 = Out_Vale_L_7; - _calResult.extremum_Value = extremum_Value; - if (out_Circle.Length() > 4) { - _calResult.circleCenter = cv::Point(out_Circle[4].D(), out_Circle[3].D()); - _calResult.radius = out_Circle[5].D(); - } - - for (int i = out_LinePoint.Length() / 2; i < out_LinePoint.Length(); i++) { - _calResult.lines.push_back(out_LinePoint[i].D()); - } - - - _detParams->insertResult(_calResult); - if (Out_Vale_T_1 > xinBaoJianJuLimitHigh || Out_Vale_T_1 < xinBaoJianJuLimitLow) { - - textPainter.putText(Paint, "铜(正)极的芯包间距:" + std::to_string(Out_Vale_T_1), cv::Point(50, 0), cv::Scalar(0, 0, 255)); - data->halconOK = false; - if (xinBaoJianJuLimitEnable == true) - plcResult = "2"; - } - else - textPainter.putText(Paint, "铜(正)极的芯包间距:" + std::to_string(Out_Vale_T_1), cv::Point(50, 0), cv::Scalar(0, 255, 0)); - - textPainter.putText(Paint, "铜(正)极连接片中心的和上极耳电芯边缘距离:" + std::to_string(Out_Vale_T_2), cv::Point(50, 100), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铜(正)极连接片中心的和下极耳电芯边缘距离:" + std::to_string(Out_Vale_T_3), cv::Point(50, 200), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铜(正)极连接片中心的和上极耳水平边缘距离:" + std::to_string(Out_Vale_T_4), cv::Point(50, 300), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铜(正)极连接片中心的和上极耳水平边缘距离:" + std::to_string(Out_Vale_T_5), cv::Point(50, 400), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铜(正)极连接片上边缘的和上极耳下边缘距离:" + std::to_string(Out_Vale_T_6), cv::Point(50, 500), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铜(正)极连接片下边缘的和下极耳上边缘距离:" + std::to_string(Out_Vale_T_7), cv::Point(50, 600), cv::Scalar(0, 255, 0)); - if (extremum_Value > lianJiePianJianJuLimitHigh || extremum_Value < lianJiePianJianJuLimitLow) { - textPainter.putText(Paint, "铜(正)极和铝(负)极的中心距离:" + std::to_string(extremum_Value), cv::Point(50, 700), cv::Scalar(0, 0, 255)); - data->halconOK = false; - if (lianJiePianJianJuLimitEnable == true) - plcResult = "2"; - } - else - textPainter.putText(Paint, "铜(正)极和铝(负)极的中心距离:" + std::to_string(extremum_Value), cv::Point(50, 700), cv::Scalar(0, 255, 0)); - - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(Out_Vale_T_1));//数据1 - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(extremum_Value));//数据2 - for (int i = 0; i < out_LinePoint.Length() / 8; i++){ - cv::line(Paint, cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4].D()), - cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), - cv::Scalar(0, 255, 0), 10, cv::LINE_4); - } - - if (out_Circle.Length() > 2){ - cv::drawMarker(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), cv::Scalar(0, 255, 0), cv::MARKER_CROSS, 200, 5); - cv::circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 5); - } - } - else{ - std::string errTails = out_NGTails.S().Text(); - hanQianDingWeiSubresult _calResult; - _calResult.algoFailed = true; - _detParams->insertResult(_calResult); - textPainter.putText(Paint, "NG" + errTails, cv::Point(0, 50), cv::Scalar(0, 255, 0)); - data->halconOK = false; - } - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - plcResult = "1";//强制OK - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(Paint); - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode); - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "NG", cv::Point(1000, 50), cv::Scalar(0, 255, 0)); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(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");//结果反馈 - return true; -} -bool hanQianCeLiang_Sub(std::shared_ptr data, zhongHanHanQianParams* _detParams, sx_581_address address) { - try { - //测试算法用 - QByteArray plcResult = "1"; - { -#if 0 - data->getOriImg(0) = cv::imread("D:\\testImage\\L.bmp", -1); -#endif - } - double xinBaoJianJuLimitHigh = data->service->_paramSyncManager->get("焊前检测", "芯包间距(上限)", 72.00).toDouble(); - double xinBaoJianJuLimitLow = data->service->_paramSyncManager->get("焊前检测", "芯包间距(下限)", 68.00).toDouble(); - bool xinBaoJianJuLimitEnable = data->service->_paramSyncManager->get("焊前检测", "芯包间距判定启用", true).toBool(); - - double xinBaoDingBuDaoYuanXinLimitHigh = data->service->_paramSyncManager->get("焊前检测", "芯包顶部到圆心距离(上限)", 35.00).toDouble(); - double xinBaoDingBuDaoYuanXinLimitLow = data->service->_paramSyncManager->get("焊前检测", "芯包顶部到圆心距离(下限)", 33.00).toDouble(); - bool xinBaoDingBuDaoYuanXinLimitEnable = data->service->_paramSyncManager->get("焊前检测", "芯包顶部到圆心距离判定启用", true).toBool(); - - double lianJiePianJianJuLimitHigh = data->service->_paramSyncManager->get("焊前检测", "连接片间距(上限)", 124.00).toDouble(); - double lianJiePianJianJuLimitLow = data->service->_paramSyncManager->get("焊前检测", "连接片间距(下限)", 122.00).toDouble(); - bool lianJiePianJianJuLimitEnable = data->service->_paramSyncManager->get("焊前检测", "连接片间距判定启用", true).toBool(); - - cv::Mat sourceImg = data->getOriImg(0); - sourceImg(cv::Rect(0, 0, 3000, 3648)).copyTo(sourceImg); - data->insertSegOriginImg(sourceImg); - cv::Mat Paint; - sourceImg.copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - - HObject image = MatToHObject(sourceImg); - //发送图片 - _detParams->insertImg(image); - - TextRendererZH textPainter(Paint.cols, Paint.rows, 90); - //等待结果 - hanQianDingWeiSubresult _calResult; - bool waitResultResult = _detParams->waitResult(_calResult); - - if (waitResultResult == false) { - data->halconOK = false; - textPainter.putText(Paint, "NG:TimeOut", cv::Point(0, 50), cv::Scalar(0, 255, 0)); - plcResult = "2"; - data->insertResultImg(Paint); - return false; - } - - if (_calResult.algoFailed == false) { - if (_calResult.Out_Vale_L_1 > xinBaoJianJuLimitHigh || _calResult.Out_Vale_L_1 < xinBaoJianJuLimitLow) { - - textPainter.putText(Paint, "铝(负)极的芯包间距:" + std::to_string(_calResult.Out_Vale_L_1), cv::Point(50, 0), cv::Scalar(0, 0, 255)); - if (xinBaoJianJuLimitEnable == true) - plcResult = "2"; - } - else - textPainter.putText(Paint, "铝(负)极的芯包间距:" + std::to_string(_calResult.Out_Vale_L_1), cv::Point(50, 0), cv::Scalar(0, 255, 0)); - - textPainter.putText(Paint, "铝(负)极连接片中心的和上极耳电芯边缘距离:" + std::to_string(_calResult.Out_Vale_L_2), cv::Point(50, 100), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铝(负)极连接片中心的和下极耳电芯边缘距离:" + std::to_string(_calResult.Out_Vale_L_3), cv::Point(50, 200), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铝(负)极连接片中心的和上极耳水平边缘距离:" + std::to_string(_calResult.Out_Vale_L_4), cv::Point(50, 300), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铝(负)极连接片中心的和下极耳水平边缘距离:" + std::to_string(_calResult.Out_Vale_L_5), cv::Point(50, 400), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铝(负)极连接片上边缘的和上极耳下边缘距离:" + std::to_string(_calResult.Out_Vale_L_6), cv::Point(50, 500), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "铝(负)极连接片下边缘的和下极耳上边缘距离:" + std::to_string(_calResult.Out_Vale_L_7), cv::Point(50, 600), cv::Scalar(0, 255, 0)); - if (_calResult.extremum_Value > lianJiePianJianJuLimitHigh || _calResult.extremum_Value < lianJiePianJianJuLimitLow) { - textPainter.putText(Paint, "铜(正)极和铝(负)极的中心距离:" + std::to_string(_calResult.extremum_Value), cv::Point(50, 700), cv::Scalar(0, 0, 255)); - if (lianJiePianJianJuLimitEnable == true) - plcResult = "2"; - } - else - textPainter.putText(Paint, "铜(正)极和铝(负)极的中心距离:" + std::to_string(_calResult.extremum_Value), cv::Point(50, 700), cv::Scalar(0, 255, 0)); - - - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(_calResult.Out_Vale_L_1));//数据1 - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(_calResult.extremum_Value));//数据2 - for (int i = 0; i < _calResult.lines.size() / 4; i++) { - cv::line(Paint, cv::Point(_calResult.lines[i * 4 + 1], _calResult.lines[i * 4]), - cv::Point(_calResult.lines[i * 4 + 3], _calResult.lines[i * 4 + 2]), - cv::Scalar(0, 255, 0), 10, cv::LINE_4); - } - cv::drawMarker(Paint, cv::Point(_calResult.circleCenter.x, _calResult.circleCenter.y), cv::Scalar(0, 255, 0), cv::MARKER_CROSS, 200, 5); - cv::circle(Paint, cv::Point(_calResult.circleCenter.x, _calResult.circleCenter.y), _calResult.radius, cv::Scalar(0, 255, 0), 5); - } - else { - data->halconOK = false; - textPainter.putText(Paint, "NG:algoError", cv::Point(0, 50), cv::Scalar(0, 255, 0)); - plcResult = "2"; - } - - if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) - plcResult = "1";//强制OK - - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(Paint); - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode); - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "NG", cv::Point(1000, 50), cv::Scalar(0, 255, 0)); - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - data->insertResultImg(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");//结果反馈 - return true; -} - -class _581_YuHan_hanqian : public mission { -public: - _581_SX_Single_triggerTemplate tong_1; - _581_SX_Single_triggerTemplate lv_1; - - zhongHanHanQianParams detParams; - bool initOnce = false; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); - - if (initOnce == false) { - - initOnce = true; - } - } - bool initCustom() { -#pragma region 注册触发器回调 - tong_1.init("Camera1", "焊前定位-相机1", { { 5060, 1,{5100,5070},"5062","5064",5066} }, 1, &detParams, _serviceManager, bridge, hanQianCeLiang_Main); - lv_1.init("Camera2", "焊前定位-相机2", { { 5090, 1,{5100,5070},"5092","5094",5096} }, 1, &detParams, _serviceManager, bridge, hanQianCeLiang_Sub); -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/602/ZH/581_ZhongHan_hanqian/CMakeLists.txt b/src/mission/602/ZH/581_ZhongHan_hanqian/CMakeLists.txt deleted file mode 100644 index 76e9200..0000000 --- a/src/mission/602/ZH/581_ZhongHan_hanqian/CMakeLists.txt +++ /dev/null @@ -1,77 +0,0 @@ -# 获取获取当前目录名 -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/602/ZH/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.cpp b/src/mission/602/ZH/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.cpp deleted file mode 100644 index 5e0fe23..0000000 --- a/src/mission/602/ZH/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include <581_ZhongHan_silie_jixing.h> -#include -void aiEvaluate(cv::Mat input, handdleAI::pSegmentation* seg, handdleAI::pClassification* cls,cv::Mat& Paint, bool& isNG){ - cv::Mat forSeg; - input.copyTo(forSeg); - //cv::resize(forSeg, forSeg, cv::Size(), 0.25, 0.25); - cv::Mat segRes; - if (seg != nullptr) - { - segRes = ~seg->Evaluate(forSeg); - cv::resize(segRes, segRes, cv::Size(), 4, 4); - std::vector>contours; - cv::findContours(segRes, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); - int cnt = 0; - for (auto& contour : contours) { - cv::Rect rect = cv::boundingRect(contour); - if (rect.width < 250 || rect.height < 250) - continue; - cv::Mat clsImg = cutImg2Cls(rect, input); - cnt++; - int claResult = cls->Evaluate(clsImg); - TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - switch (claResult) - { - case 0://OK - cv::rectangle(Paint, rect, cv::Scalar(0, 255, 0), 3); - break; - case 1://NG - cv::rectangle(Paint, rect, cv::Scalar(0, 0, 255), 3); - textPainter.putText(Paint,"NG",cv::Point(rect.x, rect.y), cv::Scalar(0, 0, 255)); - isNG = true; - break; - } - } - } - else { - isNG = false; - } - -} -bool lieHenJianCe90(std::shared_ptr data, LieHenJianCeParams* _detParams, sx_581_address address){ - try { - //data->getOriImg(0) = cv::imread("D:/testimg/" + data->cameraKeyName + ".bmp", -1); - cv::Mat sourceImage = data->getOriImg(0); - cv::Mat imgPaint; - sourceImage.copyTo(imgPaint); - QByteArray plcResult = "1"; - cv::Mat afterDingWei; - {//定位 - cv::Mat forDingWei; - cv::resize(sourceImage, forDingWei, cv::Size(), 0.1, 0.1); - cv::Mat dingWeiResult = ~_detParams->dingwei->Evaluate(forDingWei); - cv::Rect dingWeiRect = findMaxAreaContour(dingWeiResult); - if (dingWeiRect.width < 250 || dingWeiRect.height < 250) { - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "NG2", cv::Point(1000, 50), cv::Scalar(0, 255, 0)); - data->insertSegOriginImg(forDingWei); - data->insertSegOriginImg(dingWeiResult); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 - } - dingWeiRect.x *= 10; dingWeiRect.y *= 10; dingWeiRect.width *= 10; dingWeiRect.height *= 10; - dingWeiRect.y -= 75; dingWeiRect.height += 150; - sourceImage(dingWeiRect & cv::Rect(0, 0, sourceImage.cols, sourceImage.rows)).copyTo(afterDingWei); - cv::resize(afterDingWei, afterDingWei, cv::Size(), 0.5, 0.5); - afterDingWei.copyTo(imgPaint); - } - //检测 - - data->insertSegOriginImg(afterDingWei); - TextRendererZH textPainter(imgPaint.cols, imgPaint.rows, 300); - //if (isNG_1 == true || isNG_2 == true) { - // textPainter.putText(imgPaint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); - // data->halconOK = false; - // plcResult = "2"; - //} - //else { - textPainter.putText(imgPaint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); - //} - if (!data->service->_paramSyncManager->get("底部焊后", "底部焊后判定启用", true).toBool()) - plcResult = "1"; - data->insertResultImg(imgPaint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "NG", cv::Point(1000, 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");//结果反馈 - return true; - - -} - -bool lieHenJianCe45(std::shared_ptr data, LieHenJianCeParams* _detParams, sx_581_address address) { - try - { - cv::Mat sourceImg; - cv::Rect cutROI; - cutROI = cv::Rect(1600, 900, 2200, 1400) & cv::Rect(0, 0, data->getOriImg(0).cols, data->getOriImg(0).rows); - data->getOriImg(0)(cutROI).copyTo(sourceImg); - cv::Mat Paint; - sourceImg.copyTo(Paint); - TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - bool isNG = false; - QByteArray plcResult = "1"; - textPainter.putText(Paint, "OK", cv::Point(0, 50), cv::Scalar(0, 255, 0)); - //cv::rectangle(Paint, cutROI, cv::Scalar(0, 255, 0), 5); - data->insertResultImg(Paint); - - sourceImg.release(); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "NG", cv::Point(1000, 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");//结果反馈 - return true; - -} - - -bool jiXingJianCe(std::shared_ptr data, JiXingJianCeParams* _detParams, sx_581_address address){ - try - { - /*if (indexTest < 17) - img2D = cv::imread("./testImages/" + std::to_string(indexTest++) + ".bmp", -1);*/ - - //存图数据加保存队列,加锁,避免数据访问冲突 - //cv::Rect cutRect(0, 0, img2D.cols, img2D.rows);//裁剪出有效区域 - //cutRect = cutRect & cv::Rect(0, 0, img2D.cols, img2D.rows); - cv::Mat sourceImg; - data->getOriImg(0).copyTo(sourceImg); - - HDevEngineCpp::HDevProcedure proc("_2_JX_Inspection"); - HDevProcedureCall procedureCall(proc); - - cv::Mat Paint; - sourceImg.copyTo(Paint); - //极性检测 - HObject in_Image; - HTuple in_FilePath = "./halconFiles/"; - HTuple in_LineType = "602"; - in_Image = MatToHObject(sourceImg); - procedureCall.SetInputIconicParamObject("in_Image", in_Image);//设置输入图像类变量 - procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); - procedureCall.SetInputCtrlParamTuple("in_LineType", in_LineType); - procedureCall.Execute();//执行halcon程序 - HTuple out_ColorType; - HTuple out_Flag; - HTuple out_InspectionPosition; - HTuple out_NgTails; - out_ColorType = procedureCall.GetOutputCtrlParamTuple("out_ColorType");//获取输出图像类变量 - out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - out_InspectionPosition = procedureCall.GetOutputCtrlParamTuple("out_InspectionPosition"); - out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails"); - //相机2 OK为铜 NG为铝 - QByteArray plcResult = "2"; - TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - if (out_Flag.D() == 1) - { - if (out_InspectionPosition.Length() > 3) { - for (int i = 0; i < out_InspectionPosition.Length() / 4; i++) { - cv::Rect rect = cv::Rect(out_InspectionPosition[i * 4 + 0], \ - out_InspectionPosition[i * 4 + 1], \ - out_InspectionPosition[i * 4 + 2], \ - out_InspectionPosition[i * 4 + 3]); - cv::rectangle(Paint, rect, cv::Scalar(0, 255, 255), 2); - } - } - - std::string jx_Type = out_ColorType.S().Text(); - if (jx_Type == "LV") { - //铝 - cv::putText(Paint, "NG", cv::Point(0, 500), 2, 10, cv::Scalar(0, 0, 255), 5); - data->halconOK = false; - } - else if (jx_Type == "CU") { - //铜 - textPainter.putText(Paint, "铜极", cv::Point(0, 0), cv::Scalar(0, 255, 0)); - cv::putText(Paint, "OK", cv::Point(0, 500), 2, 10, cv::Scalar(0, 255, 0), 5); - plcResult = "1"; - } - else { - textPainter.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); - data->halconOK = false; - } - } - else { - std::string temp_NGTails = out_NgTails.S().Text(); - textPainter.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255)); - textPainter.putText(Paint, temp_NGTails.c_str(), cv::Point(0, 350), cv::Scalar(0, 0, 255)); - data->halconOK = false; - } - if (!data->service->_paramSyncManager->get("极性检测", "极性判定启用", true).toBool()) - plcResult = "1"; - sourceImg.release(); - data->insertResultImg(Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - return true; - } - CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode); - cv::Mat Paint; - data->getOriImg(0).copyTo(Paint); - if (Paint.channels() == 1) - cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "NG", cv::Point(1000, 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 + "_2");//结果反馈 - return true; - - -} - - -mission* createMission() { - return new _581_ZhongHan_silie_jixing(); -} -void destroyMission(mission* _mission) { - delete _mission; -} \ No newline at end of file diff --git a/src/mission/602/ZH/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.h b/src/mission/602/ZH/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.h deleted file mode 100644 index 1c155c5..0000000 --- a/src/mission/602/ZH/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.h +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; -#pragma endregion -class LieHenJianCeParams { -public: - handdleAI::pSegmentation* dingwei = nullptr; - handdleAI::pSegmentation* seg_diBu = nullptr; - handdleAI::pClassification* cls_diBu = nullptr; - bool isTong = false; -}; - -class JiXingJianCeParams { -public: - -}; - -void aiEvaluate(cv::Mat input, handdleAI::pSegmentation* seg, handdleAI::pClassification* cls, cv::Mat& Paint, bool& isNG); -bool lieHenJianCe90(std::shared_ptr data, LieHenJianCeParams* _detParams, sx_581_address address); - -bool lieHenJianCe45(std::shared_ptr data, LieHenJianCeParams* _detParams, sx_581_address address); - -bool jiXingJianCe(std::shared_ptr data, JiXingJianCeParams* _detParams, sx_581_address address); - - - - -class _581_ZhongHan_silie_jixing : public mission { -public: - _581_SX_Single_triggerTemplate< LieHenJianCeParams> liehen_tong_1; - _581_SX_Single_triggerTemplate< LieHenJianCeParams> liehen_tong_2; - _581_SX_Single_triggerTemplate< LieHenJianCeParams> liehen_tong_3; - - _581_SX_Single_triggerTemplate< LieHenJianCeParams> liehen_lv_4; - _581_SX_Single_triggerTemplate< LieHenJianCeParams> liehen_lv_5; - _581_SX_Single_triggerTemplate< LieHenJianCeParams> liehen_lv_6; - - _581_SX_Single_triggerTemplate< JiXingJianCeParams> jixing_cu; - - JiXingJianCeParams tongJiXingParams; - LieHenJianCeParams tong90Params; - LieHenJianCeParams lv90Params; - - LieHenJianCeParams tong45Params; - LieHenJianCeParams lv45Params; - bool initOnce = false; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); - if(initOnce == false){ - tong90Params.dingwei = handdleAI::CreateSegObjS("./handleaiModels/dingwei90_seg.BHD", 16, 0); - - lv90Params.dingwei = handdleAI::CreateSegObjS("./handleaiModels/dingwei90_seg.BHD", 16, 1); - initOnce = true; - } - //tong90Params.seg_diBu = handdleAI::CreateSegObjS("./handleaiModels/seg-zhongHanHanHouDiBu.BHD", 1, 0); - //tong90Params.cls_diBu = handdleAI::CreateClsObjV3("./handleaiModels/cls-zhongHanHanHouDiBu.BHD", 0, 1); - - //lv90Params.seg_diBu = handdleAI::CreateSegObjS("./handleaiModels/seg-zhongHanHanHouDiBu.BHD", 1, 1); - //lv90Params.cls_diBu = handdleAI::CreateClsObjV3("./handleaiModels/cls-zhongHanHanHouDiBu.BHD", 1, 1); - lv90Params.isTong == false; - } - bool initCustom() { -#pragma region 注册触发器回调 - liehen_tong_1.init("Camera1", "裂痕检测-铜-相机1", { { 5280, 1,{5160,5180},"5282","5284",-1} }, 1, &tong90Params, _serviceManager, bridge, lieHenJianCe90, "CCD裂痕检测"); - liehen_tong_2.init("Camera2", "裂痕检测-铜-相机2", { { 5290, 1,{5160,5180},"5292","5294",-1} }, 1, &tong45Params, _serviceManager, bridge, lieHenJianCe45, "CCD裂痕检测"); - liehen_tong_3.init("Camera3", "裂痕检测-铜-相机3", { { 5300, 1,{5160,5180},"5302","5304",-1} }, 1, &tong45Params, _serviceManager, bridge, lieHenJianCe45, "CCD裂痕检测"); - - liehen_lv_4.init("Camera4", "裂痕检测-铝-相机4", { { 5310, 1,{5160,5180},"5312","5314",-1} }, 1, &lv90Params, _serviceManager, bridge, lieHenJianCe90, "CCD裂痕检测"); - liehen_lv_5.init("Camera5", "裂痕检测-铝-相机5", { { 5320, 1,{5160,5180},"5322","5324",-1} }, 1, &lv45Params, _serviceManager, bridge, lieHenJianCe45, "CCD裂痕检测"); - liehen_lv_6.init("Camera6", "裂痕检测-铝-相机6", { { 5330, 1,{5160,5180},"5332","5334",-1} }, 1, &lv45Params, _serviceManager, bridge, lieHenJianCe45, "CCD裂痕检测"); - - jixing_cu.init("Camera7", "极性检测-相机1", { { 5000, 1,{5010},"5002","5004",-1} }, 1, &tongJiXingParams, _serviceManager, bridge, jiXingJianCe, "CCD极性检测"); - -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/602/ZH/581_ZhongHan_silie_jixing/CMakeLists.txt b/src/mission/602/ZH/581_ZhongHan_silie_jixing/CMakeLists.txt deleted file mode 100644 index 76e9200..0000000 --- a/src/mission/602/ZH/581_ZhongHan_silie_jixing/CMakeLists.txt +++ /dev/null @@ -1,77 +0,0 @@ -# 获取获取当前目录名 -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/602/ZH/CMakeLists.txt b/src/mission/602/ZH/CMakeLists.txt deleted file mode 100644 index f9a95fd..0000000 --- a/src/mission/602/ZH/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# 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 ${}) diff --git a/subModule/Hd_CameraModule_3DKeyence/Hd_CameraModule_3DKeyence.cpp b/subModule/Hd_CameraModule_3DKeyence/Hd_CameraModule_3DKeyence.cpp index 01b58e9..081e777 100644 --- a/subModule/Hd_CameraModule_3DKeyence/Hd_CameraModule_3DKeyence.cpp +++ b/subModule/Hd_CameraModule_3DKeyence/Hd_CameraModule_3DKeyence.cpp @@ -50,7 +50,7 @@ void myCallbackFunc(LJX8IF_PROFILE_HEADER* pProfileHeaderArray, WORD* pHeightPro { qDebug() << __FUNCTION__ << " line:" << __LINE__ << " --> Enter callback function"; qDebug() << __FUNCTION__ << " line:" << __LINE__ << "dwProfileDataCount = " << dwProfileDataCount; - qDebug() << __FUNCTION__ << " line:" << __LINE__ << "dwCount = " << dwCount; + qDebug() << __FUNCTION__ << " line:" << __LINE__ << "dwCount = " << dwCount<< dwUser; std::cout << "dwCount->" << dwCount <<" dwProfileDataCount"<< dwProfileDataCount << "dwNotify = " << dwNotify<< std::endl; qDebug() << __FUNCTION__ << " line:" << __LINE__ << "dwNotify = " << dwNotify; //if (dwCount < 1000)return; @@ -89,8 +89,8 @@ void myCallbackFunc(LJX8IF_PROFILE_HEADER* pProfileHeaderArray, WORD* pHeightPro return; } - qDebug() << __FUNCTION__ << " line:" << __LINE__ << "_heightBuf[dwUser]: " << _heightBuf[dwUser]; - qDebug() << __FUNCTION__ << " line:" << __LINE__ << "pHeightProfileArray: " << pHeightProfileArray; + // qDebug() << __FUNCTION__ << " line:" << __LINE__ << "_heightBuf[dwUser]: " << _heightBuf[dwUser]; + //qDebug() << __FUNCTION__ << " line:" << __LINE__ << "pHeightProfileArray: " << pHeightProfileArray; //判断内存是否重叠 if (_heightBuf[dwUser] <= pHeightProfileArray || (unsigned short*)_heightBuf[dwUser] >= (WORD*)pHeightProfileArray + dwProfileDataCount * dwCount * 2) @@ -554,9 +554,8 @@ bool Hd_CameraModule_3DKeyence::run() luminanceMat = cv::Mat(_lastImageSizeHeight[deviceId], xImageSize, CV_16UC1, luminanceImage); else luminanceMat = cv::Mat(yImageSize, xImageSize, CV_16UC1, luminanceImage); - cv::normalize(luminanceMat, luminanceMat, 0, 255, cv::NORM_MINMAX); - cv::convertScaleAbs(luminanceMat, luminanceMat); - + + cv::normalize(luminanceMat, luminanceMat, 0, 255, cv::NORM_MINMAX,CV_8U); luminanceMatS.enqueue(luminanceMat); cv::Mat heightImg; diff --git a/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.cpp b/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.cpp index 833a111..97d833f 100644 --- a/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.cpp +++ b/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.cpp @@ -244,7 +244,9 @@ void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFra { srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0); } - queuepic.push_back(srcImage); + queuepic.enqueue(srcImage); + if (queuepic.size() > 10) + queuepic.dequeue(); pData0 = { 0 }; double time_End = (double)clock(); qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" @@ -303,14 +305,6 @@ Hd_CameraModule_HIK_General::~Hd_CameraModule_HIK_General() //从类中读数据到实例对象 bool Hd_CameraModule_HIK_General::readData(std::vector& mat, QByteArray& data) { - if(data == "getStatus"){ - data = lastError.toUtf8(); - return true; - } - if (data == "clearCache") { - queuepic.clear(); - return true; - } if (queuepic.isEmpty()) { return false; @@ -334,6 +328,14 @@ bool Hd_CameraModule_HIK_General::writeData(std::vector& mat, QByteArra return true; } } + if (data == "getStatus") { + data = lastError.toUtf8(); + return true; + } + if (data == "clearCache") { + queuepic.clear(); + return true; + } return true; } //传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... diff --git a/src/mission/602/581_YiCiZhuYe_canye/CMakeLists.txt b/subModule/Hd_CameraModule_HIK_General_debouncing/CMakeLists.txt similarity index 66% rename from src/mission/602/581_YiCiZhuYe_canye/CMakeLists.txt rename to subModule/Hd_CameraModule_HIK_General_debouncing/CMakeLists.txt index 76e9200..8412669 100644 --- a/src/mission/602/581_YiCiZhuYe_canye/CMakeLists.txt +++ b/subModule/Hd_CameraModule_HIK_General_debouncing/CMakeLists.txt @@ -1,9 +1,9 @@ -# 获取获取当前目录名 +# 获取获取当前目录名 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") +set(DLL_NAMES "mvs" "opencv") foreach(child ${DLL_NAMES}) LIST(APPEND ENV_INCLUDE ${${child}_include}) LIST(APPEND ENV_LIB ${${child}_lib}) @@ -13,10 +13,7 @@ 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} ) @@ -24,7 +21,7 @@ link_directories ( ${ENV_LIB} ) -add_compile_options(/utf-8) + set(CMAKE_INCLUDE_CURRENT_DIR ON) SET(CMAKE_CXX_STANDARD 11) @@ -33,26 +30,25 @@ 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 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) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/interface.h ) -set_target_properties(${CURRENT_FOLDER} PROPERTIES +set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} @@ -62,8 +58,6 @@ set_target_properties(${CURRENT_FOLDER} PROPERTIES target_link_libraries(${CURRENT_FOLDER} PRIVATE ${ENV_TARGET} Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network ) @@ -73,5 +67,4 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) +message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME}) diff --git a/subModule/Hd_CameraModule_HIK_General_debouncing/Hd_CameraModule_HIK_General.cpp b/subModule/Hd_CameraModule_HIK_General_debouncing/Hd_CameraModule_HIK_General.cpp new file mode 100644 index 0000000..fd7e320 --- /dev/null +++ b/subModule/Hd_CameraModule_HIK_General_debouncing/Hd_CameraModule_HIK_General.cpp @@ -0,0 +1,430 @@ +#include "Hd_CameraModule_HIK_General.h" +#include +using namespace std; +#include +#include +#include +#include +#include +QElapsedTimer eTimer; +enum statusEnum { + CONNECTED, + RECONNECTING, + DISCONNECTED +}; +enum triggerModeEnum { + SOFTWARE, + HARDWARE, + EMPTY +}; +std::atomic cameraStatus(DISCONNECTED); +std::atomic reconnecting(false); +std::mutex handleMutex; +triggerModeEnum triggerMode = HARDWARE; +int getImageTimeOut = 3000; +bool runFlag = true; +//总取图数 +int imgIndex = 0; +MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表 +string Username = ""; +int cameraIndex = -1; +QString lastError; +QQueue queuepic; +QMutex* n_mutex = new QMutex(); + +void* handle = NULL; +void CloseDevice(); + +//0106 断线重连 +void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser); +void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0); +//搜索所有设备 +int SearchDevice(){ + + if (m_stDevList.nDeviceNum == 0) { + memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); + // ch:枚举子网内所有设备 | en:Enumerate all devices within subnet + int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList); + if (MV_OK != nRet) + { + return -1; + } + } + for (int i = 0; i < m_stDevList.nDeviceNum; i++) + { + //SN + unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber; + string userName = static_cast((LPCSTR)name); + if (Username == userName) + { + return i; + break; + } + + name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chSerialNumber; + userName = static_cast((LPCSTR)name); + if (Username == userName) + { + return i; + break; + } + } + return -1; +} + +bool connectDevice() +{ + int cameraIndex = SearchDevice(); + if (cameraIndex == -1){ + //未匹配到相机 + qDebug() << "[Waring] " << "Hd_CameraModule_HIK not match --CameraName:" << QString::fromStdString(Username); + lastError = "找不到相机" + QString::fromStdString(Username); + return false; + } + + std::lock_guard lock(handleMutex); + if (handle != NULL) + { + MV_CC_StopGrabbing(handle); + MV_CC_CloseDevice(handle); + MV_CC_DestroyHandle(handle); + handle = NULL; + } + + //打开相机 + MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[cameraIndex]); + int nRet = MV_CC_OpenDevice(handle); + ////触发模式 + if(triggerMode == SOFTWARE) + { + MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); + MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE); + } + else if(triggerMode == HARDWARE) + { + MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); + MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0); + } + + // //加载用户集,相机设置应当UserSet1 + nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1"); + if (MV_OK != nRet)qDebug() << "Set UserSetSelector fail! nRet " << nRet; + // ch:注册抓图回调 | en:Register image callback + MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志 + + nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调 + if (MV_OK != nRet)return false; + nRet = MV_CC_RegisterExceptionCallBack(handle, ReconnectDevice, NULL);//断线重连 + if (MV_OK != nRet)return false; + + MV_CC_StartGrabbing(handle); + cameraStatus.store(CONNECTED); + return true; +} +void SetExposureTime(float exposureValue) +{ + qDebug() << "[INFO] " << "exposureValue:" << exposureValue; + MV_CC_SetEnumValue(handle, "ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF); + MV_CC_SetFloatValue(handle, "ExposureTime", exposureValue); +} + +void SetGain(float GainValue) +{ + qDebug() << "[INFO] " << "GainValue:" << GainValue; + MV_CC_SetEnumValue(handle, "GainAuto", 0); + MV_CC_SetFloatValue(handle, "Gain", GainValue); +} + +//断线重连 +void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser){ + + qDebug() << "[Error] " << " MV camera disconnects!"; + + if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT && cameraStatus.load() == CONNECTED){ + + // 防止重复启动重连线程 + bool expected = false; + if (!reconnecting.compare_exchange_strong(expected, true)) { + qDebug() << "[Warning] Reconnect already in progress, skipping duplicate request"; + return; + } + + cameraStatus.store(RECONNECTING); + // 启动后台线程负责重连,避免在回调线程中长时间阻塞 + std::thread([]() { + qDebug() << QString::fromStdString(Username) << " start reconnect thread"; + + // 确保设备资源关闭 + CloseDevice(); + int times = 0; + while (runFlag) + { + qDebug() << QString::fromStdString(Username) << " reconnect attempt:" << times++; + if (connectDevice()) + { + qWarning() << QString::fromStdString(Username) << " reconnect success!"; + cameraStatus.store(CONNECTED); + reconnecting.store(false); + return; + } + + qDebug() << QString::fromStdString(Username) << " reconnect failed, waiting 1 seconds before retry..."; + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + // 如果runFlag为false,线程退出 + qDebug() << "[Info] reconnect thread stopped (runFlag=false)"; + cameraStatus.store(DISCONNECTED); + reconnecting.store(false); + }).detach(); + } +} + +//回调函数; +//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题 +void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0) +{ + if (eTimer.elapsed() < 500) { + qDebug() << "触法时间间隔过短 当前500ms"; + return; + } + eTimer.start(); + + Q_UNUSED(pUser0) + int frameNum = 0; + double time_Start = (double)clock(); + QMutexLocker locker(n_mutex); + cv::Mat srcImage = cv::Mat(); + //qDebug() << "[info]" << __FUNCTION__ << " line:" << __LINE__ << "--- start"; + if (pFrameInfo0) + { + //获取的是单通道灰度图 + if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8)//获取当前采集到的图像格式 + { + srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0); + } + //获取的是RGB8图 + else if (pFrameInfo0->enPixelType == PixelType_Gvsp_BGR8_Packed) + { + srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); + + //cvtColor(srcImage, srcImage, COLOR_RGB2BGR);//导致异色 + } + else if (IsColor(pFrameInfo0->enPixelType)) //其它格式彩色图 + { + MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined; + enDstPixelType = PixelType_Gvsp_BGR8_Packed; + unsigned char* pConvertData = NULL; + pConvertData = (unsigned char*)malloc(pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3); + if (NULL == pConvertData) + { + printf("malloc pConvertData fail!\n"); + } + else + { + unsigned int nConvertDataSize = 0; + nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3; + + // ch:像素格式转换 | en:Convert pixel format + MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; + + frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number + stConvertParam.nWidth = pFrameInfo0->nWidth; //ch:图像宽 | en:image width + stConvertParam.nHeight = pFrameInfo0->nHeight; //ch:图像高 | en:image height + stConvertParam.pSrcData = pData0; //ch:输入数据缓存 | en:input data buffer + stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; //ch:输入数据大小 | en:input data size + stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; //ch:输入像素格式 | en:input pixel format + stConvertParam.enDstPixelType = enDstPixelType; //ch:输出像素格式 | en:output pixel format + stConvertParam.pDstBuffer = pConvertData; //ch:输出数据缓存 | en:output data buffer + stConvertParam.nDstBufferSize = nConvertDataSize; //ch:输出缓存大小 | en:output buffer size + int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam); + + Mat mysrcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer); + mysrcImage.copyTo(srcImage); + + free(pConvertData); + pConvertData = NULL; + stConvertParam = { 0 }; + } + } + } + if (srcImage.empty()) + { + srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0); + } + queuepic.enqueue(srcImage); + if (queuepic.size() > 10) + queuepic.dequeue(); + pData0 = { 0 }; + double time_End = (double)clock(); + qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" + << "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgIndex << "nFrameNum : " << frameNum; +} + +//关闭设备 +void CloseDevice() +{ + std::lock_guard lock(handleMutex); + + // 如果 handle 已经为空,直接返回 + if (handle == nullptr) + return; + + // 使用 SDK 正确的停止/关闭/销毁流程,避免使用 CloseHandle 等不匹配的 API + int nRet = MV_CC_StopGrabbing(handle); + if (MV_OK != nRet) { + qDebug() << "[Warning] MV_CC_StopGrabbing failed, nRet=" << nRet; + } + + nRet = MV_CC_CloseDevice(handle); + if (MV_OK != nRet) { + qDebug() << "[Warning] MV_CC_CloseDevice failed, nRet=" << nRet; + } + + nRet = MV_CC_DestroyHandle(handle); + if (MV_OK != nRet) { + qDebug() << "[Warning] MV_CC_DestroyHandle failed, nRet=" << nRet; + } + + handle = nullptr; +} + +Hd_CameraModule_HIK_General::~Hd_CameraModule_HIK_General() +{ + runFlag = false; + + // 等待重连线程结束 + int waitCount = 0; + while (reconnecting.load() && waitCount < 50) { // 最多等待5秒 + qDebug() << "[Info] Waiting for reconnect thread to finish..."; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + waitCount++; + } + + CloseDevice(); + if (n_mutex) + { + delete n_mutex; + n_mutex = nullptr; + } + + qDebug() << "[INFO] " << " delete success!"; +} +//从类中读数据到实例对象 +bool Hd_CameraModule_HIK_General::readData(std::vector& mat, QByteArray& data) +{ + if (queuepic.isEmpty()) + { + return false; + } + QMutexLocker locker(n_mutex); + cv::Mat img = queuepic.dequeue(); + mat.push_back(img); + + qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex; + return true; +} + +//实例对象把数据写入到类;加载模型后会运行此函数 +bool Hd_CameraModule_HIK_General::writeData(std::vector& mat, QByteArray& data) +{ + Q_UNUSED(mat); + if (data.contains("deviceList")) { + auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10)); + if (result.nDeviceNum != 0) { + m_stDevList = result; + return true; + } + } + if (data == "getStatus") { + data = lastError.toUtf8(); + return true; + } + if (data == "clearCache") { + queuepic.clear(); + return true; + } + return true; +} +//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... +bool Hd_CameraModule_HIK_General::initParas(QByteArray& initData) +{ + QByteArrayList valueList = initData.split('#'); + if (valueList.size() < 3) { + qDebug() << "[Error] " << " Hd_CameraModule_HIK initParas fail--params error!参数数量不满足"; + lastError = "参数数量不满足"; + return false; + } + Username = valueList[0]; + + auto triggerModeStr = valueList[1]; + if (triggerModeStr == "HARDWARE") + triggerMode = HARDWARE; + else if (triggerModeStr == "SOFTWARE") + triggerMode = SOFTWARE; + else if (triggerModeStr == "EMPTY") + triggerMode = EMPTY; + else { + qDebug() << "[Error] " << " Hd_CameraModule_HIK initParas fail--params error!触发模式参数错误"; + lastError = "触发模式参数错误"; + return false; + } + + getImageTimeOut = valueList[2].toInt(); + + imgIndex = 0; + return connectDevice(); +} + +bool Hd_CameraModule_HIK_General::run() +{ + qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username); + if (triggerMode == SOFTWARE) + MV_CC_SetCommandValue(handle, "TriggerSoftware"); + try + { + int sleepMs = 10; + int cnt = 0; + int timeoutCnt = getImageTimeOut / sleepMs; + while (true) + { + QMutexLocker locker(n_mutex); + if (queuepic.size() > 0)return true; + if (cnt++ > timeoutCnt) { + queuepic.push_back(cv::Mat(200, 200, CV_8UC1, cv::Scalar(0))); //返回空图 + qDebug() << QString::fromStdString(Username) << "timeout" ; + return true; + } + QThread::msleep(sleepMs); + } + } + catch (QString ev) + { + qDebug() << "[Error] " << " ev:" << ev; + } + return true; +} + +//相机连接状态:正常连接或断开 +bool Hd_CameraModule_HIK_General::checkStatus() +{ + //status = moduleStatus; + return status; +} + + +Hd_CameraModule_HIK_General* create() +{ + qDebug() << "[INFO] " << "Hd_CameraModule_HIK create success!"; + return new Hd_CameraModule_HIK_General; +} + +void destory(Hd_CameraModule_HIK_General* ptr) +{ + if (ptr) + { + delete ptr; + ptr = nullptr; + } + qDebug() << "[INFO] " << "Hd_CameraModule_HIK destory success!"; +} \ No newline at end of file diff --git a/subModule/Hd_CameraModule_HIK_General_debouncing/Hd_CameraModule_HIK_General.h b/subModule/Hd_CameraModule_HIK_General_debouncing/Hd_CameraModule_HIK_General.h new file mode 100644 index 0000000..2483799 --- /dev/null +++ b/subModule/Hd_CameraModule_HIK_General_debouncing/Hd_CameraModule_HIK_General.h @@ -0,0 +1,84 @@ +#ifndef Hd_CameraModule_HIK_General_H +#define Hd_CameraModule_HIK_General_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace cv; +#pragma execution_character_set("utf-8") + +static MV_CC_DEVICE_INFO_LIST QByteArrayToMV_CC_DeviceInfoList(const QByteArray& byteArray) { + MV_CC_DEVICE_INFO_LIST deviceInfoList; + if (byteArray.size() == sizeof(MV_CC_DEVICE_INFO_LIST)) { + memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_CC_DEVICE_INFO_LIST)); + } + else { + qDebug() << "Invalid size of QByteArray for MV_CC_DEVICE_INFO_LIST!"; + } + return deviceInfoList; +} +bool IsColor(MvGvspPixelType enType) +{ + switch (enType) + { + case PixelType_Gvsp_RGB8_Packed: + case PixelType_Gvsp_YUV422_Packed: + case PixelType_Gvsp_YUV422_YUYV_Packed: + case PixelType_Gvsp_BayerGR8: + case PixelType_Gvsp_BayerRG8: + case PixelType_Gvsp_BayerGB8: + case PixelType_Gvsp_BayerBG8: + case PixelType_Gvsp_BayerGB10: + case PixelType_Gvsp_BayerGB10_Packed: + case PixelType_Gvsp_BayerBG10: + case PixelType_Gvsp_BayerBG10_Packed: + case PixelType_Gvsp_BayerRG10: + case PixelType_Gvsp_BayerRG10_Packed: + case PixelType_Gvsp_BayerGR10: + case PixelType_Gvsp_BayerGR10_Packed: + case PixelType_Gvsp_BayerGB12: + case PixelType_Gvsp_BayerGB12_Packed: + case PixelType_Gvsp_BayerBG12: + case PixelType_Gvsp_BayerBG12_Packed: + case PixelType_Gvsp_BayerRG12: + case PixelType_Gvsp_BayerRG12_Packed: + case PixelType_Gvsp_BayerGR12: + case PixelType_Gvsp_BayerGR12_Packed: + return true; + default: + return false; + } +} +class Hd_CameraModule_HIK_General :public dsModuleBase +{ +public: + Hd_CameraModule_HIK_General() {}; + virtual ~Hd_CameraModule_HIK_General(); + //从类中读数据到实例对象 + bool readData(std::vector& mat, QByteArray& data); + //实例对象把数据写入到类 + bool writeData(std::vector& mat, QByteArray& data); + bool initParas(QByteArray& initData); + bool run(); + bool checkStatus(); +private: + + //MyThread *m_thread = nullptr; + //QMutex* m_mutex; +}; + +extern "C" +{ +Q_DECL_EXPORT Hd_CameraModule_HIK_General * create(); +Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_General * ptr); +} + +#endif // Hd_CameraModule_HIK_hard_H +//Hd_CameraModule_HIK_General diff --git a/subModule/Hd_CameraModule_HIK_General_debouncing/readme.txt b/subModule/Hd_CameraModule_HIK_General_debouncing/readme.txt new file mode 100644 index 0000000..ccb05c9 --- /dev/null +++ b/subModule/Hd_CameraModule_HIK_General_debouncing/readme.txt @@ -0,0 +1,3 @@ +֧³ÖUSBÉ豸ºÍÍø¿ÚÉ豸£¬²»֧³ֲɼ¯¿¨É豸 +³õʼ»¯¸ñʽ "Ïà»úÐòÁкÅ#HARDWARE/SOFTWARE/EMPTY#ȡͼ³¬ʱʱ¼ä" +SAMPLE: Vir76210850#SOFTWARE#2000 \ No newline at end of file