426 lines
12 KiB
C++
426 lines
12 KiB
C++
#include "DEM_GeneVec.h"
|
||
#include<windows.h>
|
||
#include<stdio.h>
|
||
#include<stdlib.h>
|
||
|
||
#include <QSettings>
|
||
|
||
TrainMoudle::TrainMoudle()
|
||
{
|
||
//ui.setupUi(this);
|
||
}
|
||
|
||
TrainMoudle::~TrainMoudle()
|
||
{
|
||
|
||
}
|
||
|
||
QString TrainMoudle::PannelName()
|
||
{
|
||
return QString::fromLocal8Bit("");
|
||
}
|
||
|
||
QString TrainMoudle::CategoryName()
|
||
{
|
||
return QString::fromLocal8Bit("DEM模块");
|
||
}
|
||
|
||
QString TrainMoudle::EnglishName()
|
||
{
|
||
return QString::fromLocal8Bit("DEM_Module");
|
||
}
|
||
|
||
QString TrainMoudle::ChineseName()
|
||
{
|
||
return QString::fromLocal8Bit("模型构建");
|
||
}
|
||
|
||
QString TrainMoudle::Information()
|
||
{
|
||
return QString::fromLocal8Bit("模型构建");
|
||
}
|
||
|
||
QString TrainMoudle::IconPath()
|
||
{
|
||
return ":/DEM_GeneVec/resources/dem_vec.svg";
|
||
}
|
||
|
||
QWidget* TrainMoudle::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(":/DEM_GeneVec/resources/dem_vec.svg"));
|
||
myWidget->setAttribute(Qt::WA_QuitOnClose, false);
|
||
|
||
myWidget->setAttribute(Qt::WA_DeleteOnClose);
|
||
connect(myWidget, &QDialog::destroyed, this, [=] {
|
||
qDebug() << "----DEM train window close----";
|
||
|
||
QDir pluginsDir = QDir(qApp->applicationDirPath());
|
||
if (pluginsDir.cd("srsplugins\\DemModel"))
|
||
{
|
||
QString strConfigPath = pluginsDir.absoluteFilePath("dem_config.ini");
|
||
QFile f(strConfigPath);
|
||
if (f.exists())
|
||
{
|
||
WriteConfigPaths(strConfigPath);
|
||
f.close();
|
||
}
|
||
}
|
||
|
||
if (mThread != nullptr)
|
||
{
|
||
mThread->requestInterruption();//请求线程中断
|
||
mThread->quit();
|
||
mThread->wait();//调用wait后先调用finished信号对应的槽函数,执行完成后再往下走
|
||
mWorkObject->on_cancel();
|
||
mThread = nullptr;//m_objThread, &QThread::finished, m_objThread, &QObject::deleteLater,不需要delete
|
||
mWorkObject = nullptr;//m_objThread, &QThread::finished, m_obj, &QObject::deleteLater
|
||
}
|
||
myWidget->close();
|
||
myWidget = nullptr;
|
||
});
|
||
connect(ui.pbtInModel, &QPushButton::pressed, this, &TrainMoudle::choseInModel);
|
||
connect(ui.pbtInDom, &QPushButton::pressed, this, &TrainMoudle::choseInDom);
|
||
connect(ui.pbtInDsm, &QPushButton::pressed, this, &TrainMoudle::choseInDsm);
|
||
connect(ui.pbtInLabel, &QPushButton::pressed, this, &TrainMoudle::choseInLabel);
|
||
connect(ui.pbtOutModel, &QPushButton::pressed, this, &TrainMoudle::choseOutModel);
|
||
|
||
connect(ui.pushButton_ok, &QPushButton::pressed, this, &TrainMoudle::readAndStart);
|
||
connect(ui.pushButton_cancel, &QPushButton::pressed, this, &TrainMoudle::pbCancel);
|
||
|
||
connect(ui.checkBoxMid, &QCheckBox::clicked, this, [=](bool checked) {
|
||
executeMid = checked;
|
||
if (!executeMid && !executeTrain)
|
||
ui.pushButton_ok->setEnabled(false);
|
||
else
|
||
ui.pushButton_ok->setEnabled(true);
|
||
});
|
||
connect(ui.checkBoxTrain, &QCheckBox::clicked, this, [=](bool checked) {
|
||
executeTrain = checked;
|
||
if (!executeMid && !executeTrain)
|
||
ui.pushButton_ok->setEnabled(false);
|
||
else
|
||
ui.pushButton_ok->setEnabled(true);
|
||
});
|
||
|
||
ui.progressBar->setTextVisible(true);
|
||
ui.progressBar->setRange(0, 100);
|
||
|
||
ui.lineEpoch1->setValidator(new QIntValidator(0, 999, this));
|
||
ui.lineEpoch2->setValidator(new QIntValidator(0, 999, this));
|
||
ui.lineEpoch1->setText("100");
|
||
ui.lineEpoch2->setText("100");
|
||
|
||
ui.pbtInModel->setFocus();
|
||
|
||
QFile qssFile(":/DEM_GeneVec/DEM_GeneVec.qss");
|
||
qssFile.open(QFile::ReadOnly); //以只读方式打开
|
||
if (qssFile.isOpen())
|
||
{
|
||
QString qss = QLatin1String(qssFile.readAll());
|
||
myWidget->setStyleSheet(qss);
|
||
qssFile.close();
|
||
}
|
||
else
|
||
qDebug() << "无法打开文件";
|
||
|
||
QDir pluginsDir = QDir(qApp->applicationDirPath());
|
||
if (pluginsDir.cd("srsplugins\\DemModel"))
|
||
{
|
||
QString strConfigPath = pluginsDir.absoluteFilePath("dem_config.ini");
|
||
QFile f(strConfigPath);
|
||
if (f.exists())
|
||
{
|
||
ReadConfigHistoryPaths(strConfigPath);
|
||
f.close();
|
||
}
|
||
}
|
||
|
||
if (showWin)
|
||
myWidget->show();
|
||
|
||
return myWidget;
|
||
}
|
||
|
||
void TrainMoudle::startWorkThread()
|
||
{
|
||
if (mWorkObject != nullptr)
|
||
{
|
||
return;
|
||
}
|
||
mThread = new QThread();
|
||
mWorkObject = new WorkThreadObject();
|
||
mWorkObject->moveToThread(mThread);
|
||
connect(mThread, &QThread::finished, mThread, &QObject::deleteLater);
|
||
connect(mThread, &QThread::finished, mWorkObject, &QObject::deleteLater);
|
||
connect(mWorkObject, &WorkThreadObject::process, myWidget, [=](double val) {ui.progressBar->SetDoubleFormatValue(QString::fromLocal8Bit("进度"), val); });
|
||
connect(mWorkObject, &WorkThreadObject::addDataToMap, this, &TrainMoudle::addMap);
|
||
//connect(this, &TrainMoudle::killChildThread, mWorkObject, &WorkThreadObject::on_cancel);
|
||
|
||
connect(this, &TrainMoudle::start, mWorkObject, &WorkThreadObject::runTrainWork);
|
||
mThread->start();
|
||
}
|
||
//pbtDataset
|
||
//pbtValName
|
||
//pbtOutModel
|
||
void TrainMoudle::choseInModel()
|
||
{
|
||
QString inModel = QFileDialog::getOpenFileName(ui.pbtInModel, QString::fromLocal8Bit("选择输入模型文件路径"), "", "*.pth");
|
||
if (inModel != "")
|
||
ui.lineInModel->setText(inModel);
|
||
}
|
||
void TrainMoudle::choseInDom()
|
||
{
|
||
QString dataset = QFileDialog::getExistingDirectory(ui.pbtInDom, QString::fromLocal8Bit("选择输入DOM文件路径"), "");
|
||
if (dataset != "")
|
||
ui.lineInDom->setText(dataset);
|
||
}
|
||
void TrainMoudle::choseInDsm()
|
||
{
|
||
QString valName = QFileDialog::getExistingDirectory(ui.pbtInDsm, QString::fromLocal8Bit("选择输入Slope文件路径"), "");
|
||
if (valName != "")
|
||
ui.lineInDsm->setText(valName);
|
||
}
|
||
void TrainMoudle::choseInLabel()
|
||
{
|
||
QString valName = QFileDialog::getExistingDirectory(ui.pbtInLabel, QString::fromLocal8Bit("选择输入Label文件路径"), "");
|
||
if (valName != "")
|
||
ui.lineInLabel->setText(valName);
|
||
}
|
||
void TrainMoudle::choseOutModel()
|
||
{
|
||
QString outModel = QFileDialog::getExistingDirectory(ui.pbtOutModel, QString::fromLocal8Bit("选择输出模型文件路径"), "");
|
||
if (outModel != "")
|
||
ui.lineOutModel->setText(outModel);
|
||
}
|
||
|
||
void TrainMoudle::ReadConfigHistoryPaths(QString strPath)
|
||
{
|
||
QSettings configIni(strPath, QSettings::IniFormat);
|
||
|
||
//打开标题为:[DemTrain] 的组,并读取出port字段的值
|
||
configIni.beginGroup("DemTrain");
|
||
|
||
ui.lineInModel->setText(configIni.value("RetrainModel").toString());
|
||
ui.lineInDom->setText(configIni.value("SrcDom").toString());
|
||
ui.lineInDsm->setText(configIni.value("SrcDsm").toString());
|
||
ui.lineInLabel->setText(configIni.value("SrcLabel").toString());
|
||
ui.lineOutModel->setText(configIni.value("TrainResult").toString());
|
||
|
||
configIni.endGroup();//关闭组
|
||
}
|
||
|
||
void TrainMoudle::WriteConfigPaths(QString strPath)
|
||
{
|
||
QSettings configIni(strPath, QSettings::IniFormat);
|
||
configIni.setIniCodec("utf-8");
|
||
//打开标题为:[DemTrain] 的组
|
||
configIni.beginGroup("DemTrain");
|
||
|
||
//更新输入模型路径
|
||
QString temp = ui.lineInModel->text();
|
||
if (temp != "")
|
||
configIni.setValue("RetrainModel", temp);
|
||
//更新输入DOM路径
|
||
temp = ui.lineInDom->text();
|
||
if (temp != "")
|
||
configIni.setValue("SrcDom", temp);
|
||
//更新输入DSM路径
|
||
temp = ui.lineInDsm->text();
|
||
if (temp != "")
|
||
configIni.setValue("SrcDsm", temp);
|
||
//更新输入Label路径
|
||
temp = ui.lineInLabel->text();
|
||
if (temp != "")
|
||
configIni.setValue("SrcLabel", temp);
|
||
//更新输出结果路径
|
||
temp = ui.lineOutModel->text();
|
||
if (temp != "")
|
||
configIni.setValue("TrainResult", temp);
|
||
|
||
configIni.endGroup();//关闭组
|
||
}
|
||
|
||
void TrainMoudle::addMap()
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon,
|
||
QString::fromLocal8Bit("运行结束"),
|
||
QString::fromLocal8Bit("结果文件生成路径\n") + ui.lineOutModel->text(),
|
||
QMessageBox::Ok, NULL);
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
mess.setButtonText(QMessageBox::Ok, QString::fromLocal8Bit("确认"));
|
||
int result = mess.exec();
|
||
//switch (result)
|
||
//{
|
||
//case QMessageBox::Ok:
|
||
// //string_list.append(ui.lineEdit_outras->text());
|
||
// //string_list.append(ui.lineEdit_outshp->text());
|
||
// //qDebug() << "----Yes:" << string_list;
|
||
// //openResultData(string_list);
|
||
// //emit addDataToCanvas(string_list);
|
||
// break;
|
||
//default:
|
||
// break;
|
||
//}
|
||
pbCancel();
|
||
}
|
||
|
||
void TrainMoudle::readAndStart()
|
||
{
|
||
QString inModel = ui.lineInModel->text();
|
||
QString inDOM = ui.lineInDom->text();
|
||
QString inDSM = ui.lineInDsm->text();
|
||
QString inLabel = ui.lineInLabel->text();
|
||
QString outModel = ui.lineOutModel->text();
|
||
|
||
ui.progressBar->SetDoubleFormatValue(QString::fromLocal8Bit("进度"), 0);
|
||
|
||
if (inModel == "" || inDOM == "" || inDSM == "" || inLabel == "" || outModel == "")
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("请检查输入输出文件夹或数据"));
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
QDir inDOMdir(inDOM);
|
||
if (!inDOMdir.exists())
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("DOM文件夹不存在"));
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
QDir inDSMdir(inDSM);
|
||
if (!inDSMdir.exists())
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("Slope文件夹不存在"));
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
QDir inLabeldir(inLabel);
|
||
if (!inLabeldir.exists())
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("Label文件夹不存在"));
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
QDir outModeldir(outModel);
|
||
if (!outModeldir.exists())
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("模型输出文件夹不存在"));
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
|
||
if (executeMid && executeTrain)
|
||
qDebug() << "executeMid & executeTrain";
|
||
if (executeMid && (!executeTrain))
|
||
qDebug() << "executeMid, not executeTrain";
|
||
if ((!executeMid) && executeTrain)
|
||
{
|
||
//判断train文件夹下有无训练集文件夹
|
||
QDir dirImage(outModel + "/Images");
|
||
QDir dirLabel(outModel + "/Labels");
|
||
if (!dirImage.exists() || !dirLabel.exists())
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"),
|
||
QString::fromLocal8Bit("未找到训练集文件夹\n确保Images和Labels在以下路径中: \n") + outModel);
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
//判断文件是否匹配
|
||
QStringList imgList = getAllFiles(outModel + "/Images", "tif");
|
||
QStringList labelList = getAllFiles(outModel + "/Labels", "tif");
|
||
if (imgList.size() == 0 || labelList.size() == 0)
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"),
|
||
QString::fromLocal8Bit("训练集文件夹内为空"));
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
if (imgList.size() != labelList.size())
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"),
|
||
QString::fromLocal8Bit("训练集Images、Labels文件夹内文件不匹配"));
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (ui.lineEpoch1->text() == "" || ui.lineEpoch2->text() == "")
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("请输入正确的训练轮数"));
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
QString epoch1 = ui.lineEpoch1->text();
|
||
QString epoch2 = ui.lineEpoch2->text();
|
||
|
||
if (mThread == nullptr)
|
||
{
|
||
qDebug() << "--startThread";
|
||
startWorkThread();
|
||
}
|
||
|
||
emit start(inModel, inDOM, inDSM, inLabel, outModel, executeMid, executeTrain, epoch1, epoch2);
|
||
}
|
||
|
||
QStringList TrainMoudle::getAllFiles(QString path, QString fileType)
|
||
{
|
||
QDir dir(path);
|
||
if (!dir.exists())
|
||
return QStringList();
|
||
dir.setFilter(QDir::Files | QDir::NoSymLinks);
|
||
QFileInfoList list = dir.entryInfoList();
|
||
|
||
int file_count = list.count();
|
||
if (file_count <= 0)
|
||
return QStringList();
|
||
QStringList files;
|
||
for (int i = 0; i < file_count; i++)
|
||
{
|
||
QFileInfo file_info = list.at(i);
|
||
QString suffix = file_info.suffix();
|
||
if (QString::compare(suffix, QString(fileType), Qt::CaseInsensitive) == 0)
|
||
{
|
||
QString absolute_file_path = file_info.absoluteFilePath();
|
||
files.append(absolute_file_path);
|
||
}
|
||
}
|
||
return files;
|
||
}
|
||
|
||
void TrainMoudle::pbCancel()
|
||
{
|
||
delete myWidget;//调起&QDialog::destroyed
|
||
}
|