diff --git a/include/qtBridge.h b/include/qtBridge.h index cf1cf39..ad20522 100644 --- a/include/qtBridge.h +++ b/include/qtBridge.h @@ -24,7 +24,7 @@ class qtFuncBridge : public QObject { Q_OBJECT signals: // 日志相关 - void loadingWindow_appendLog(const QString& text, const QColor& color); + void loadingWindow_appendInitLog(const QString& text, const QColor& color); void loadingWindow_modifyLog(int col, const QString& text, const QColor& color); void loadingWindow_clearLog(); @@ -58,11 +58,6 @@ signals: void loadingWindow_SetErrorIcon(); void loadingWindow_SetErrorText(QString text); - // 初始化日志 - int loadingWindow_appendInitLog(QString text, QString color); - void loadingWindow_modifyInitLog(QString text, QString color, int col); - void loadingWindow_clearInitLog(); - // 警告日志 void loadingWindow_appendWarningLog(QString text); void loadingWindow_clearWarningLog(); diff --git a/include/sxGlobal.h b/include/sxGlobal.h index 908b9f3..5a3c7d4 100644 --- a/include/sxGlobal.h +++ b/include/sxGlobal.h @@ -132,7 +132,7 @@ public: QString::number(address[batteryOffset].triggerAddr), sn, 1, camera->config.oriSaveFormat);//创建数据包 camera->captureImage(data);//拍照 data->saveObjectName = saveObjectName; - generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_0"));//处理算法 并在取到图片后发送完成信号 + generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); } private: diff --git a/src/Core/back/cameraManager.cpp b/src/Core/back/cameraManager.cpp index 2bfb96b..19ac289 100644 --- a/src/Core/back/cameraManager.cpp +++ b/src/Core/back/cameraManager.cpp @@ -156,7 +156,7 @@ void cameraManager::run(){ if (cameraStruct.module_ptr->initParas(initByte)){ camera* _camera = new camera(cameraStruct, cameras.size(), bridge); cameras.insert(std::make_pair(cameraStruct.key, _camera)); - emit bridge->loadingWindow_appendLog("相机" + QString::fromStdString(cameraStruct.key) + "初始化成功", "green"); + emit bridge->loadingWindow_appendInitLog("相机" + QString::fromStdString(cameraStruct.key) + "初始化成功", "green"); qDebug() << "[INFO] " << " initParas success!"; cameraStruct.init = true; } @@ -165,7 +165,7 @@ void cameraManager::run(){ cameraStruct.module_ptr->readData(vec_mat, errorStr); initReuslt = false; qCritical() << "[Error] " << " moduleName:" << QString::fromStdString(cameraStruct.dllPath) << " initParas failed!"; - emit bridge->loadingWindow_appendLog("相机" + QString::fromStdString(cameraStruct.key) + "初始化失败->" + errorStr, "red"); + emit bridge->loadingWindow_appendInitLog("相机" + QString::fromStdString(cameraStruct.key) + "初始化失败->" + errorStr, "red"); } } if (initReuslt == true){ @@ -202,7 +202,7 @@ bool cameraManager::loadModule(cameraStruct& _cameraStruct){ if (!m_lib->isLoaded()){ qDebug() << "[Error] " << " Loaded error:" << m_lib->errorString(); - bridge->loadingWindow_appendLog("加载相机模块" + dllPath + "失败->" + m_lib->errorString(), "red"); + emit bridge->loadingWindow_appendInitLog("加载相机模块" + dllPath + "失败->" + m_lib->errorString(), "red"); return false; } diff --git a/src/Core/back/triggerManager.cpp b/src/Core/back/triggerManager.cpp index fb449e9..28ac239 100644 --- a/src/Core/back/triggerManager.cpp +++ b/src/Core/back/triggerManager.cpp @@ -55,7 +55,7 @@ bool triggerManager::connectHost(){ libLoadedflag = m_lib->load(); if (!m_lib->isLoaded()){ //emit _core._qtFunc.sendErrorToMainwindow(dllNotFound); - emit bridge->loadingWindow_appendLog("找不到" + triggerFileName,"red"); + emit bridge->loadingWindow_appendInitLog("找不到" + triggerFileName,"red"); return false; } if (libLoadedflag){ @@ -79,7 +79,7 @@ bool triggerManager::connectHost(){ initFailure = trigger->initParas(QByteArray()); #endif - emit bridge->loadingWindow_appendLog(triggerFileName + "连接到" + IpAndPort,QColor("white")); + emit bridge->loadingWindow_appendInitLog(triggerFileName + "连接到" + IpAndPort,QColor("white")); } @@ -87,14 +87,14 @@ bool triggerManager::connectHost(){ //emit _core._qtFunc.sendErrorToMainwindow(triggerInitFailure); delete m_lib; m_lib = nullptr; - emit bridge->loadingWindow_appendLog(triggerFileName + "初始化失败","red"); + emit bridge->loadingWindow_appendInitLog(triggerFileName + "初始化失败","red"); status = InitFailure; return false; } else{ status = InitOK; init = true; - emit bridge->loadingWindow_appendLog(triggerFileName + "连接成功","green"); + emit bridge->loadingWindow_appendInitLog(triggerFileName + "连接成功","green"); return true; } } diff --git a/src/Core/backendInterface.cpp b/src/Core/backendInterface.cpp index 4f874d0..11e6312 100644 --- a/src/Core/backendInterface.cpp +++ b/src/Core/backendInterface.cpp @@ -15,7 +15,7 @@ public: } _detProcess->init(); bridge = bridgeIn; - emit bridge->loadingWindow_appendLog(u8"核心加载成功,正在初始化",QColor("white")); + emit bridge->loadingWindow_appendInitLog(u8"核心加载成功,正在初始化",QColor("white")); _detProcess->start(); } diff --git a/src/Core/detProcess.hpp b/src/Core/detProcess.hpp index c6f9a25..1b1cffc 100644 --- a/src/Core/detProcess.hpp +++ b/src/Core/detProcess.hpp @@ -16,7 +16,6 @@ public: bool initOnce = false; detProcess(SQLiteDB* dbIn, nlohmann::ordered_json& jsonIn, qtFuncBridge* bridgeIn): db(dbIn),bridge(bridgeIn), missionJson(jsonIn){ - } ~detProcess() { safeShutdownDelete(_serviceManager._triggerManager); @@ -120,6 +119,7 @@ public: bool res3 = waitrForInitResult(_serviceManager._triggerManager); if (res1 == true && res2 == true && res3 == true) { + emit bridge->loadingWindow_appendInitLog("初始化Mission中...", "yellow"); _missionLoader.loadMission(missionJson["missionDllPath"]); _missionLoader.getmission(missionJson["missionDllPath"])->initBasic( &_serviceManager, diff --git a/src/Core/handleAi/handleAiModel.h b/src/Core/handleAi/handleAiModel.h index 2a54201..7989118 100644 --- a/src/Core/handleAi/handleAiModel.h +++ b/src/Core/handleAi/handleAiModel.h @@ -9,20 +9,23 @@ //#include #include #include +#include +#include const bool enableHandleAiModel = true; // 是否启用HandleAI模型 -class handleAiModelSeg -{ +class handleAiModelSeg { public: + bool initFlag = false; std::string path; - int gpuIndex =0; - std::mutex* gpuMutex; - handleAiModelSeg(std::string pathIn, int gpuIndexIn, std::mutex* mutex){ + int gpuIndex = 0,batchSize = 64; + QMutex gpuMutex; + handleAiModelSeg(std::string pathIn, int gpuIndexIn, int batchSizeIn = 64){ path = pathIn; gpuIndex = gpuIndexIn; - gpuMutex = mutex; + batchSize = batchSizeIn; }; std::string init() { - segPtr = handdleAI::CreateSegObj((char*)path.c_str(),gpuIndex); + segPtr = handdleAI::CreateSegObjS((char*)path.c_str(), batchSize, gpuIndex); + initFlag = true; return path; } bool destroy(){ @@ -31,27 +34,27 @@ public: handdleAI::DestroySegObj(segPtr); return true; } - cv::Mat Evaluate(cv::Mat& in){ - gpuMutex->lock(); - cv::Mat res = segPtr->Evaluate(in); - gpuMutex->unlock(); - return res; + cv::Mat Evaluate(cv::Mat& input){ + QMutexLocker locker(&gpuMutex); + return segPtr->Evaluate(input); } handdleAI::pSegmentation* segPtr = nullptr; }; class handleAiModelCls{ public: + bool initFlag = false; std::string path; - int gpuIndex = 0; - std::mutex* gpuMutex; - handleAiModelCls(std::string pathIn, int gpuIndexIn, std::mutex* mutex){ + int gpuIndex = 0, batchSize = 1; + QMutex gpuMutex; + handleAiModelCls(std::string pathIn, int gpuIndexIn, int batchSizeIn = 1){ path = pathIn; gpuIndex = gpuIndexIn; - gpuMutex = mutex; + batchSize = batchSizeIn; }; std::string init(){ - clsPtr = handdleAI::CreateClsObjV3((char*)path.c_str(), gpuIndex,1); + clsPtr = handdleAI::CreateClsObjV3((char*)path.c_str(), gpuIndex, batchSize); + initFlag = true; return path; } bool destroy(){ @@ -60,26 +63,26 @@ public: handdleAI::DestroyClsObj(clsPtr); return true; } - int Evaluate(cv::Mat& in){ - gpuMutex->lock(); - int res = clsPtr->Evaluate(in); - gpuMutex->unlock(); - return res; + int Evaluate(cv::Mat& input){ + QMutexLocker locker(&gpuMutex); + return clsPtr->Evaluate(input); } - handdleAI::pClassification* clsPtr; + handdleAI::pClassification* clsPtr = nullptr; }; class handleAiModelDet{ public: + bool initFlag = false; std::string path; - int gpuIndex = 0; - std::mutex* gpuMutex; - handleAiModelDet(std::string pathIn, int gpuIndexIn, std::mutex* mutex){ + int gpuIndex = 0,batchSize = 1; + QMutex gpuMutex; + handleAiModelDet(std::string pathIn, int gpuIndexIn,int batchSizeIn = 1){ path = pathIn; gpuIndex = gpuIndexIn; - gpuMutex = mutex; + batchSize = batchSizeIn; }; std::string init(){ - detPtr = handdleAI::CreateDetObjS((char*)path.c_str(), 1, gpuIndex); + detPtr = handdleAI::CreateDetObjS((char*)path.c_str(), batchSize, gpuIndex); + initFlag = true; return path; } bool destroy(){ @@ -88,13 +91,12 @@ public: handdleAI::DestroyDetObj(detPtr); return true; } - bool Evaluate(cv::Mat& in, std::vector& result){ - gpuMutex->lock(); - result=detPtr->Evaluate(in); - gpuMutex->unlock(); + bool Evaluate(cv::Mat& input, std::vector& result){ + QMutexLocker locker(&gpuMutex); + result=detPtr->Evaluate(input); return true; } - handdleAI::pDetection* detPtr; + handdleAI::pDetection* detPtr = nullptr; }; class handleAiModelManager :public serviceModule{ @@ -102,7 +104,6 @@ public: enum type{ seg, cls, det }; - bool initFlag = false; std::string basePath; handleAiModelManager(nlohmann::ordered_json& json, qtFuncBridge* bridgeIn) :bridge(bridgeIn){ @@ -129,37 +130,39 @@ public: int gpuIndex = clsModel.value()["gpuIndex"]; insertClsModelPath(keyName, modelPath, gpuIndex); } - jsonAvailable = true; } catch (const std::exception& e) { std::cerr << "handleAiModelManager读取配置文件异常: " << e.what() << std::endl; } }; - bool insertSegModelPath(std::string keyName,std::string modelPath ,int gpuIndex){ + handleAiModelSeg* insertSegModelPath(std::string keyName,std::string modelPath ,int gpuIndex){ auto mapResult = segModels.find(keyName); if (mapResult != segModels.end())//已有数据 - return true; - handleAiModelSeg* segModel = new handleAiModelSeg(modelPath, gpuIndex, gpuMutex[gpuIndex]); + return nullptr; + handleAiModelSeg* segModel = new handleAiModelSeg(modelPath, gpuIndex); segModels.insert(std::make_pair(keyName, segModel)); + return segModel; } - bool insertDetModelPath(std::string keyName, std::string modelPath, int gpuIndex){ + handleAiModelDet* insertDetModelPath(std::string keyName, std::string modelPath, int gpuIndex){ auto mapResult = detModels.find(keyName); if (mapResult != detModels.end())//已有数据 - return true; - handleAiModelDet* detModel = new handleAiModelDet(modelPath, gpuIndex, gpuMutex[gpuIndex]); + return nullptr; + handleAiModelDet* detModel = new handleAiModelDet(modelPath, gpuIndex); detModels.insert(std::make_pair(keyName, detModel)); + return detModel; } - bool insertClsModelPath(std::string keyName, std::string modelPath, int gpuIndex){ + handleAiModelCls* insertClsModelPath(std::string keyName, std::string modelPath, int gpuIndex){ auto mapResult = clsModels.find(keyName); if (mapResult != clsModels.end())//已有数据 - return true; - handleAiModelCls* clsModel = new handleAiModelCls(modelPath, gpuIndex, gpuMutex[gpuIndex]); + return nullptr; + handleAiModelCls* clsModel = new handleAiModelCls(modelPath, gpuIndex); clsModels.insert(std::make_pair(keyName, clsModel)); + return clsModel; } // handleAiModelSeg* getSegModel(std::string modelName){ auto mapResult = segModels.find(modelName); - if (mapResult == segModels.end())//已有数据 + if (mapResult == segModels.end())//没有数据 return nullptr; return mapResult->second; } @@ -176,36 +179,59 @@ public: return mapResult->second; } + //handdleAI::pSegmentation* insertSegModelAndInit(std::string modelPath, int gpuIndex, int batchSize = 64) { + // std::string uuid = QUuid().createUuid().toString().toStdString(); + // handleAiModelSeg* segModel = new handleAiModelSeg(modelPath, gpuIndex, batchSize); + // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[SEG]检测模型初始化中..."), "white"); + // //segModel->init(); + // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[SEG]初始化成功..."), "white"); + // segModels.insert(std::make_pair(uuid, segModel)); + // return segModel->segPtr; + //} + //handdleAI::pClassification* insertClsModelAndInit(std::string modelPath, int gpuIndex, int batchSize = 1) { + // std::string uuid = QUuid().createUuid().toString().toStdString(); + // handleAiModelCls* clsModel = new handleAiModelCls(modelPath, gpuIndex, batchSize); + // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[CLS]检测模型初始化中..."), "white"); + // //clsModel->init(); + // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[CLS]初始化成功..."), "white"); + // clsModels.insert(std::make_pair(uuid, clsModel)); + // return clsModel->clsPtr; + //} + //handdleAI::pDetection* insertDetModelAndInit(std::string modelPath, int gpuIndex, int batchSize = 1) { + // std::string uuid = QUuid().createUuid().toString().toStdString(); + // handleAiModelDet* detModel = new handleAiModelDet(modelPath, gpuIndex, batchSize); + // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[DET]检测模型初始化中..."), "white"); + // //detModel->init(); + // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[DET]初始化成功..."), "white"); + // detModels.insert(std::make_pair(uuid, detModel)); + // return detModel->detPtr; + //} void run(){ - if (init == true || jsonAvailable == false) - return; if (enableHandleAiModel == true) { std::vector> futures; - for (auto& model : segModels) - { + for (auto& model : segModels){ + if (model.second->initFlag == true) continue; futures.push_back(std::async(std::launch::async, &handleAiModelSeg::init, model.second)); - bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); + emit bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); } - for (auto& model : clsModels) - { + for (auto& model : clsModels){ + if (model.second->initFlag == true) continue; futures.push_back(std::async(std::launch::async, &handleAiModelCls::init, model.second)); - bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); + emit bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); } - for (auto& model : detModels) - { + for (auto& model : detModels){ + if (model.second->initFlag == true) continue; futures.push_back(std::async(std::launch::async, &handleAiModelDet::init, model.second)); - bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); + emit bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); } - for (int i = 0; i < futures.size(); i++) - { + for (int i = 0; i < futures.size(); i++){ futures[i].wait(); std::string result = futures[i].get(); - bridge->loadingWindow_appendLog( + emit bridge->loadingWindow_appendInitLog( QString::fromStdString(fileManager::getFileName(result)) + "成功( " + QString::number(i + 1) + "/" + QString::number(futures.size()) + ")", "green"); qDebug() << QString::fromStdString(fileManager::getFileName(result) + "成功"); std::cout << fileManager::getFileName(result) + "成功" << std::endl; } - init = true; status = InitOK; } else { @@ -215,8 +241,7 @@ public: } - ~handleAiModelManager() - { + ~handleAiModelManager(){ if (enableHandleAiModel) { for (auto& model : detModels) model.second->destroy(); @@ -231,11 +256,8 @@ private: std::unordered_map segModels; std::unordered_map clsModels; std::unordered_map detModels; - std::vectorgpuMutex = std::vector(6, new std::mutex()); int gpuCnt = 1;//gpu数量 - bool init = false; nlohmann::json handleAiJson; - bool jsonAvailable = false; qtFuncBridge* bridge; }; diff --git a/src/core/back/detCallbackChain.hpp b/src/core/back/detCallbackChain.hpp index 1e5e0d8..d06deda 100644 --- a/src/core/back/detCallbackChain.hpp +++ b/src/core/back/detCallbackChain.hpp @@ -28,7 +28,7 @@ public: //异步启动检测 void ansyncProcess(std::shared_ptr data, addressTemplate address, QByteArray completeSignal = "") { QFuture future = QtConcurrent::run([this, data, address, completeSignal]() { - process(data, address); + process(data, address, completeSignal); }); } //启动检测 @@ -37,7 +37,8 @@ public: while (data->oriImgs.size() < data->imgAmountMin) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - _triggerManager->writeShort(completeSignal); + if(completeSignal != "") + _triggerManager->writeShort(completeSignal); //等待图片满足要求后,储存原图,异步执行算法函数 auto resultData = algoEvaluate(data, _handleAiModels, address); // 确保线程安全退出 diff --git a/src/launcher/GUI/front/loadingWidget.h b/src/launcher/GUI/front/loadingWidget.h index 2461067..638a93b 100644 --- a/src/launcher/GUI/front/loadingWidget.h +++ b/src/launcher/GUI/front/loadingWidget.h @@ -17,12 +17,12 @@ public: QLabel* sign = nullptr; QMovie* movie = nullptr; QTextEdit* initLog = nullptr; + QTextEdit* consoleLog = nullptr; fancyButtonText* retryBtn = new fancyButtonText("重试", 100, 50, "重新进行初始化"); fancyButtonText* manualBtn = new fancyButtonText("离线模式", 180, 50, "离线模式"); QGridLayout* glayout = new QGridLayout(this); - QVBoxLayout* vlayout = new QVBoxLayout(this); - loadingWidget(qtFuncBridge* bridgeIn) - { + QGridLayout* logLayout = new QGridLayout(this); + loadingWidget(qtFuncBridge* bridgeIn){ bridge = bridgeIn; glayout->setAlignment(Qt::AlignCenter); connect(retryBtn, &QPushButton::clicked, [=]() @@ -32,8 +32,7 @@ public: emit bridge->reInitConfig(); }); } - void start() - { + void start(){ if (isRunning == true) stop(); QPalette palette; @@ -46,7 +45,7 @@ public: movie->start(); sign->setMovie(movie); - + //初始化日志 initLog = new QTextEdit(); initLog->setAlignment(Qt::AlignCenter); initLog->setStyleSheet(QString("background-color: transparent;" @@ -59,17 +58,34 @@ public: initLog->setTextColor(Qt::white); initLog->append("正在初始化..."); - vlayout->addWidget(initLog); + logLayout->addWidget(initLog, 0, 0); + + //控制台日志 + consoleLog = new QTextEdit(); + consoleLog->setAlignment(Qt::AlignCenter); + consoleLog->setStyleSheet(QString("background-color: black;" + "border: 1px solid white;" + "border-radius: 0px;")); + consoleLog->setReadOnly(true); + consoleLog->setFixedWidth(720); + QFont font2("微软雅黑", 7); + consoleLog->setFont(font2); + consoleLog->setTextColor(Qt::white); + consoleLog->append("控制台日志..."); + logLayout->addWidget(consoleLog, 1, 0,Qt::AlignCenter|Qt::AlignTop); + + //重试或者离线模式等按钮 QHBoxLayout* btnLayout = new QHBoxLayout(); btnLayout->setAlignment(Qt::AlignLeft); btnLayout->addWidget(manualBtn); + manualBtn->hide(); btnLayout->addWidget(retryBtn); retryBtn->hide(); - vlayout->addLayout(btnLayout); + logLayout->addLayout(btnLayout, 2, 0,Qt::AlignLeft); glayout->addWidget(sign, 0, 0); - glayout->addLayout(vlayout, 1, 0); + glayout->addLayout(logLayout, 1, 0); glayout->setRowStretch(0, 5); glayout->setRowStretch(1, 4); //screenshot_ = QPixmap::grabWindow(widget->winId()); @@ -77,8 +93,7 @@ public: isRunning = true; initOK = true; } - void stop() - { + void stop(){ if (isRunning == false) return; isRunning = false; @@ -91,10 +106,8 @@ public: movie = nullptr; initLog = nullptr; } - void setError() - { - if (isRunning == true) - { + void setError(){ + if (isRunning == true){ if (movie != nullptr) delete movie; movie = nullptr; @@ -105,8 +118,15 @@ public: manualBtn->setEnabled(true); } } - - int appendLog(const QString& text, const QColor& color = Qt::white) { + int appendConsoleLog(const QString& text) { + if (consoleLog && initOK == true) { + QMutexLocker locker(&mutex); + consoleLog->append(text); + return consoleLog->document()->blockCount(); + } + return -1; + } + int appendInitLog(const QString& text, const QColor& color = Qt::white) { if (initLog && initOK == true) { QMutexLocker locker(&mutex); initLog->setTextColor(color); @@ -141,6 +161,7 @@ public: } void clearLog() { initLog->clear(); + consoleLog->clear(); } protected: #if 0 diff --git a/src/launcher/GUI/mainwindow.h b/src/launcher/GUI/mainwindow.h index 615ed01..436350f 100644 --- a/src/launcher/GUI/mainwindow.h +++ b/src/launcher/GUI/mainwindow.h @@ -395,7 +395,9 @@ public slots: void recvInitFinished(initStatus input){ switch (input){ case initStatus::InitOK: + _loadingWidget.clearLog(); backEndInit = true; + logService::getInstance()->disableLoadingWidgetOutput(); if (isLogin == true) loading(false); break; diff --git a/src/launcher/logger/logService.cpp b/src/launcher/logger/logService.cpp index 9c97df2..0003750 100644 --- a/src/launcher/logger/logService.cpp +++ b/src/launcher/logger/logService.cpp @@ -29,7 +29,7 @@ logService::logService(){ _qtRediretor = std::make_unique(); // STD日志到Qt日志界面、Qt主界面、spdLog - _stdConsoleRedirector->registerCallback([this](const std::string& output) { + _stdConsoleRedirector->registerCallback("qtLogWidget",[this](const std::string& output) { if (!output.empty() && output != "\n") { QString outPutMsg = QString::fromStdString(output); _logToQtWidget->sendStdLogSignal(outPutMsg); // Qt日志界面 @@ -39,14 +39,21 @@ logService::logService(){ }); // STD日志到控制台 - _stdConsoleRedirector->registerCallback([this](const std::string& output) { + _stdConsoleRedirector->registerCallback("console",[this](const std::string& output) { if (!output.empty() && output != "\n") { _stdConsoleRedirector->writeToConsole(output); } }); - + + // STD日志到加载界面 + _stdConsoleRedirector->registerCallback("loadingWidget", [this](const std::string& output) { + if (!output.empty() && output != "\n") { + emit _logToQtWidget->loadingWindow_appendConsoleLog(QString::fromStdString(output)); + } + }); + // QT日志到spdLog和Qt日志界面 - _qtRediretor->registerCallback([this](const QString& output) { + _qtRediretor->registerCallback("qtLogWidget",[this](const QString& output) { if (!output.isEmpty()) { qtLogger->LogDebug("[QT]" + output.toStdString()); _logToQtWidget->sendQtLogSignal(output); // Qt日志界面 @@ -54,7 +61,7 @@ logService::logService(){ }); // QT日志到控制台 - _qtRediretor->registerCallback([this](const QString& output) { + _qtRediretor->registerCallback("console", [this](const QString& output) { if (!output.isEmpty()) { _stdConsoleRedirector->writeToConsole(output.toStdString()); } @@ -64,23 +71,15 @@ logService::logService(){ qDebug() << "Failed to initialize logService:" << e.what(); } } -logService::~logService(){ +logService::~logService() { try { _stdConsoleRedirector.reset(); _qtRediretor.reset(); _logToQtWidget.reset(); qtLogger.reset(); - } catch (const std::exception& e) { + } + catch (const std::exception& e) { // 析构函数中不应抛出异常,只记录错误 qDebug() << "Error in logService destructor:" << e.what(); } -} - -void logService::disableConsole(){ - if (_stdConsoleRedirector) { - _stdConsoleRedirector->eraseSecondCallback(); - } - if (_qtRediretor) { - _qtRediretor->eraseSecondCallback(); - } } \ No newline at end of file diff --git a/src/launcher/logger/logService.h b/src/launcher/logger/logService.h index e3adc0e..86c1606 100644 --- a/src/launcher/logger/logService.h +++ b/src/launcher/logger/logService.h @@ -35,6 +35,7 @@ signals: void mainWindowStdLogSignal(const QString& logMsg); void stdLogSignal(const QString& logMsg); void qtLogSignal(const QString& logMsg); + void loadingWindow_appendConsoleLog(const QString& logMsg); }; class logService : public QThread { @@ -47,8 +48,20 @@ public: static logService* getInstance(); // 禁用控制台输出 - void disableConsole(); - + void disableConsoleOutput(){ + if (_stdConsoleRedirector) { + _stdConsoleRedirector->eraseCallback("console"); + } + if (_qtRediretor) { + _qtRediretor->eraseCallback("console"); + } + } + // 禁用加载界面输出 + void disableLoadingWidgetOutput() { + if (_stdConsoleRedirector) { + _stdConsoleRedirector->eraseCallback("loadingWidget"); + } + } // 获取日志组件 logToQtWidget* getLogWidget() const { return _logToQtWidget.get(); } diff --git a/src/launcher/logger/qtLogRediretor.cpp b/src/launcher/logger/qtLogRediretor.cpp index f3ca370..1d9a12a 100644 --- a/src/launcher/logger/qtLogRediretor.cpp +++ b/src/launcher/logger/qtLogRediretor.cpp @@ -5,8 +5,7 @@ // 全局指针,用于消息处理函数 static qtRediretor* qtRediretor_Ptr = nullptr; -static void qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) -{ +static void qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) { if (!qtRediretor_Ptr) { return; } @@ -21,32 +20,30 @@ static void qtMessageHandler(QtMsgType type, const QMessageLogContext& context, qtRediretor_Ptr->sendMsg(outputMessage); } -qtRediretor::qtRediretor() -{ +qtRediretor::qtRediretor(){ qtRediretor_Ptr = this; qInstallMessageHandler(qtMessageHandler); } -void qtRediretor::registerCallback(CallbackType callback) -{ +void qtRediretor::registerCallback(std::string key,CallbackType callback) { std::lock_guard lock(consoleLock); - callbacks.push_back(callback); + callbacks.insert(std::make_pair(key,callback)); } -void qtRediretor::sendMsg(const QString& msg) -{ +void qtRediretor::sendMsg(const QString& msg){ + std::lock_guard lock(consoleLock); for (const auto& callback : callbacks) { - if (callback) { - callback(msg); + if (callback.second) { + callback.second(msg); } } } -void qtRediretor::eraseSecondCallback() -{ +void qtRediretor::eraseCallback(std::string key) { + std::lock_guard lock(consoleLock); if (callbacks.size() > 1) { - callbacks.erase(callbacks.begin() + 1, callbacks.end()); + callbacks.erase(key); } } \ No newline at end of file diff --git a/src/launcher/logger/qtLogRediretor.h b/src/launcher/logger/qtLogRediretor.h index ddb9a25..7920e03 100644 --- a/src/launcher/logger/qtLogRediretor.h +++ b/src/launcher/logger/qtLogRediretor.h @@ -7,17 +7,16 @@ #include #include -class qtRediretor -{ +class qtRediretor{ public: qtRediretor(); ~qtRediretor() = default; using CallbackType = std::function; - void registerCallback(CallbackType callback); + void registerCallback(std::string key, CallbackType callback); void sendMsg(const QString& msg); - void eraseSecondCallback(); + void eraseCallback(std::string key); // 禁用拷贝构造和赋值操作 qtRediretor(const qtRediretor&) = delete; @@ -25,5 +24,5 @@ public: private: std::mutex consoleLock; - std::vector callbacks; + std::map callbacks; }; \ No newline at end of file diff --git a/src/launcher/logger/stdLogRediretor.hpp b/src/launcher/logger/stdLogRediretor.hpp index 3f7b933..a4eeb96 100644 --- a/src/launcher/logger/stdLogRediretor.hpp +++ b/src/launcher/logger/stdLogRediretor.hpp @@ -56,17 +56,17 @@ public: } } - void registerCallback(CallbackType callback) { + void registerCallback(std::string key,CallbackType callback) { if (callback) { std::lock_guard lock(consoleLock); - callbacks.push_back(callback); + callbacks.insert(std::make_pair(key,callback)); } } - void eraseSecondCallback() { + void eraseCallback(std::string key) { std::lock_guard lock(consoleLock); - if (callbacks.size() > 1) { - callbacks.erase(callbacks.begin() + 1, callbacks.end()); + if (callbacks.size() >= 1) { + callbacks.erase(key); } } @@ -121,12 +121,12 @@ private: std::ostream& originalStream; std::streambuf* originalBuffer; std::string buffer; - std::vector callbacks; + std::map callbacks; mutable std::recursive_mutex consoleLock; // 使用递归锁 // 异步处理相关 std::thread asyncThread; - std::queue>> asyncQueue; + std::queue>> asyncQueue; std::mutex asyncMutex; std::condition_variable asyncCondition; std::atomic stopAsyncThread; @@ -157,12 +157,12 @@ private: // 执行回调函数 const std::string& bufferContent = item.first; - const std::vector& callbackList = item.second; + const std::map& callbackList = item.second; for (const auto& callback : callbackList) { - if (callback) { + if (callback.second) { try { - callback(bufferContent); + callback.second(bufferContent); } catch (...) { // 忽略回调函数中的异常,防止影响其他回调 } @@ -185,7 +185,7 @@ private: if (asyncProcessingEnabled && !callbacks.empty()) { // 异步处理回调函数 - std::vector callbacksCopy = callbacks; + auto callbacksCopy = callbacks; { std::lock_guard lock(asyncMutex); asyncQueue.emplace(std::move(bufferCopy), std::move(callbacksCopy)); @@ -194,9 +194,9 @@ private: } else { // 同步处理(用于关闭时或禁用异步时) for (const auto& callback : callbacks) { - if (callback) { + if (callback.second) { try { - callback(bufferCopy); + callback.second(bufferCopy); } catch (...) { // 忽略回调函数中的异常 } diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index ddb28c3..6bb6059 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -116,11 +116,12 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* _MainWindow->_logWidget, &logWidget::recvQtLogMsg); QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::mainWindowStdLogSignal, _MainWindow->_displayWidget, &displayWidget::recvMainWindowStdLogMsg); - + QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::loadingWindow_appendConsoleLog, + _MainWindow, [=](const QString& text) {_MainWindow->_loadingWidget.appendConsoleLog(text); }); //BackEnd To Front //等待界面 - QObject::connect(bridge, &qtFuncBridge::loadingWindow_appendLog, - _MainWindow, [=](const QString& text, const QColor& color) {_MainWindow->_loadingWidget.appendLog(text, color); }); + QObject::connect(bridge, &qtFuncBridge::loadingWindow_appendInitLog, + _MainWindow, [=](const QString& text, const QColor& color) {_MainWindow->_loadingWidget.appendInitLog(text, color); }); QObject::connect(bridge, &qtFuncBridge::loadingWindow_modifyLog, _MainWindow, [=](int col, const QString& text, const QColor& color) {_MainWindow->_loadingWidget.modifyLog(col, text, color); }); QObject::connect(bridge, &qtFuncBridge::loadingWindow_clearLog, @@ -219,7 +220,7 @@ int main(int argc, char* argv[]) #if HIDE_CONSOLE if (config.consoleHandle) { ShowWindow(config.consoleHandle, SW_HIDE); - _core._logService->disableConsole(); + _core._logService->disableConsoleOutput(); }// 隐藏控制台窗口 #endif w.registerQuitFunc([&]() { diff --git a/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp b/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp new file mode 100644 index 0000000..8b7200a --- /dev/null +++ b/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp @@ -0,0 +1,303 @@ +#include <581_YuHan_hanhou.h> + +void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint, + bool& silieResult, bool& fanZheResult, + cv::Point offset, handdleAI::pClassification* clsPtr, std::vector& clsImgs){ + + 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 < 50 || originRect.height < 50) + continue; + std::vector clsImgVec = cutImg2ClsVec(rect, src); + std::vector clsRes;//true ok + bool isNg = false; + for (auto& cls : clsImgVec) { + int Result = clsPtr->Evaluate(cls); + if (Result == 1)isNg = true; + clsRes.push_back(Result); + } + clsImgs.insert(clsImgs.end(), clsImgVec.begin(), clsImgVec.end()); + 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){//算法先画 + 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(0.013682); + + 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_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 + out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量 + out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 + 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); + } + + double value1 = out_Distance[0].D(); + double value2 = out_Distance[1].D(); + double value3 = out_Distance[2].D(); + + result.jiErWidth = value1; + result.jiErHeight = value2; + result.hanYin1 = value3; + } + 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.result = false; + return result; + } + result.result = true; + return result; +} +bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address) { + QByteArray plcResult = "2"; + try { +#if 0 + /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ + QString resultTag = "OK"; + Mat srcImage; + srcImage = img2D.clone(); + cv::Mat dstImage; + srcImage.copyTo(dstImage); + cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5); + putTextHusky(dstImage, utf8_to_gbk("AI_OK").c_str(), cv::Point(1800, 50), cv::Scalar(0, 255, 0), 200); + putTextHusky(dstImage, utf8_to_gbk("ALGO_OK").c_str(), cv::Point(1800, 250), cv::Scalar(0, 255, 0), 200); + cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5); + resMat.push_back(dstImage); + addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, resultTag)); + addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, resultTag)); + return true; + /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ +#else + cv::Mat sourceImg = data->oriImgs[0]; + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + + //HALCON异步处理 + cv::Mat hySegResult; + auto futrue = std::async(std::launch::async, halconAlgoProcess, sourceImg, Paint, _detParams->segHanYinZhuaQu, std::ref(hySegResult));//异步执行 + + //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(rect.x * resizeRate, rect.y * resizeRate), _detParams->clsHanHou, clsImgs); + + //等待halcon算法完成 + futrue.wait(); + 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(4000, 50), cv::Scalar(0, 255, 0)); + } + else { + textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(4000, 50), cv::Scalar(0, 255, 0)); + plcResult = "2"; + data->aiDetOK = false; + } + if (halconResult.result == true) { + textPainter.putText(Paint, "算法OK", cv::Point(4000, 350), cv::Scalar(0, 255, 0)); + } + else { + textPainter.putText(Paint, "算法NG", cv::Point(4000, 350), cv::Scalar(0, 255, 0)); + plcResult = "2"; + data->halconOK = false; + } + + plcResult = "1"; silieResultText = "1"; fanzheResultText = "1"; + 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.hanYin1));//发送数据-芯包顶部到焊印的距离 + + textPainter.putText(Paint, "极耳宽度" + std::to_string(halconResult.jiErWidth), cv::Point(100, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "极耳高度" + std::to_string(halconResult.jiErHeight), cv::Point(100, 300), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "焊印上边缘到极耳上边缘高度" + std::to_string(halconResult.hanYin1), cv::Point(100, 550), cv::Scalar(0, 255, 0)); + + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + return true; +#endif + } + CATCH_EXCEPTIONS + + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, "NG", cv::Point(100, 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 hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address) { + QByteArray plcResult = "2"; + try{ +#if 0 + /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ + QString resultTag = "OK"; + Mat srcImage; + srcImage = img2D.clone(); + cv::Mat dstImage; + srcImage.copyTo(dstImage); + cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5); + putTextHusky(dstImage, utf8_to_gbk("AI_OK").c_str(), cv::Point(1800, 50), cv::Scalar(0, 255, 0), 200); + cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5); + resMat.push_back(dstImage); + addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, resultTag)); + addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, resultTag)); + return true; + /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ + +#else + //存图数据加保存队列,加锁,避免数据访问冲突 + cv::Mat sourceImg = data->oriImgs[0]; + 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缺陷检测 + cv::Mat SegRes = ~_detParams->segHanHou->Evaluate(matDet); + bool silieOk = true, fanZheOk = true; + std::vector clsImgs; + handleAiProcess(sourceImg, SegRes, Paint, silieOk, fanZheOk, cv::Point(rect.x * resizeRate, rect.y * resizeRate), _detParams->clsHanHou, clsImgs); + QString okNgSaveText = "OK"; + QByteArray silieResultText = silieOk == true ? "1" : "2"; + QByteArray fanzheResultText = fanZheOk == true ? "1" : "2"; + plcResult = "1"; + TextRendererZH textPainter(Paint.cols, Paint.rows, 200); + if (silieOk == true && fanZheOk == true) {//OK + textPainter.putText(Paint, "OK", cv::Point(3000, 50), cv::Scalar(0, 255, 0)); + } + else { + textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(3000, 50), cv::Scalar(0, 255, 0)); + plcResult = "2"; + data->aiDetOK = false; + } + plcResult = "1"; + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + return true; +#endif + } + CATCH_EXCEPTIONS + + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, "NG", cv::Point(100, 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; +} + + + + + +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_YuHan_hanhou/581_YuHan_hanhou.h b/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.h new file mode 100644 index 0000000..534b313 --- /dev/null +++ b/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.h @@ -0,0 +1,114 @@ +#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; + bool isTong = true; +}; +struct halconResult { + bool result = true; + double jiErWidth = -1; + double jiErHeight = -1; + double hanYin1 = -1; +}; +void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint, + bool& silieResult, bool& fanZheResult, + cv::Point offset, handdleAI::pClassification* clsPtr, std::vector& clsImgs); +halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegmentation* seg_hanYinZhuaQu, cv::Mat& segResult); +bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); +bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); + +namespace hanhou45{ + +} +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; + 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); + + 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); + } + initOnce = true; + } + } + 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_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_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; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581_YuHan_hanhou/CMakeLists.txt b/src/mission/581_YuHan_hanhou/CMakeLists.txt new file mode 100644 index 0000000..bba2e81 --- /dev/null +++ b/src/mission/581_YuHan_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_YuHan_hanqian/581_YuHan_hanqian.h b/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h index d0ca3b1..759538a 100644 --- a/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h +++ b/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h @@ -8,10 +8,11 @@ using namespace HDevEngineCpp; #pragma endregion class yuHanHanQianParams { public: - handleAiModelSeg* segDingWei = nullptr; + handdleAI::pSegmentation* segDingWei = nullptr; - handleAiModelSeg* segJiErFanZhe = nullptr; - handleAiModelCls* clsJiErFanZhe = nullptr; + handdleAI::pSegmentation* segJiErFanZhe = nullptr; + handdleAI::pClassification* clsJiErFanZhe = nullptr; + bool isTong = true; }; void halconProcess(cv::Mat& sourceImg, cv::Mat& Paint) { try { @@ -158,14 +159,14 @@ bool jiErFanZhe(std::shared_ptr data, yuHanHanQianParams* _detParams, sourceImg.copyTo(Paint); if (Paint.channels() == 1) cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); - halconProcess(sourceImg, Paint); + //halconProcess(sourceImg, Paint); float resizeRate = 5.0; - auto rect = getImageLocateRect(sourceImg, _detParams->segDingWei->segPtr, 1.0 / resizeRate);//定位 + 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_saveImg; if (rect.width > 500 || rect.height > 500) { - isNG = handleAiProcess(sourceImg(rect), Paint(rect), _detParams->segJiErFanZhe->segPtr, _detParams->clsJiErFanZhe->clsPtr, data->clsOriginImgs); + isNG = handleAiProcess(sourceImg(rect), Paint(rect), _detParams->segJiErFanZhe, _detParams->clsJiErFanZhe, data->clsOriginImgs); cv::rectangle(Paint, rect, cv::Scalar(0, 255, 255), 3); cv::resize(sourceImg(rect), seg_saveImg, cv::Size(), 0.5, 0.5); } @@ -173,15 +174,15 @@ bool jiErFanZhe(std::shared_ptr data, yuHanHanQianParams* _detParams, isNG = true; } QString okNgSaveText = "NG"; - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); if (isNG == false)//OK { - textPainter.putText(Paint, "OK", cv::Point(1000, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "OK", cv::Point(100, 50), cv::Scalar(0, 255, 0)); okNgSaveText = "OK"; } else { - textPainter.putText(Paint, "NG", cv::Point(1000, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 255, 0)); data->aiDetOK = false; plcResult = "2"; } @@ -189,11 +190,12 @@ bool jiErFanZhe(std::shared_ptr data, yuHanHanQianParams* _detParams, data->resultImgs.push_back(Paint); sourceImg.release(); data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + return true; #endif } CATCH_EXCEPTIONS - - qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + + qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode); cv::Mat Paint; data->oriImgs[0].copyTo(Paint); if (Paint.channels() == 1) @@ -216,33 +218,39 @@ public: _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; - yuHanHanQianParams tongDetParams; - yuHanHanQianParams lvDetParams; + 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_602.hdpl"); - - tongDetParams.segDingWei = _serviceManager->_handleAiModelManager->getSegModel("segDingWei_GPU0"); - tongDetParams.segJiErFanZhe = _serviceManager->_handleAiModelManager->getSegModel("segTongJiErFanZhe_GPU0"); - tongDetParams.clsJiErFanZhe = _serviceManager->_handleAiModelManager->getClsModel("clsTongJiErFanZhe_GPU0"); - - - lvDetParams.segDingWei = _serviceManager->_handleAiModelManager->getSegModel("clsLvJiErFanZhe_GPU1"); - lvDetParams.segJiErFanZhe = _serviceManager->_handleAiModelManager->getSegModel("segLvJiErFanZhe_GPU1"); - lvDetParams.clsJiErFanZhe = _serviceManager->_handleAiModelManager->getClsModel("clsLvJiErFanZhe_GPU1"); + 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; + } + initOnce = true; + } } bool initCustom() { #pragma region 注册触发器回调 - in_lv_top_1.init("Camera1", "极耳翻折-铝-内-相机1(顶部)", { { 522, 1,540,"523","530",-1} }, 1, tongDetParams, _serviceManager, bridge, jiErFanZhe); - in_lv_down_2.init("Camera2", "极耳翻折-铝-内-相机2(底部)", { { 524, 1,620,"525","532",-1} }, 1, tongDetParams, _serviceManager, bridge, jiErFanZhe); - in_tong_top_3.init("Camera3", "极耳翻折-铜-内-相机3(顶部)", { { 526,1,540,"527","534",-1} }, 1, tongDetParams, _serviceManager, bridge, jiErFanZhe); - in_tong_down_4.init("Camera4", "极耳翻折-铜-内-相机4(底部)", { { 528, 1,620,"529","536",-1} }, 1, tongDetParams, _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(顶部)", { { 562,1,580,"563","570",-1} }, 1, lvDetParams, _serviceManager, bridge, jiErFanZhe); - out_lv_down_6.init("Camera6", "极耳翻折-铝-外-相机6(底部)", { { 564, 1,660,"565","572",-1} }, 1, lvDetParams, _serviceManager, bridge, jiErFanZhe); - out_tong_top_7.init("Camera7", "极耳翻折-铜-外-相机7(顶部)", { { 566, 1,580,"567","574",-1} }, 1, lvDetParams, _serviceManager, bridge, jiErFanZhe); - out_tong_down_8.init("Camera8", "极耳翻折-铜-外-相机8(底部)", { { 568, 1,660,"569","576",-1} }, 1, lvDetParams, _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; }