#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 sx_581_address { int triggerAddr = -1; int triggerValue = -1; int snAddr; QByteArray completeAddr = "-1"; QByteArray resultAddr = "-1"; int valueOffsetAddr = -1; }; class detParams { public: }; #pragma endregion //算法回调函数需要包含完整的算法流程以及发送信号,发送ui图表,捕获异常,处理异常等操作 //并且注意 异常可能会导致运行不到发送信号的函数,请在处理异常时发送异常结果 static bool generalAlgoTest(std::shared_ptr data, detParams* _detParams, sx_581_address address) { try { qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; std::vector < std::string> defects = {"测试"}; ///////////////////取图//处理////////////////// if (data->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_SX_Single_triggerTemplate { public: paramTemplte* _detParams; detCallbackChain* generalDet; std::string cameraName; QString viewerName; std::vectoraddress; /// /// 初始化 /// /// 相机名 /// 窗口名 /// 开始地址 /// 触发信号数 /// 单次触发调用几次相机模块 /// 参数输入 /// 默认 /// 默认 /// 算法函数 /// void init(std::string cameraNameIn, QString viewerNameIN, std::vector addressIN, int oneTriggerCaptrueTimes, paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn, typename detCallbackChain::processAlgoCallback _processAlgoCallback, QString saveObjectNameIN = "") { viewerName = viewerNameIN; cameraName = cameraNameIn; _serviceManager = _serviceManagerIn; _detParams = detParamsIn; bridge = bridgeIn; address = addressIN; saveObjectName = saveObjectNameIN; generalDet = new detCallbackChain(_serviceManager, _detParams, bridge); generalDet->registerProcessAlgoCallback(_processAlgoCallback); //单次触发器条件 for (int i = 0; i < addressIN.size(); i++) { //注册单触发器 触发地址置1时触发 _serviceManager->_triggerManager->registerCallback(address[i].triggerAddr, address[i].triggerValue, [this, i](int triggerPos, int triggerValue, QByteArray& byteArray) { evaluate(i, byteArray);}, ""); } for (int i = 0; i < address.size(); i++) { _serviceManager->_triggerManager->registerPlcValueViewer(viewerNameIN + "_" + QString::number(i), { {"触发",address[i].triggerAddr }, {"反馈",address[i].completeAddr.toInt()}, {"结果",address[i].resultAddr.toInt()}, {"数值1",address[i].valueOffsetAddr}, {"数值2",address[i].valueOffsetAddr + 2}, {"数值3",address[i].valueOffsetAddr + 4} }); } } //获取图片并进行检测 void evaluate(int batteryOffset, QByteArray& byteArray) { _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(address[0].triggerAddr) + "_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], ("D" + address[0].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); } private: QString saveObjectName = ""; qtFuncBridge* bridge; ServiceManager* _serviceManager = nullptr; };