From 1b7451ba07f882b5fe55bfd2ab7c5d19cf3313d3 Mon Sep 17 00:00:00 2001 From: RCi <15089880081@163.com> Date: Tue, 14 Oct 2025 01:27:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=92=E9=9A=9C=E5=A2=9E=E5=8A=A0=E5=85=A8?= =?UTF-8?q?=E9=83=A8=E8=A7=A6=E5=8F=91=E4=BB=A5=E5=8F=8A=E5=85=A8=E9=83=A8?= =?UTF-8?q?=E6=B8=85=E9=9B=B6=E6=8C=89=E9=92=AE=E3=80=82=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=89=E5=8D=8F=E5=A4=B4=E6=96=87=E4=BB=B6=E4=BC=A0?= =?UTF-8?q?=E5=8F=82=E7=B1=BB=E5=9E=8B=E3=80=82=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=AD=98=E5=9B=BE=E6=89=93=E5=8D=B0=E6=97=A5=E5=BF=97=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/sxGlobal.h | 10 +- src/Core/back/imgSaveThreadManager.h | 200 ++++++----- src/Core/back/triggerManager.cpp | 2 +- src/core/back/CLIManager.h | 72 +++- .../581_YuHan_hanhou/581_YuHan_hanhou.cpp | 5 +- .../581_YuHan_hanhou/581_YuHan_hanhou.h | 73 ++--- .../581_YuHan_hanqian/581_YuHan_hanqian.h | 16 +- .../581_ZhongHan_hanhou.cpp | 8 + .../581_ZhongHan_hanhou/581_ZhongHan_hanhou.h | 189 +++++++++++ .../581_ZhongHan_hanhou/CMakeLists.txt | 78 +++++ .../581_ZhongHan_hanqian.cpp | 8 + .../581_ZhongHan_hanqian.h | 310 ++++++++++++++++++ .../581_ZhongHan_hanqian/CMakeLists.txt | 78 +++++ .../Hd_VirtualCamera/Hd_VirtualCamera.cpp | 2 +- 14 files changed, 896 insertions(+), 155 deletions(-) create mode 100644 src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp create mode 100644 src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h create mode 100644 src/mission/581_ZhongHan_hanhou/CMakeLists.txt create mode 100644 src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp create mode 100644 src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h create mode 100644 src/mission/581_ZhongHan_hanqian/CMakeLists.txt diff --git a/include/sxGlobal.h b/include/sxGlobal.h index 5a3c7d4..d57c51c 100644 --- a/include/sxGlobal.h +++ b/include/sxGlobal.h @@ -25,7 +25,7 @@ struct sx_581_address { int triggerAddr = -1; int triggerValue = -1; - int snAddr = -1; + int snAddr; QByteArray completeAddr = "-1"; QByteArray resultAddr = "-1"; int valueOffsetAddr = -1; @@ -83,7 +83,7 @@ template //例触发地址有4个,输入信号为 1 0 0 1 则按顺序触发1和4的地址拍照检测,2和3不做处理 class _581_SX_Single_triggerTemplate { public: - paramTemplte _detParams; + paramTemplte* _detParams; detCallbackChain* generalDet; std::string cameraName; QString viewerName; @@ -102,7 +102,7 @@ public: /// 算法函数 /// void init(std::string cameraNameIn, QString viewerNameIN, std::vector addressIN, int oneTriggerCaptrueTimes, - paramTemplte& detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn, + paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn, typename detCallbackChain::processAlgoCallback _processAlgoCallback, QString saveObjectNameIN = "") { viewerName = viewerNameIN; @@ -112,12 +112,12 @@ public: bridge = bridgeIn; address = addressIN; saveObjectName = saveObjectNameIN; - generalDet = new detCallbackChain(_serviceManager, &_detParams, bridge); + generalDet = new detCallbackChain(_serviceManager, _detParams, bridge); generalDet->registerProcessAlgoCallback(_processAlgoCallback); //单次触发器条件 for (int i = 0; i < addressIN.size(); i++) { //注册单触发器 触发地址置1时触发 - _serviceManager->_triggerManager->registerCallback(address[i].triggerAddr, 1, [this, i](int triggerPos, int triggerValue, QByteArray& byteArray) { + _serviceManager->_triggerManager->registerCallback(address[i].triggerAddr, address[i].triggerValue, [this, i](int triggerPos, int triggerValue, QByteArray& byteArray) { evaluate(i, byteArray);}, ""); } diff --git a/src/Core/back/imgSaveThreadManager.h b/src/Core/back/imgSaveThreadManager.h index 47d08ef..a882cff 100644 --- a/src/Core/back/imgSaveThreadManager.h +++ b/src/Core/back/imgSaveThreadManager.h @@ -5,109 +5,99 @@ #include #include -enum imgSaveThreadType -{ +enum imgSaveThreadType { oriImg, resImg, segImg, clsImg, tiffOriImg }; -class imgSaveThread : public QThread -{ +struct saveJob { + saveJob(std::string jobNameIn) :jobName(jobNameIn) {} + std::string jobName; + QQueue> imgQueue; +}; +class imgSaveThread : public QThread { + public: - enum type{ + enum type { normal, priority }; QMutex mutex; - std::vector compressionParams{ cv::IMWRITE_PNG_COMPRESSION ,9}; - QQueue>priorityQueue; - QQueue>imgQueue; - void run() - { - while (true) - { - QQueue> localQueue; + std::vector compressionParams{ cv::IMWRITE_PNG_COMPRESSION ,9 }; + QQueue< std::shared_ptr>priorityQueue; + QQueue< std::shared_ptr>defaultQueue; + int imgRemainCount = 0; + void run() { + while (true) { + QQueue> localQueue; + std::shared_ptr job = nullptr; // 优先处理 priorityQueue { QMutexLocker locker(&mutex); if (!priorityQueue.isEmpty()) { - localQueue.swap(priorityQueue); + job = priorityQueue.dequeue(); } - else if (!imgQueue.isEmpty()) { - localQueue.swap(imgQueue); + else if (!defaultQueue.isEmpty()) { + job = defaultQueue.dequeue(); } } // 没有任务就跳出 - if (localQueue.isEmpty()) { + if (job == nullptr) { break; } + qDebug() << "saveJob start" << QString::fromStdString(job->jobName) << "remain" << imgRemainCount; + localQueue.swap(job->imgQueue); + imgRemainCount -= job->imgQueue.size(); // 批量保存 while (!localQueue.isEmpty()) { auto data = std::move(localQueue.dequeue()); - qDebug() << "saving img " << QString::fromStdString(data.first); #if saveImgEnable cv::imwrite(data.first, data.second); #endif - } + + qDebug() << "saveJob end " << QString::fromStdString(job->jobName); } } - void addData(std::string str, cv::Mat& mat,type type_ = normal) - { - try - { - if (mat.data == nullptr || &mat == nullptr) - { - qDebug() << "在存图线程中发现无效图像"; - return; - } - } - catch(...) - { - qDebug() << "在存图线程中发现无效图像"; - return; - } - mutex.lock(); - cv::Mat img; - mat.copyTo(img); + void addJob(std::shared_ptr job, type type_ = normal) { + + QMutexLocker locker(&mutex); switch (type_) { case normal: - imgQueue.append(std::make_pair(str, img)); + defaultQueue.append(job); break; case priority: - priorityQueue.append(std::make_pair(str, img)); + priorityQueue.append(job); break; } - qDebug() << "img enqueue" << QString::fromStdString(str)<<"current size"<< priorityQueue.size()<<","<< imgQueue.size(); - mutex.unlock(); + imgRemainCount += job->imgQueue.size(); + qDebug() << "savejob enqueue" << QString::fromStdString(job->jobName) << "queue size" << priorityQueue.size() << "|" << defaultQueue.size() << " imgRemain" << imgRemainCount; this->start(); } - int queueSize() - { - mutex.lock(); - int size = imgQueue.size(); - mutex.unlock(); + + int queueSize() { + QMutexLocker locker(&mutex); + int size = defaultQueue.size(); return size; } }; -class imgSaveThreadManager -{ +class imgSaveThreadManager { public: imgSaveThreadManager(std::string pathIn) { path = QString::fromStdString(pathIn); } ~imgSaveThreadManager() {}; - void setPath(QString pathIn){ + void setPath(QString pathIn) { path = pathIn; } imgSaveThread saveThread; - QString genDirName(std::shared_ptr data, imgSaveThreadType type, saveMode mode){ + QString genDirName(std::shared_ptr data, imgSaveThreadType type, saveMode mode) { // 一级目录(根路径) const QString basePath = path; @@ -137,18 +127,18 @@ public: // 拼接路径 QDir dir(basePath); dir = QDir(dir.filePath(imgTypeDir)); - if (data->saveObjectName != "") + if (data->saveObjectName != "") dir = QDir(dir.filePath(data->saveObjectName)); dir = QDir(dir.filePath(dateDir)); dir = QDir(dir.filePath(hourDir)); dir = QDir(dir.filePath(resultDir)); - if (mode != oneFile) + if (mode != oneFile) dir = QDir(dir.filePath(detailName)); return dir.path() + "/"; } - std::vector genFileNames(std::shared_ptr data, imgSaveThreadType type, std::string format = "") - { + std::vector genFileNames(std::shared_ptr data, imgSaveThreadType type, std::string format = "") { + std::vector resultFileNames; std::string fileName; if (data->SNcode.length() != 0 && data->SNcode.length() < 50) @@ -162,7 +152,7 @@ public: case oriImg: for (int i = 0; i < data->oriImgs.size(); i++) { - if (i < data->oriFormat.size() ) + if (i < data->oriFormat.size()) resultFileNames.push_back(fileName + getCurrentDateTime() + "_Count" + std::to_string(i) + "." + data->oriFormat[i]); else resultFileNames.push_back(fileName + getCurrentDateTime() + "_Count" + std::to_string(i) + ".bmp"); @@ -183,36 +173,84 @@ public: } return resultFileNames; } + void packageData(QQueue>& jobQueue, std::vector fileNames, std::vector& mats) { + if (fileNames.size() != mats.size()) + qWarning() << "检测到存图文件名数量与图片数量不符"; - void saveOri(std::shared_ptr data) { - QString fileSavePath = genDirName(data, oriImg, data->_saveMode);//获取文件夹名 - createDirectoryIfNotExists(fileSavePath);//不存在此文件夹则创建 - std::vectorfileNames = genFileNames(data, oriImg); + for (int index = 0; index < fileNames.size() && index < mats.size(); index++) { + try { - for (int index = 0; index < fileNames.size(); index++) - saveThread.addData(fileSavePath.toLocal8Bit().toStdString() + fileNames[index], data->oriImgs[index]); - int queueSize = saveThread.queueSize(); - if (queueSize > 10) - qDebug() << "queueSize " << queueSize; + if (mats[index].data == nullptr || &mats[index] == nullptr) { + qDebug() << "在存图线程中发现无效图像"; + continue; + } + } + catch (...) { + qDebug() << "在存图线程中发现无效图像"; + continue; + } + + cv::Mat img; + mats[index].copyTo(img); + jobQueue.enqueue(std::make_pair(fileNames[index], img)); + } } - void saveRes(std::shared_ptr data){ - QString fileSavePath = genDirName(data, resImg,data->_saveMode);//获取文件夹名 + void packageData(QQueue>& jobQueue, std::vector fileNames, std::vector>& mats) { + if (fileNames.size() != mats.size()) + qWarning() << "检测到存图文件名数量与图片数量不符"; + + for (int index = 0; index < fileNames.size() && index < mats.size(); index++) { + try { + + if (mats[index].second.data == nullptr || &mats[index].second == nullptr) { + qDebug() << "在存图线程中发现无效图像"; + continue; + } + } + catch (...) { + qDebug() << "在存图线程中发现无效图像"; + continue; + } + + cv::Mat img; + mats[index].second.copyTo(img); + jobQueue.enqueue(std::make_pair(fileNames[index], img)); + } + + } + void saveOri(std::shared_ptr data) { + + if (data->oriImgs.size() != 0) { + + QString fileSavePath = genDirName(data, oriImg, data->_saveMode);//获取文件夹名 + createDirectoryIfNotExists(fileSavePath);//不存在此文件夹则创建 + std::vectorfileNames = genFileNames(data, oriImg);//按规则为文件创建命名 + std::shared_ptr job (new saveJob("[ORI_JOB]+ data->SNcode")); + packageData(job->imgQueue, fileNames, data->oriImgs);//打包数据 + saveThread.addJob(job); + } + } + void saveRes(std::shared_ptr data) { + + QString fileSavePath = genDirName(data, resImg, data->_saveMode);//获取文件夹名 createDirectoryIfNotExists(fileSavePath);//不存在此文件夹则创建 + std::shared_ptr job(new saveJob("[RES_JOB]"+ data->SNcode)); //结果图保存 - std::vectorresFileNames = genFileNames(data, resImg); - for (int index = 0; index < resFileNames.size(); index++) - saveThread.addData(fileSavePath.toLocal8Bit().toStdString() + resFileNames[index], data->resultImgs[index], imgSaveThread::priority); - - //seg - std::vectorsegFileNames = genFileNames(data, segImg); - for (int index = 0; index < segFileNames.size(); index++) - saveThread.addData(fileSavePath.toLocal8Bit().toStdString() + segFileNames[index], data->segOriginImgs[index]); - - //cls - std::vectorclsFileNames = genFileNames(data, clsImg); - for (int index = 0; index < clsFileNames.size(); index++) - saveThread.addData(fileSavePath.toLocal8Bit().toStdString() + clsFileNames[index], data->clsOriginImgs[index].second); - + if (data->resultImgs.size() != 0) { + std::vectorfileNames = genFileNames(data, resImg);//按规则为文件创建命名 + packageData(job->imgQueue, fileNames, data->resultImgs);//打包数据 + } + //SEG原图 + if (data->segOriginImgs.size() != 0) { + std::vectorfileNames = genFileNames(data, segImg);//按规则为文件创建命名 + packageData(job->imgQueue, fileNames, data->segOriginImgs);//打包数据 + } + //CLS原图 + if (data->clsOriginImgs.size() != 0) { + std::vectorfileNames = genFileNames(data, clsImg);//按规则为文件创建命名 + packageData(job->imgQueue, fileNames, data->clsOriginImgs);//打包数据 + } + saveThread.addJob(job, imgSaveThread::priority); //额外储存NG文件夹 //std::string additionalSaveNgImgPath = genDirName(data, additionalSaveNgImg); //std::vectoradditionalSaveNgImgNames = genFileNames(data, additionalSaveNgImg); @@ -237,7 +275,7 @@ public: } private: QString path = ""; - + }; #pragma once \ No newline at end of file diff --git a/src/Core/back/triggerManager.cpp b/src/Core/back/triggerManager.cpp index 28ac239..f117204 100644 --- a/src/Core/back/triggerManager.cpp +++ b/src/Core/back/triggerManager.cpp @@ -79,7 +79,7 @@ bool triggerManager::connectHost(){ initFailure = trigger->initParas(QByteArray()); #endif - emit bridge->loadingWindow_appendInitLog(triggerFileName + "连接到" + IpAndPort,QColor("white")); + emit bridge->loadingWindow_appendInitLog(triggerFileName + "连接到" + IpAndPort,"white"); } diff --git a/src/core/back/CLIManager.h b/src/core/back/CLIManager.h index 8e8254d..e2db966 100644 --- a/src/core/back/CLIManager.h +++ b/src/core/back/CLIManager.h @@ -54,22 +54,24 @@ public: } void initBasicPreset(mission* _missionIn) { + //初始化单触发测试按钮 for (auto& data : _serviceManager->_triggerManager->triggerCallbackFuncs) { for (auto& callbacks : data.second) { if (callbacks.funcName.find(avoid) != std::string::npos) { continue; } QString uuid = QUuid::createUuid().toString();; - auto commands = basicTriggerPresetGenerate(callbacks.triggerAddress); + auto commands = basicTriggerPresetGenerate(callbacks.triggerAddress, callbacks.triggerValue); QString tips; for(auto& cmd : commands) { tips += cmd + "\n"; } emit bridge->runCommand_addBtn( - QString::fromStdString(callbacks.funcName),tips,uuid); + QString::fromStdString(callbacks.funcName + "_" + std::to_string(callbacks.triggerAddress) + "_" + std::to_string(callbacks.triggerValue)), tips, uuid); presets[uuid] = commands; } } + //初始化联合触发测试按钮 for (auto& data : _serviceManager->_triggerManager->unionTriggerCallbackFuncs) { for (auto& callbacks : data.second) { if (callbacks.funcName.find(avoid) != std::string::npos) { @@ -86,19 +88,65 @@ public: presets[uuid] = commands; } } - - QString uuid = QUuid::createUuid().toString();; - QStringList commands = { "reloadConfig" }; - QString tips = "reloadConfig"; - emit bridge->runCommand_addBtn( - QString::fromStdString("重新加载算法文件"), tips, uuid); - presets[uuid] = commands; - _mission = _missionIn; + //初始化重新加载配置文件按钮 + { + QString uuid = QUuid::createUuid().toString();; + QStringList commands = { "reloadConfig" }; + QString tips = "reloadConfig"; + emit bridge->runCommand_addBtn( + QString::fromStdString("重新加载算法文件"), tips, uuid); + presets[uuid] = commands; + _mission = _missionIn; + } + //初始化全触发按钮 + { + QStringList commands; + QString tips; + QStringList setZeroCommands; + QString setZeroTips; + for (auto& data : _serviceManager->_triggerManager->triggerCallbackFuncs) { + for (auto& callbacks : data.second) { + if (callbacks.funcName.find(avoid) != std::string::npos) { + continue; + } + commands.append("fins#write_short_D" + QString::number(callbacks.triggerAddress) + "_" + QString::number(callbacks.triggerValue)); + tips += "fins#write_short_D" + QString::number(callbacks.triggerAddress) + "_" + QString::number(callbacks.triggerValue) + "\n"; + setZeroCommands.append("fins#write_short_D" + QString::number(callbacks.triggerAddress) + "_0"); + setZeroTips += "fins#write_short_D" + QString::number(callbacks.triggerAddress) + "_0" + "\n"; + } + } + for (auto& data : _serviceManager->_triggerManager->unionTriggerCallbackFuncs) { + for (auto& unionCallbacks : data.second) { + if (unionCallbacks.funcName.find(avoid) != std::string::npos) { + continue; + } + for (auto& callbacks : unionCallbacks.triggerAddressAndValue) { + commands.append("fins#write_short_D" + QString::number(callbacks.first) + "_" + QString::number(callbacks.second)); + tips += "fins#write_short_D" + QString::number(callbacks.second) + "_" + QString::number(callbacks.second) + "\n"; + setZeroCommands.append("fins#write_short_D" + QString::number(callbacks.first) + "_0"); + setZeroTips += "fins#write_short_D" + QString::number(callbacks.first) + "_0" + "\n"; + } + } + } + QString allTriggerUuid = QUuid::createUuid().toString(); + commands.append("waitMs#500"); + commands.append(setZeroCommands); + presets[allTriggerUuid] = commands; + tips.append("waitMs#500\n"); + tips.append(setZeroTips); + emit bridge->runCommand_addBtn("全部触发", tips, allTriggerUuid); + + QString allClearUuid = QUuid::createUuid().toString(); + emit bridge->runCommand_addBtn("全部清零", setZeroTips, allClearUuid); + presets[allClearUuid] = setZeroCommands; + } + } - QStringList basicTriggerPresetGenerate(int& triggerAddress) { + QStringList basicTriggerPresetGenerate(int& triggerAddress,int triggerValue) { QString triggerAddressStr = QString::number(triggerAddress); + QString triggerValueStr = QString::number(triggerValue); return { - "fins#write_short_D"+ triggerAddressStr +"_1", + "fins#write_short_D"+ triggerAddressStr +"_" + triggerValueStr, "waitMs#500", "fins#write_short_D" + triggerAddressStr + "_0", }; diff --git a/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp b/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp index 8b7200a..181ab1c 100644 --- a/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp +++ b/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp @@ -292,11 +292,8 @@ bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, s } - - - mission* createMission() { - return new _581_YuHan_hanqian(); + return new _581_YuHan_hanhou(); } void destroyMission(mission* _mission) { delete _mission; diff --git a/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.h b/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.h index 534b313..3b54e5d 100644 --- a/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.h +++ b/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.h @@ -30,7 +30,7 @@ bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, s namespace hanhou45{ } -class _581_YuHan_hanqian : public mission { +class _581_YuHan_hanhou : public mission { public: _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_top90_1; _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_down90_2; @@ -41,39 +41,26 @@ public: _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> tongDetParams = std::vector < yuHanHanHouParams>(4); + std::vector < yuHanHanHouParams> lvDetParams = std::vector < yuHanHanHouParams>(4); bool initOnce = false; void onConfigReloaded() { HDevEngineCpp::HDevEngine myEngine; myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl"); - /*tongDetParams.segHanYinZhuaQu = _serviceManager->_handleAiModelManager->getSegModel("segTongHanYinZhuaQu_GPU1"); - tongDetParams.segYuHanDingWei = _serviceManager->_handleAiModelManager->getSegModel("segTongYuHanDingWei_GPU1"); - tongDetParams.segHanHou = _serviceManager->_handleAiModelManager->getSegModel("segTongHanHou_GPU1"); - tongDetParams.clsHanHou = _serviceManager->_handleAiModelManager->getClsModel("clsTongHanHou_GPU1"); - - - lvDetParams.segHanYinZhuaQu = _serviceManager->_handleAiModelManager->getSegModel("segLvHanYinZhuaQu_GPU0"); - lvDetParams.segYuHanDingWei = _serviceManager->_handleAiModelManager->getSegModel("segLvYuHanDingWei_GPU0"); - lvDetParams.segHanHou = _serviceManager->_handleAiModelManager->getSegModel("segLvHanHou_GPU0"); - lvDetParams.clsHanHou = _serviceManager->_handleAiModelManager->getClsModel("clsLvHanHou_GPU0");*/ if (initOnce == false) { - for (int i = 0; i < 4; i++) { - yuHanHanHouParams tong; - tong.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-T.BHD", 64, 0); - tong.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanDingWei-T.BHD", 64, 0); - tong.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-T.BHD", 64, 0); - tong.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-T.BHD", 0, 1); - tongDetParams.push_back(tong); + for (auto& params : tongDetParams) { + params.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-T.BHD", 64, 0); + params.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanDingWei-T.BHD", 64, 0); + params.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-T.BHD", 64, 0); + params.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-T.BHD", 0, 1); + } - yuHanHanHouParams lv; - lv.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-L.BHD", 64, 1); - lv.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanDingWei-L.BHD", 64, 1); - lv.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-L.BHD", 64, 1); - lv.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-L.BHD", 1, 1); - lv.isTong = false; - lvDetParams.push_back(lv); + for (auto& params : lvDetParams) { + params.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-L.BHD", 64, 1); + params.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanDingWei-L.BHD", 64, 1); + params.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-L.BHD", 64, 1); + params.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-L.BHD", 1, 1); } initOnce = true; } @@ -81,26 +68,26 @@ public: bool initCustom() { #pragma region 注册触发器回调 if (_configMap["hanhou"] == "OUT") { - lv_top90_1.init("Camera1", "极耳尺寸-外-铝-相机1(顶部90°)", { { 522, 1,540,"523","530",820} }, 1, lvDetParams[0], _serviceManager, bridge, hanHouCeLiang); - lv_down90_2.init("Camera2", "极耳尺寸-外-铝-相机2(底部90°)", { { 524, 1,540,"525","532",-1} }, 1, lvDetParams[1], _serviceManager, bridge, hanHouDown); - tong_top90_3.init("Camera3", "极耳尺寸-外-铜-相机3(顶部90°)", { { 526,1,540,"527","534",800} }, 1, tongDetParams[0], _serviceManager, bridge, hanHouCeLiang); - tong_down90_4.init("Camera4", "极耳尺寸-外-铜-相机4(底部90°)", { { 528, 1,540,"529","536",-1} }, 1, tongDetParams[1], _serviceManager, bridge, hanHouDown); + lv_top90_1.init("Camera1", "极耳尺寸-外-铝-相机1(顶部90°)", { { 522, 1,540,"523","530",820} }, 1, &lvDetParams[0], _serviceManager, bridge, hanHouCeLiang); + lv_down90_2.init("Camera2", "极耳尺寸-外-铝-相机2(底部90°)", { { 524, 1,540,"525","532",-1} }, 1, &lvDetParams[1], _serviceManager, bridge, hanHouDown); + tong_top90_3.init("Camera3", "极耳尺寸-外-铜-相机3(顶部90°)", { { 526,1,540,"527","534",800} }, 1, &tongDetParams[0], _serviceManager, bridge, hanHouCeLiang); + tong_down90_4.init("Camera4", "极耳尺寸-外-铜-相机4(底部90°)", { { 528, 1,540,"529","536",-1} }, 1, &tongDetParams[1], _serviceManager, bridge, hanHouDown); - lv_top45_5.init("Camera5", "底部撕裂-外-铝-相机5(顶部45°)", { { 562,1,540,"563","570",-1} }, 1, lvDetParams[2], _serviceManager, bridge, hanHouDown); - lv_down45_6.init("Camera6", "底部撕裂-外-铝-相机6(底部45°)", { { 564, 1,540,"565","572",-1} }, 1, lvDetParams[3], _serviceManager, bridge, hanHouDown); - tong_top45_7.init("Camera7", "底部撕裂-外-铜-相机7(顶部45°)", { { 566, 1,540,"567","574",-1} }, 1, tongDetParams[2], _serviceManager, bridge, hanHouDown); - tong_down45_8.init("Camera8", "底部撕裂-外-铜-相机8(底部45°)", { { 568, 1,540,"569","576",-1} }, 1, tongDetParams[3], _serviceManager, bridge, hanHouDown); + lv_top45_5.init("Camera5", "底部撕裂-外-铝-相机5(顶部45°)", { { 562,1,540,"563","570",-1} }, 1, &lvDetParams[2], _serviceManager, bridge, hanHouDown); + lv_down45_6.init("Camera6", "底部撕裂-外-铝-相机6(底部45°)", { { 564, 1,540,"565","572",-1} }, 1, &lvDetParams[3], _serviceManager, bridge, hanHouDown); + tong_top45_7.init("Camera7", "底部撕裂-外-铜-相机7(顶部45°)", { { 566, 1,540,"567","574",-1} }, 1, &tongDetParams[2], _serviceManager, bridge, hanHouDown); + tong_down45_8.init("Camera8", "底部撕裂-外-铜-相机8(底部45°)", { { 568, 1,540,"569","576",-1} }, 1, &tongDetParams[3], _serviceManager, bridge, hanHouDown); } else { - lv_top90_1.init("Camera1", "极耳尺寸-内-铝-相机1(顶部90°)", { { 602, 1,580,"603","610",860} }, 1, lvDetParams[0], _serviceManager, bridge, hanHouCeLiang); - lv_down90_2.init("Camera2", "极耳尺寸-内-铝-相机2(底部90°)", { { 604, 1,580,"605","612",-1} }, 1, lvDetParams[1], _serviceManager, bridge, hanHouDown); - tong_top90_3.init("Camera3", "极耳尺寸-内-铜-相机3(顶部90°)", { { 606,1,580,"607","614",840} }, 1, tongDetParams[0], _serviceManager, bridge, hanHouCeLiang); - tong_down90_4.init("Camera4", "极耳尺寸-内-铜-相机4(底部90°)", { { 608, 1,580,"609","616",-1} }, 1, tongDetParams[1], _serviceManager, bridge, hanHouDown); + lv_top90_1.init("Camera1", "极耳尺寸-内-铝-相机1(顶部90°)", { { 602, 1,580,"603","610",860} }, 1, &lvDetParams[0], _serviceManager, bridge, hanHouCeLiang); + lv_down90_2.init("Camera2", "极耳尺寸-内-铝-相机2(底部90°)", { { 604, 1,580,"605","612",-1} }, 1, &lvDetParams[1], _serviceManager, bridge, hanHouDown); + tong_top90_3.init("Camera3", "极耳尺寸-内-铜-相机3(顶部90°)", { { 606,1,580,"607","614",840} }, 1, &tongDetParams[0], _serviceManager, bridge, hanHouCeLiang); + tong_down90_4.init("Camera4", "极耳尺寸-内-铜-相机4(底部90°)", { { 608, 1,580,"609","616",-1} }, 1, &tongDetParams[1], _serviceManager, bridge, hanHouDown); - lv_top45_5.init("Camera5", "底部撕裂-内-铝-相机5(顶部45°)", { { 642,1,580,"643","650",-1} }, 1, lvDetParams[2], _serviceManager, bridge, hanHouDown); - lv_down45_6.init("Camera6", "底部撕裂-内-铝-相机6(底部45°)", { { 644, 1,580,"645","652",-1} }, 1, lvDetParams[3], _serviceManager, bridge, hanHouDown); - tong_top45_7.init("Camera7", "底部撕裂-内-铜-相机7(顶部45°)", { { 646, 1,580,"647","654",-1} }, 1, tongDetParams[2], _serviceManager, bridge, hanHouDown); - tong_down45_8.init("Camera8", "底部撕裂-内-铜-相机8(底部45°)", { { 648, 1,580,"649","656",-1} }, 1, tongDetParams[3], _serviceManager, bridge, hanHouDown); + lv_top45_5.init("Camera5", "底部撕裂-内-铝-相机5(顶部45°)", { { 642,1,580,"643","650",-1} }, 1, &lvDetParams[2], _serviceManager, bridge, hanHouDown); + lv_down45_6.init("Camera6", "底部撕裂-内-铝-相机6(底部45°)", { { 644, 1,580,"645","652",-1} }, 1, &lvDetParams[3], _serviceManager, bridge, hanHouDown); + tong_top45_7.init("Camera7", "底部撕裂-内-铜-相机7(顶部45°)", { { 646, 1,580,"647","654",-1} }, 1, &tongDetParams[2], _serviceManager, bridge, hanHouDown); + tong_down45_8.init("Camera8", "底部撕裂-内-铜-相机8(底部45°)", { { 648, 1,580,"649","656",-1} }, 1, &tongDetParams[3], _serviceManager, bridge, hanHouDown); } #pragma endregion return true; diff --git a/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h b/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h index 759538a..46ae801 100644 --- a/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h +++ b/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h @@ -242,15 +242,15 @@ public: } 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); + 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); + 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; } diff --git a/src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp b/src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp new file mode 100644 index 0000000..07fbb71 --- /dev/null +++ b/src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp @@ -0,0 +1,8 @@ +#include <581_ZhongHan_hanhou.h> + +mission* createMission() { + return new _581_ZhongHan_hanhou(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h b/src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h new file mode 100644 index 0000000..60ef0ab --- /dev/null +++ b/src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h @@ -0,0 +1,189 @@ +#include +#include +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +#pragma endregion +class zhongHanParams { +public: + handdleAI::pSegmentation* seg_hanHouDingWei = nullptr; + bool isTong = true; +}; +bool zhongHan_hanHouCeLiang(std::shared_ptr data, zhongHanParams* _detParams, sx_581_address address) { + try + { +#if 0 + /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ + plcResult = "1"; + QString resultTag = "OK"; + cv::Mat resultImage = img2D.clone(); + putTextHusky(resultImage, utf8_to_gbk("OK").c_str(), cv::Point(0, 50), cv::Scalar(0, 255, 0), 500); + cv::resize(resultImage, resultImage, cv::Size(), 0.5, 0.5); + resMat.push_back(resultImage); + if (resMat.size() > 0) + { + addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, resultTag));//保存结果图 + } + return true; + /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ + + + +#endif + QByteArray plcResult = "2"; + //img2D = cv::imread("D:\\终焊CCD存图\\焊后正面测量CCD\\2025-07-28\\原图\\21H\\errSN\\ORI0_errSN_DA1806128_0_21-34-01-10.bmp", -1); + cv::Mat sourceImg = data->oriImgs[0]; + cv::Rect cutRect; + if (_detParams->isTong == true) { + cutRect = cv::Rect(2000, 0, 3000, 3648); + } + if (_detParams->isTong == true) { + cutRect = cv::Rect(400, 0, 3000, 3648); + } + cv::Mat cutImage = sourceImg(cutRect & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows))); + + 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->segOriginImgs.push_back(segProcessMat); + data->segOriginImgs.push_back(cutImage); + + 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(0.0346699); + 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, out_LineCor, + out_Distance1, out_Distance2, out_Distance3, out_Distance4, + out_ColorType, out_Flag; + 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_ColorType = procedureCall.GetOutputCtrlParamTuple("out_ColorType"); + out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + TextRendererZH textPainter(Paint.cols, Paint.rows, 120); + 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, "水平间距:" + std::to_string(out_Distance1[0].D()), cv::Point(50, 25), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "竖直间距:" + std::to_string(out_Distance1[1].D()), cv::Point(50, 25), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + QByteArray::number(out_Distance1[1].D())); + } + //2 + { + textPainter.putText(Paint, "水平间距:" + std::to_string(out_Distance2[0].D()), cv::Point(50, 450), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "竖直间距:" + std::to_string(out_Distance2[1].D()), cv::Point(50, 675), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + 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"; + } + plcResult = "1";//强制OK + data->resultImgs.push_back(Paint); + sourceImg.release(); + 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->oriImgs[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->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//结果反馈 + return true; +} +class _581_ZhongHan_hanhou : public mission { +public: + _581_SX_Single_triggerTemplate< zhongHanParams> lv_top_1; + _581_SX_Single_triggerTemplate< zhongHanParams> lv_left45_2; + _581_SX_Single_triggerTemplate< zhongHanParams> lv_right45_3; + _581_SX_Single_triggerTemplate< zhongHanParams> _3D_1; + + _581_SX_Single_triggerTemplate< zhongHanParams> tong_top_5; + _581_SX_Single_triggerTemplate< zhongHanParams> tong_left45_6; + _581_SX_Single_triggerTemplate< zhongHanParams> tong_right45_7; + _581_SX_Single_triggerTemplate< zhongHanParams> _3D_2; + zhongHanParams tongDetParams; + zhongHanParams lvDetParams; + 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/60_2_hanqian_dingwei_seg.BHD", 64, 0); + // params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_segT.BHD", 64, 0); + // params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/60_2_hanqian_clsT.BHD", 0, 1); + //} + //for (auto& params : lvDetParams) { + // params.segDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_dingwei_seg.BHD", 64, 1); + // params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_segL.BHD", 64, 1); + // params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/60_2_hanqian_clsL.BHD", 1, 1); + // params.isTong = false; + //} + tongDetParams.isTong = true; + lvDetParams.isTong = false; + initOnce = true; + } + } + bool initCustom() { +#pragma region 注册触发器回调 + lv_top_1.init("Camera1", "焊印检测-内-铜-相机1(90°)", { { 5360, 1,5340,"5362","5364",-1} }, 1, &lvDetParams, _serviceManager, bridge, zhongHan_hanHouCeLiang); + lv_left45_2.init("Camera2", "翻折撕裂-内-铜-相机2(45°)", { { 5370, 1,5340,"5372","5374",-1} }, 1, &lvDetParams, _serviceManager, bridge, zhongHan_hanHouCeLiang); + lv_right45_3.init("Camera3", "翻折撕裂-内-铜-相机3(45°)", { { 5380,1,5340,"5382","5384",-1} }, 1, &tongDetParams, _serviceManager, bridge, zhongHan_hanHouCeLiang); + _3D_1.init("Camera4", "焊后检测-3D相机1" , { { 5400, 1,5340,"5402","5404",-1} }, 1, & tongDetParams, _serviceManager, bridge, zhongHan_hanHouCeLiang); + + tong_top_5.init("Camera5", "焊印检测-外-铝-相机5(90°)", { { 5440, 1,5420,"5442","5444",-1} }, 1, &tongDetParams, _serviceManager, bridge, zhongHan_hanHouCeLiang); + tong_left45_6.init("Camere6", "翻折撕裂-外-铝-相机6(45°)", { { 5450,1,5420,"5452","5454",-1} }, 1, &lvDetParams, _serviceManager, bridge, zhongHan_hanHouCeLiang); + tong_right45_7.init("Camera7", "翻折撕裂-外-铝-相机7(45°)", { { 5460, 1,5420,"5462","5464",-1} }, 1, &lvDetParams, _serviceManager, bridge, zhongHan_hanHouCeLiang); + _3D_2.init("Camera8", "焊后检测-3D相机2", { { 5480, 1,5420,"5482","5484",-1} }, 1, &tongDetParams, _serviceManager, bridge, zhongHan_hanHouCeLiang); +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581_ZhongHan_hanhou/CMakeLists.txt b/src/mission/581_ZhongHan_hanhou/CMakeLists.txt new file mode 100644 index 0000000..bba2e81 --- /dev/null +++ b/src/mission/581_ZhongHan_hanhou/CMakeLists.txt @@ -0,0 +1,78 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/back + ${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 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 Gui Network Sql REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/qtBridge.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp b/src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp new file mode 100644 index 0000000..2ffa3c3 --- /dev/null +++ b/src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp @@ -0,0 +1,8 @@ +#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/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h b/src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h new file mode 100644 index 0000000..b8bd5e4 --- /dev/null +++ b/src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h @@ -0,0 +1,310 @@ +#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 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 = "2"; +#if 0 + /*img2D = cv::imread("./testImages/CU_1.png", -1); + sourceImg = img2D.clone();*/ + img2D = cv::imread("./testImages/CU.bmp", -1); + sourceImg = img2D(cutROI & cv::Rect(0, 0, img2D.cols, img2D.rows)).clone(); +#endif + cv::Mat sourceImg = data->oriImgs[0]; + 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.0337797; + 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, 120); + 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_L_1 = out_Distance[3].D();//铝(负)极的包膜距离(mm) + double Out_Vale_L_2 = out_Distance[4].D();//铝(负)极连接片中心的和上极耳水平边缘距离(mm) + double Out_Vale_L_3 = out_Distance[5].D();//铝(负)极连接片中心的和下极耳水平边缘距离(mm) + + double extremum_Value = out_Distance[6].D(); + + //发送到另一算法线程 + 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.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(); + } + + if (out_LinePoint.Length() > 38) { + for (int i = 20; i < 40; i++) { + _calResult.lines.push_back(out_LinePoint[i].D()); + } + } + + _detParams->insertResult(_calResult); + textPainter.putText(Paint, "铜(正)极的包膜距离:" + std::to_string(Out_Vale_T_1), cv::Point(50, 50), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(Out_Vale_T_1));//数据1 + textPainter.putText(Paint, "铜(正)极连接片中心的和上极耳水平边缘距离:" + std::to_string(Out_Vale_T_2), cv::Point(50, 200), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "铜(正)极连接片中心的和下极耳水平边缘距离:" + std::to_string(Out_Vale_T_3), cv::Point(50, 350), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "铜(正)极和铝(负)极的中心距离:" + std::to_string(extremum_Value), cv::Point(50, 600), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(extremum_Value));//数据2 + for (int i = 0; i < 5; 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; + } + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + plcResult = "1";//强制OK + data->resultImgs.push_back(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->oriImgs[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->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + return true; +} +bool hanQianCeLiang_Sub(std::shared_ptr data, zhongHanHanQianParams* _detParams, sx_581_address address) { + try { + //测试算法用 + QByteArray plcResult = "2"; + { +#if 0 + //img2D = cv::imread("./testImages/AL_1.png", -1); + //sourceImg = img2D.clone(); + img2D = cv::imread("./testImages/AL.bmp", -1); + sourceImg = img2D(cutROI & cv::Rect(0, 0, img2D.cols, img2D.rows)).clone(); +#endif + } + cv::Mat sourceImg = data->oriImgs[0]; + 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, 120); + //等待结果 + 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->resultImgs.push_back(Paint); + return false; + } + + if (_calResult.algoFailed == false) { + textPainter.putText(Paint, "铝(负)极的包膜距离:" + std::to_string(_calResult.Out_Vale_L_1), cv::Point(50, 50), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(_calResult.Out_Vale_L_1));//数据1 + textPainter.putText(Paint, "铝(负)极连接片中心的和上极耳水平边缘距离:" + std::to_string(_calResult.Out_Vale_L_2), cv::Point(50, 200), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "铝(负)极连接片中心的和下极耳水平边缘距离:" + std::to_string(_calResult.Out_Vale_L_3), cv::Point(50, 350), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "铜(正)极和铝(负)极的中心距离:" + std::to_string(_calResult.extremum_Value), cv::Point(50, 600), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(_calResult.extremum_Value));//数据2 + for (int i = 0; i < 5; 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"; + } + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + plcResult = "1";//强制OK + data->resultImgs.push_back(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->oriImgs[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->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + 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("./halconAlgoFiles/AlgoLibrary_602.hdpl"); + + if (initOnce == false) { + + initOnce = true; + } + } + bool initCustom() { +#pragma region 注册触发器回调 + tong_1.init("Camera1", "焊前定位-相机1", { { 5060, 1,{5070},"5062","5064",5066} }, 1, &detParams, _serviceManager, bridge, hanQianCeLiang_Main); + lv_1.init("Camera1", "焊前定位-相机2", { { 5090, 1,{5100},"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/581_ZhongHan_hanqian/CMakeLists.txt b/src/mission/581_ZhongHan_hanqian/CMakeLists.txt new file mode 100644 index 0000000..bba2e81 --- /dev/null +++ b/src/mission/581_ZhongHan_hanqian/CMakeLists.txt @@ -0,0 +1,78 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/back + ${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 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 Gui Network Sql REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/qtBridge.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp b/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp index 1ef8130..e7a4159 100644 --- a/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp +++ b/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp @@ -77,7 +77,7 @@ bool Hd_VirtualCamera::run()//����� } else { vector mats; - mats.push_back(cv::Mat(4096,3200,CV_8UC3,cv::Scalar(0,255,0))); + mats.push_back(cv::Mat(20960,3200,CV_8UC3,cv::Scalar(0,255,0))); queuePic.enqueue(mats); } n_mutex->unlock();