#pragma once #include #include #include #include #include #pragma region 基础函数 #define CATCH_EXCEPTIONS \ catch (HDevEngineCpp::HDevEngineException& ex) { \ std::cout << "HDevEngineException: " << ex.Message() << std::endl; \ qDebug() << "HDevEngineException: " << ex.Message(); \ } \ catch (HalconCpp::HException& ex) { \ std::cout << "Halcon Exception Caught!" << std::endl; \ std::cout << "Error Code: " << ex.ErrorCode() << std::endl; \ std::cout << "Error Message: " << ex.ErrorMessage() << std::endl; \ qDebug() << "Halcon Exception Caught!"; \ qDebug() << "Error Code: " << ex.ErrorCode(); \ qDebug() << "Error Message: " << ex.ErrorMessage(); \ } \ catch (const std::exception& e) { \ std::cout << "Caught exception: " << e.what() << std::endl; \ qDebug() << "Caught exception: " << e.what(); \ } struct yh_581_address { int triggerAddr = -1; int snAddr = -1; QByteArray completeAddr = "-1"; QByteArray resultAddr = "-1"; int valueOffsetAddr = -1; }; static yh_581_address generateYh581Address(int startAddr, int offset) {//INPUT:开始地址/电芯地址偏移(0~3) return yh_581_address{ startAddr + offset * 2, startAddr + 10 + offset * 22 , QByteArray::number(startAddr + 98 + offset * 2), QByteArray::number(startAddr + 106 + offset * 2), startAddr + 114 + offset * 20 }; } static std::map generateYh581AddressMap(int startAddr, int cnt) {//INPUT:开始地址/0~3) 数量 std::map result; for (auto i = 0; i < cnt; i++) { result[i] = generateYh581Address(startAddr, i); } return result; } class detParams { public: }; #pragma endregion //算法回调函数需要包含完整的算法流程以及发送信号,发送ui图表,捕获异常,处理异常等操作 //并且注意 异常可能会导致运行不到发送信号的函数,请在处理异常时发送异常结果 static bool generalAlgoTest(std::shared_ptr data, detParams* _detParams, yh_581_address address) { try { qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; std::vector < std::string> defects = {"测试"}; ///////////////////取图//处理////////////////// if (data->oriImgs.size() < 1) { qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); return false; } if (data->oriImgs[0].rows == 100) { cv::Mat Paint; data->oriImgs[0].copyTo(Paint); cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); return false; } cv::Mat Paint; QMutex paintMutex; clock_t start, finish; start = clock(); cv::Mat src1 = data->oriImgs[0]; if (src1.channels() != 3) cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); else src1.copyTo(Paint); TextRendererZH textPainter(Paint.cols, Paint.rows, 15); textPainter.putText(Paint, "划伤", cv::Point(10,10), cv::Scalar(0, 255, 0)); cv::putText(Paint, "pos:" + data->additional["触发地址"].toString().toStdString(), cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 0, 0), 2); data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 data->service->_missionResultHandle->handleAllResult(data->SNcode, !defects.size() > 0, defects);//发送图标操作 data->resultImgs.push_back(Paint); return true; } CATCH_EXCEPTIONS data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送异常结果 return false; } template //此类适用于单相机多触发地址需要联合判断的情况的情况 比如顶盖焊,包膜,入壳机台 //例触发地址有4个,输入信号为 1 0 0 1 则触发1和4的地址拍照检测,2和3拍照取图并废弃 class _581_Union_triggerTemplate { public: paramTemplte _detParams; detCallbackChain* generalDet; std::string cameraName; QString viewerName; std::mapaddress; /// /// 初始化 /// /// 相机名 /// 窗口名 /// 开始地址 /// 触发信号数 /// 单次触发调用几次相机模块 /// 参数输入 /// 默认 /// 默认 /// 算法函数 /// void init(std::string cameraNameIn, QString viewerNameIN, int startAddr, int triggerCount,int oneTriggerCaptrueTimes, paramTemplte& detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn, typename detCallbackChain::processAlgoCallback _processAlgoCallback, QString saveObjectNameIN = "") { viewerName = viewerNameIN; cameraName = cameraNameIn; _serviceManager = _serviceManagerIn; _detParams = detParamsIn; bridge = bridgeIn; saveObjectName = saveObjectNameIN; generalDet = new detCallbackChain(_serviceManager, &_detParams, bridge); generalDet->registerProcessAlgoCallback(_processAlgoCallback); address = generateYh581AddressMap(startAddr, triggerCount); //联合触发器条件 std::vector> conditions; for (int i = 0; i < triggerCount; i++) { conditions.push_back(std::make_pair(address[i].triggerAddr, 1)); //注册清除完成信号触发器 任意触发地址归零时触发一次 _serviceManager->_triggerManager->registerCallback(address[i].triggerAddr, 0, [this, i](int triggerPos, int triggerValue, QByteArray& byteArray) {_serviceManager->_triggerManager->writeShort("D" + address[0].completeAddr + "_0"); }, "D" + address[0].completeAddr.toStdString() + "清零"); } //注册联合触发器 任意触发地址置1时触发 _serviceManager->_triggerManager->registerUnionCallback(conditions, triggerManager::conditionMode::or ,[this](std::vector> vals, QByteArray& byteArray){ int cnt = 0; for (auto& val : vals) { if (val.second == 1) evaluate(cnt, byteArray); else captrueAndDiscard(); cnt++; } }, ""); } //获取图片并进行检测 void evaluate(int batteryOffset, QByteArray& byteArray) { _serviceManager->_triggerManager->writeShort("D" + address[0].completeAddr + "_1");//完成信号 固定只发在第0位 std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, address[batteryOffset].snAddr, false, false, -1); auto camera = _serviceManager->_cameraManager->getCamera(cameraName); camera->clearCache(); std::shared_ptr data = _serviceManager->_detDataManager->createDetData( QString::fromStdString(cameraName), sn, 1, camera->config.oriSaveFormat);//创建数据包 camera->captureImage(data);//拍照 data->saveObjectName = saveObjectName; generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); } //获取图片然后废弃 void captrueAndDiscard() { auto camera = _serviceManager->_cameraManager->getCamera(cameraName); std::shared_ptr data = _serviceManager->_detDataManager->createDetData();//创建数据包 camera->captureImage(data);//拍照 _serviceManager->_detDataManager->deleteDetData(data->uuid); } private: QString saveObjectName = ""; qtFuncBridge* bridge; ServiceManager* _serviceManager = nullptr; }; template //此类适用于单相机多触发地址单次判断的情况,比如密封钉,三协机台 //例触发地址有4个,输入信号为 1 0 0 1 则按顺序触发1和4的地址拍照检测,2和3不做处理 class _581_Single_triggerTemplate { public: paramTemplte2 _detParams; detCallbackChain* generalDet; std::string cameraName; QString viewerName; std::mapaddress; /// /// 初始化 /// /// 相机名 /// 窗口名 /// 开始地址 /// 触发信号数 /// 单次触发调用几次相机模块 /// 参数输入 /// 默认 /// 默认 /// 算法函数 /// void init(std::string cameraNameIn, QString viewerNameIN, int startAddr, int triggerCount, int oneTriggerCaptrueTimes, paramTemplte2& detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn, typename detCallbackChain::processAlgoCallback _processAlgoCallback, QString saveObjectNameIN = "") { viewerName = viewerNameIN; cameraName = cameraNameIn; _serviceManager = _serviceManagerIn; _detParams = detParamsIn; bridge = bridgeIn; saveObjectName = saveObjectNameIN; generalDet = new detCallbackChain(_serviceManager, &_detParams, bridge); generalDet->registerProcessAlgoCallback(_processAlgoCallback); address = generateYh581AddressMap(startAddr, triggerCount); //单次触发器条件 for (int i = 0; i < triggerCount; i++) { //注册单触发器 触发地址置1时触发 _serviceManager->_triggerManager->registerCallback(address[i].triggerAddr, 1, [this, i](int triggerPos, int triggerValue, QByteArray& byteArray) { evaluate(i, byteArray);}, ""); //注册清除完成信号触发器 任意触发地址归零时触发一次 _serviceManager->_triggerManager->registerCallback(address[i].triggerAddr, 0, [this, i](int triggerPos, int triggerValue, QByteArray& byteArray) { _serviceManager->_triggerManager->writeShort("D" + address[0].completeAddr + "_0"); }, "D" + address[0].completeAddr.toStdString() + "清零"); } } //获取图片并进行检测 void evaluate(int batteryOffset, QByteArray& byteArray) { _serviceManager->_triggerManager->writeShort("D" + address[0].completeAddr + "_1");//完成信号 固定只发在第0位 std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, address[batteryOffset].snAddr, false, false, -1); auto camera = _serviceManager->_cameraManager->getCamera(cameraName); camera->clearCache(); std::shared_ptr data = _serviceManager->_detDataManager->createDetData( QString::fromStdString(cameraName), sn, 1, camera->config.oriSaveFormat);//创建数据包 camera->captureImage(data);//拍照 data->saveObjectName = saveObjectName; generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); } private: QString saveObjectName = ""; qtFuncBridge* bridge; ServiceManager* _serviceManager = nullptr; };