#include "LandslideAssess.h" #include LandslideAssess::LandslideAssess() { //ui.setupUi(this); } QString LandslideAssess::PannelName() { return QString::fromLocal8Bit("地质模块"); } QString LandslideAssess::CategoryName() { return QString::fromLocal8Bit("地质模块"); } QString LandslideAssess::EnglishName() { return QString::fromLocal8Bit("LandslideAssess"); } QString LandslideAssess::ChineseName() { return QString::fromLocal8Bit("结果评估"); } QString LandslideAssess::Information() { return QString::fromLocal8Bit("结果评估"); } QString LandslideAssess::IconPath() { return QString(":/LandslideAssess/resources/assessment.svg"); } QWidget* LandslideAssess::CenterWidget() { QString gdal_path = qApp->applicationDirPath().toLocal8Bit() + "/share/gdal"; QString pro_lib_path = qApp->applicationDirPath().toLocal8Bit() + "/share/proj"; qputenv("GDAL_DATA", gdal_path.toLocal8Bit()); qputenv("PROJ_LIB", pro_lib_path.toLocal8Bit()); bool showWin = false; if (myWidget == nullptr) { myWidget = new QDialog(); showWin = true; qDebug() << "new QDialog()"; } else { qDebug() << "already have myWidget"; //激活窗口并提升至顶层 myWidget->activateWindow(); myWidget->raise(); return myWidget; } ui.setupUi(myWidget); myWidget->setWindowTitle(QString::fromLocal8Bit("结果评估")); myWidget->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); myWidget->setWindowIcon(QIcon(":/LandslideAssess/resources/assessment.svg")); myWidget->setAttribute(Qt::WA_QuitOnClose, false); myWidget->setAttribute(Qt::WA_DeleteOnClose); connect(myWidget, &QDialog::destroyed, this, [=] { qDebug() << "----Landslide assess window close----"; QDir pluginsDir = QDir(qApp->applicationDirPath()); if (pluginsDir.cd("srsplugins\\SldModel")) { QString strConfigPath = pluginsDir.absoluteFilePath("sld_config.ini"); QFile f(strConfigPath); if (f.exists()) { WriteConfigPaths(strConfigPath); f.close(); } } if (mWorkThread != nullptr) { mWorkThread->requestInterruption();//请求线程中断 mWorkThread->quit(); mWorkThread->wait();//调用wait后先调用finished信号对应的槽函数,执行完成后再往下走 mWorker->on_cancel(); mWorkThread = nullptr;//mWorkThread, &QThread::finished, mWorkThread, &QObject::deleteLater,不需要delete mWorker = nullptr;//mWorkThread, &QThread::finished, mWorker, &QObject::deleteLater } //qDebug() << "--destroyed"; myWidget->close(); myWidget = nullptr; }); connect(ui.pbtInDataset, &QPushButton::clicked, this, &LandslideAssess::choosePredictPath); connect(ui.pbtInLabel, &QPushButton::clicked, this, &LandslideAssess::chooseLabelPath); connect(ui.pbtIndex, &QPushButton::clicked, this, &LandslideAssess::chooseAssessFile); connect(ui.pbtInModel, &QPushButton::clicked, this, &LandslideAssess::chooseModelFile); connect(ui.pbtResult, &QPushButton::clicked, this, &LandslideAssess::chooseResultPath); connect(ui.pushButton_ok, &QPushButton::clicked, this, &LandslideAssess::readAndStart); connect(ui.pushButton_cancel, &QPushButton::clicked, this, &LandslideAssess::pbCancel); ui.progressBar->setTextVisible(true); ui.progressBar->setRange(0, 100); ui.pbtInModel->setFocus(); QFile qssFile(":/LandslideAssess/LandslideAssess.qss"); qssFile.open(QFile::ReadOnly); //以只读方式打开 if (qssFile.isOpen()) { QString qss = QLatin1String(qssFile.readAll()); myWidget->setStyleSheet(qss); qssFile.close(); } else qDebug() << "no qssFile"; QDir pluginsDir = QDir(qApp->applicationDirPath()); if (pluginsDir.cd("srsplugins\\SldModel")) { QString strConfigPath = pluginsDir.absoluteFilePath("sld_config.ini"); QFile f(strConfigPath); if (f.exists()) { ReadConfigHistoryPaths(strConfigPath); f.close(); } } if (showWin) myWidget->show(); return myWidget; } void LandslideAssess::startWorkThread() { if (mWorker != nullptr) { return; } mWorkThread = new QThread(); mWorker = new WorkObject(); mWorker->moveToThread(mWorkThread); connect(mWorkThread, &QThread::finished, mWorkThread, &QObject::deleteLater); connect(mWorkThread, &QThread::finished, mWorker, &QObject::deleteLater); connect(mWorker, &WorkObject::progress, myWidget, [=](int value) { ui.progressBar->setValue(value); if (value == 100) { QString txtDir = ui.lineResult->text() + "/assessment.txt"; QFile file(txtDir); QString outLines = ""; if (file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); // recall 召回率 // precision 精确率 // mIoU 平均交并比 // mAP 平均精度均值 // f1_score while (!stream.atEnd()) { QString line = stream.readLine(); //strs.push_back(line); if (line.contains("===>mIoU")) { //===>mIoU:68.45; mAP: 74.92 line.remove("===>"); line.replace(QStringLiteral("mAP"), QStringLiteral("平均精度均值mAP")); line.replace(QStringLiteral("mIoU"), QStringLiteral("平均交并比mIoU")); outLines = outLines + line + "\n"; } else if (line.contains("===>recall")) { //===>recall:66.62; precision: 51.2 line.remove("===>"); line.replace(QStringLiteral("recall"), QStringLiteral("召回率recall")); line.replace(QStringLiteral("precision"), QStringLiteral("精确率precision")); outLines = outLines + line + "\n"; } else if (line.contains("===>f1_score")) { //===>f1_score:57.9 line.remove("===>"); line.replace(QStringLiteral("f1_score"), QStringLiteral("F1分数f1_score")); outLines = outLines + line; } } file.close(); } QMessageBox mess(QMessageBox::Information, QString::fromLocal8Bit("评估结束"), QString::fromLocal8Bit("评价结果:\n") + txtDir + "\n" + outLines); mess.setWindowFlags(Qt::Drawer); mess.setStandardButtons(QMessageBox::Yes); mess.button(QMessageBox::StandardButton::Yes)->setText(QString::fromLocal8Bit("确认")); int result = mess.exec(); pbCancel(); } }); connect(this, &LandslideAssess::startPreAssessment, mWorker, &WorkObject::runAssessWork); mWorkThread->start(); } void LandslideAssess::ReadConfigHistoryPaths(QString strPath) { QSettings configIni(strPath, QSettings::IniFormat); //打开标题为:[DemTrain] 的组,读取DemTrain输出结果TrainResult字段 configIni.beginGroup("SldTrain"); QString strDemTrainResult = configIni.value("TrainResult").toString(); QDir srcDir = QDir(strDemTrainResult); //更新评价文件列表 if (srcDir.absoluteFilePath("val_list.txt") != "") ui.lineIndex->setText(srcDir.absoluteFilePath("val_list.txt")); //更新输入Images srcDir = QDir(strDemTrainResult); if (srcDir.cd("Images")) ui.lineInDataset->setText(srcDir.absolutePath()); //更新输入Labels srcDir = QDir(strDemTrainResult); if (srcDir.cd("Labels")) ui.lineInLabel->setText(srcDir.absolutePath()); configIni.endGroup();//关闭组 //打开标题为:[DemAssess] 的组,读取AssessResult字段 configIni.beginGroup("SldAssess"); //更新评价结果输出 ui.lineResult->setText(configIni.value("AssessResult").toString()); configIni.endGroup();//关闭组 } void LandslideAssess::WriteConfigPaths(QString strPath) { QSettings configIni(strPath, QSettings::IniFormat); configIni.setIniCodec("utf-8"); //打开标题为:[DemAssess] 的组 configIni.beginGroup("SldAssess"); //更新输入模型路径 QString temp = ui.lineResult->text(); if (temp != "") configIni.setValue("AssessResult", temp); configIni.endGroup();//关闭组 } void LandslideAssess::readAndStart() { QString dirModel = ui.lineInModel->text(); QString dirIndex = ui.lineIndex->text(); QString dirLabel = ui.lineInLabel->text(); QString dirPredict = ui.lineInDataset->text(); QString dirResult = ui.lineResult->text(); ui.progressBar->setValue(0); if (dirLabel == "" || dirPredict == "" || dirIndex == "" || dirModel == "" || dirResult == "") { QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("请检查输入路径")); mess.setWindowFlags(Qt::Drawer); int result = mess.exec(); return; } if (mWorkThread == nullptr) { qDebug() << "--startThread"; startWorkThread(); } emit startPreAssessment(dirModel, dirPredict, dirLabel, dirIndex, dirResult); } void LandslideAssess::pbCancel() { qDebug() << "--pbtCancel"; delete myWidget;//调起&QDialog::destroyed } void LandslideAssess::choosePredictPath() { QString dirInDataset = QFileDialog::getExistingDirectory(ui.pbtInDataset, QString::fromLocal8Bit("选择输入评价文件路径"), ""); if (dirInDataset != "") ui.lineInDataset->setText(dirInDataset); } void LandslideAssess::chooseLabelPath() { QString dirDom = QFileDialog::getExistingDirectory(ui.pbtInLabel, QString::fromLocal8Bit("选择输入标签文件路径"), ""); if (dirDom != "") ui.lineInLabel->setText(dirDom); } void LandslideAssess::chooseAssessFile() { QString dirDom = QFileDialog::getOpenFileName(ui.pbtIndex, QString::fromLocal8Bit("选择输入评估文件索引"), "", "*.txt"); if (dirDom != "") ui.lineIndex->setText(dirDom); } void LandslideAssess::chooseModelFile() { QString fileModel = QFileDialog::getOpenFileName(ui.pbtInModel, QString::fromLocal8Bit("选择输入模型文件"), "", "*.pth"); if (fileModel != "") ui.lineInModel->setText(fileModel); } void LandslideAssess::chooseResultPath() { QString dirResult = QFileDialog::getExistingDirectory(ui.pbtResult, QString::fromLocal8Bit("选择评估结果输出路径"), ""); if (dirResult != "") ui.lineResult->setText(dirResult); } void WorkObject::runAssessWork(QString model, QString PRE, QString label, QString index, QString result) { qDebug() << "start work:" << "\npredict: " << PRE << "\nLabel:" << label; QFileInfo file(index); file.absolutePath(); assess_txt_path = file.absolutePath() + "/assessment.txt"; QDir pluginsDir = QDir(qApp->applicationDirPath()); qDebug() << "----" << pluginsDir.currentPath(); if (!pluginsDir.cd("models\\envs")) { qDebug() << "no folder models\\envs"; return; } QString exeDirName = pluginsDir.absoluteFilePath("miou_landslide.exe"); QString model_dir = " --model_dir " + model; QString img_data_dir = " --img_data_dir " + PRE + "/"; QString label_dir = " --label_dir " + label + "/"; QString val_list = " --val_list " + index; QString out_result = " --result_file " + result + "/"; QString ss = exeDirName + model_dir + img_data_dir + label_dir + val_list + out_result; qDebug() << ss; QProcess* pProces = new QProcess(this); connect(pProces, SIGNAL(readyReadStandardOutput()), this, SLOT(writeAssessTxt())); pProces->start(ss); emit progress(2); } void WorkObject::writeAssessTxt() { mProcess = (QProcess*)sender(); QString output = QString::fromLocal8Bit(mProcess->readAllStandardOutput()); output.chop(2); if (output.toFloat() != 0) { qDebug() << "process:" << output.toFloat(); emit progress(output.toFloat()); } else qDebug() << "unsolved exe out:" << output; } void WorkObject::on_cancel() { if (mProcess == nullptr) qDebug() << "--mProces null"; else { QString KillStr = "taskkill /f /im miou_landslide.exe"; mProcess->startDetached(KillStr); qDebug() << "--kill Proces"; } }