#include "VrBeltTearingConfig.h" #include "IVrBeltTearingConfig.h" #include "tinyxml2.h" #include #include #include "VrLog.h" #include #include #include using namespace tinyxml2; VrBeltTearingConfig::VrBeltTearingConfig() : m_notify(nullptr) { } VrBeltTearingConfig::~VrBeltTearingConfig() { } // Also add the static CreateInstance method to the interface class bool IVrBeltTearingConfig::CreateInstance(IVrBeltTearingConfig** ppVrConfig) { if (!ppVrConfig) { return false; } *ppVrConfig = new VrBeltTearingConfig(); return true; } BeltTearingConfigResult VrBeltTearingConfig::LoadConfig(const std::string& filePath) { BeltTearingConfigResult result; // 使用QString处理可能包含中文的路径 QString qFilePath = QString::fromStdString(filePath); QFile file(qFilePath); // 检查文件是否存在并可读 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { LOG_DEBUG("Failed to open file: %s\n", filePath.c_str()); return result; } // 读取文件内容 QTextStream in(&file); // 设置编码为UTF-8以正确处理中文 in.setCodec("UTF-8"); QString content = in.readAll(); file.close(); // 使用tinyxml2解析XML内容 XMLDocument doc; XMLError error = doc.Parse(content.toUtf8().constData()); if (error != XML_SUCCESS) { LOG_ERROR("tinyxml2 load file error : %d \n", error); return result; } XMLElement* root = doc.RootElement(); if (!root) { return result; } // 加载服务器配置 XMLElement* serversElem = root->FirstChildElement("Servers"); if (serversElem) { XMLElement* serverElem = serversElem->FirstChildElement("Server"); while (serverElem) { ServerInfo server; server.name = serverElem->Attribute("name") ? serverElem->Attribute("name") : ""; server.ip = serverElem->Attribute("ip") ? serverElem->Attribute("ip") : ""; server.port = serverElem->IntAttribute("port", 5000); result.servers.push_back(server); serverElem = serverElem->NextSiblingElement("Server"); } } // 加载算法参数 XMLElement* algoParamsElem = root->FirstChildElement("AlgorithmParams"); if (algoParamsElem) { // 皮带撕裂参数 XMLElement* beltTearingElem = algoParamsElem->FirstChildElement("BeltTearingParam"); if (beltTearingElem) { result.algorithmParams.beltTearingParam.tearThreshold = beltTearingElem->DoubleAttribute("TearThreshold", 50.0); result.algorithmParams.beltTearingParam.minTearLength = beltTearingElem->DoubleAttribute("MinTearLength", 100.0); result.algorithmParams.beltTearingParam.maxTearWidth = beltTearingElem->DoubleAttribute("MaxTearWidth", 30.0); } // 图像处理参数 XMLElement* imageProcElem = algoParamsElem->FirstChildElement("ImageProcessingParam"); if (imageProcElem) { result.algorithmParams.imageProcessingParam.blurSize = imageProcElem->IntAttribute("BlurSize", 5); result.algorithmParams.imageProcessingParam.cannyThreshold1 = imageProcElem->IntAttribute("CannyThreshold1", 50); result.algorithmParams.imageProcessingParam.cannyThreshold2 = imageProcElem->IntAttribute("CannyThreshold2", 150); result.algorithmParams.imageProcessingParam.morphologySize = imageProcElem->IntAttribute("MorphologySize", 3); } // 监控参数 XMLElement* monitoringElem = algoParamsElem->FirstChildElement("MonitoringParam"); if (monitoringElem) { result.algorithmParams.monitoringParam.checkInterval = monitoringElem->IntAttribute("CheckInterval", 1000); result.algorithmParams.monitoringParam.alertThreshold = monitoringElem->IntAttribute("AlertThreshold", 3); result.algorithmParams.monitoringParam.maxHistorySize = monitoringElem->IntAttribute("MaxHistorySize", 100); } } // 加载调试参数 XMLElement* debugElem = root->FirstChildElement("DebugParam"); if (debugElem) { result.debugParam.enableDebug = debugElem->BoolAttribute("enableDebug", false); result.debugParam.saveDebugImage = debugElem->BoolAttribute("saveDebugImage", false); result.debugParam.printDetailLog = debugElem->BoolAttribute("printDetailLog", false); const char* debugPath = debugElem->Attribute("debugOutputPath"); if (debugPath) { result.debugParam.debugOutputPath = debugPath; } } // 加载项目类型 XMLElement* projectTypeElem = root->FirstChildElement("ProjectType"); if (projectTypeElem) { const char* typeStr = projectTypeElem->Attribute("type"); if (typeStr && std::string(typeStr) == "BeltMonitoring") { result.projectType = BeltTearingProjectType::BeltMonitoring; } else { result.projectType = BeltTearingProjectType::BeltTearing; } } return result; } bool VrBeltTearingConfig::SaveConfig(const std::string& filePath, BeltTearingConfigResult& configResult) { XMLDocument doc; // 创建根元素 XMLElement* root = doc.NewElement("BeltTearingConfig"); doc.InsertEndChild(root); // 保存服务器配置 if (!configResult.servers.empty()) { XMLElement* serversElem = doc.NewElement("Servers"); root->InsertEndChild(serversElem); for (const auto& server : configResult.servers) { XMLElement* serverElem = doc.NewElement("Server"); serverElem->SetAttribute("name", server.name.c_str()); serverElem->SetAttribute("ip", server.ip.c_str()); serverElem->SetAttribute("port", server.port); serversElem->InsertEndChild(serverElem); } } // 保存算法参数 XMLElement* algoParamsElem = doc.NewElement("AlgorithmParams"); root->InsertEndChild(algoParamsElem); // 皮带撕裂参数 XMLElement* beltTearingElem = doc.NewElement("BeltTearingParam"); beltTearingElem->SetAttribute("TearThreshold", configResult.algorithmParams.beltTearingParam.tearThreshold); beltTearingElem->SetAttribute("MinTearLength", configResult.algorithmParams.beltTearingParam.minTearLength); beltTearingElem->SetAttribute("MaxTearWidth", configResult.algorithmParams.beltTearingParam.maxTearWidth); algoParamsElem->InsertEndChild(beltTearingElem); // 图像处理参数 XMLElement* imageProcElem = doc.NewElement("ImageProcessingParam"); imageProcElem->SetAttribute("BlurSize", configResult.algorithmParams.imageProcessingParam.blurSize); imageProcElem->SetAttribute("CannyThreshold1", configResult.algorithmParams.imageProcessingParam.cannyThreshold1); imageProcElem->SetAttribute("CannyThreshold2", configResult.algorithmParams.imageProcessingParam.cannyThreshold2); imageProcElem->SetAttribute("MorphologySize", configResult.algorithmParams.imageProcessingParam.morphologySize); algoParamsElem->InsertEndChild(imageProcElem); // 监控参数 XMLElement* monitoringElem = doc.NewElement("MonitoringParam"); monitoringElem->SetAttribute("CheckInterval", configResult.algorithmParams.monitoringParam.checkInterval); monitoringElem->SetAttribute("AlertThreshold", configResult.algorithmParams.monitoringParam.alertThreshold); monitoringElem->SetAttribute("MaxHistorySize", configResult.algorithmParams.monitoringParam.maxHistorySize); algoParamsElem->InsertEndChild(monitoringElem); // 保存调试参数 XMLElement* debugElem = doc.NewElement("DebugParam"); debugElem->SetAttribute("enableDebug", configResult.debugParam.enableDebug); debugElem->SetAttribute("saveDebugImage", configResult.debugParam.saveDebugImage); debugElem->SetAttribute("printDetailLog", configResult.debugParam.printDetailLog); debugElem->SetAttribute("debugOutputPath", configResult.debugParam.debugOutputPath.c_str()); root->InsertEndChild(debugElem); // 保存项目类型 XMLElement* projectTypeElem = doc.NewElement("ProjectType"); projectTypeElem->SetAttribute("type", configResult.projectType == BeltTearingProjectType::BeltMonitoring ? "BeltMonitoring" : "BeltTearing"); root->InsertEndChild(projectTypeElem); // 使用QString处理可能包含中文的路径 QString qFilePath = QString::fromStdString(filePath); QFile file(qFilePath); // 打开文件进行写入 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { LOG_DEBUG("Failed to open file for writing: %s\n", filePath.c_str()); return false; } // 将XML内容写入文件 QTextStream out(&file); // 设置编码为UTF-8以正确处理中文 out.setCodec("UTF-8"); XMLPrinter printer; doc.Print(&printer); out << printer.CStr(); file.close(); return true; } void VrBeltTearingConfig::SetConfigChangeNotify(IVrBeltTearingConfigChangeNotify* notify) { m_notify = notify; }