/* Copyright(c)--Navinfo--Author:fangzurui--date:2023-10-13 */ #include "DataManager/ImageFileManager.h" /* -------------------------------------- 算法 -------------------------------------- */ Algorithm::Algorithm() {} Algorithm::~Algorithm() {} void Algorithm::loadParameters(ImportData importData, IMAGEPROJECT_PARAMETER &stImageProjParameter) { // 实时图相机内参 stImageProjParameter.stCameraInfor.binning = 1; stImageProjParameter.stCameraInfor.fBaseFocus = importData.cameraFocus.toFloat(); // 如果无,设置缺省值,ui上手动调整 stImageProjParameter.stCameraInfor.fov_degree = importData.range.toFloat(); if(importData.type == "InfraredImage") { stImageProjParameter.stCameraInfor.pixel_size = 17; // 如果无,设置缺缺省值 stImageProjParameter.stCameraInfor.flip = false; } else { stImageProjParameter.stCameraInfor.pixel_size = 3.3; // 如果无,设置缺缺省值 stImageProjParameter.stCameraInfor.flip = false; } // 载机(body)wgs84位置 stImageProjParameter.stBodyWGS84.fLat = importData.lat.toDouble(); // 纬度 stImageProjParameter.stBodyWGS84.fLon = importData.lon.toDouble(); // 经度 stImageProjParameter.stBodyWGS84.fAltitude = importData.alt.toDouble(); // 海拔高度 //载机(body)导航系下姿态 stImageProjParameter.stBodyRPY.fYaw = importData.craftHeading.toDouble(); // 航向角 stImageProjParameter.stBodyRPY.fPitch = importData.craftPitching.toDouble(); // 俯仰角 stImageProjParameter.stBodyRPY.fRoll = importData.craftRolling.toDouble(); // 滚转角 // 光电吊舱框架角 stImageProjParameter.stEoServe.fYaw = importData.heading.toDouble(); // 吊舱方位,右旋为正:0-360° stImageProjParameter.stEoServe.fPitch = importData.pitching.toDouble(); stImageProjParameter.stEoServe.fRoll = 0.0; if(importData.distance.toDouble() == -1.0) { // 相对高度 = 载机海拔高度 - 地面海拔高度 double groundAltitude = getElevationFromTiff(importData.lon.toDouble(), importData.lat.toDouble()); if(groundAltitude == 0) { stImageProjParameter.stEoServe.fRelativeHigh = 0.0; } else { if(importData.alt.toDouble() - groundAltitude > 0) { stImageProjParameter.stEoServe.fRelativeHigh = importData.alt.toDouble() - groundAltitude; // 米,相对高度,与上面的fAxisPtDistance必须二选一设其一, } else { stImageProjParameter.stEoServe.fRelativeHigh = 0.0; } } } else { stImageProjParameter.stEoServe.fAxisPtDistance= importData.distance.toDouble(); // 米,目标距离 //目标gps真值 stImageProjParameter.stTargetWGS84.fLat = importData.centerLat.toDouble(); // 纬度 stImageProjParameter.stTargetWGS84.fLon = importData.centerLon.toDouble(); // 经度 stImageProjParameter.stTargetWGS84.fAltitude = importData.centerAlt.toDouble(); // 海拔高度 } } WF_ERROR_CODE Algorithm::SpatialVariation(ImportData importData) { // 注册所有GDAL驱动 GDALAllRegister(); QString strAppPath = QCoreApplication::applicationDirPath(); // 输入影像路径 QString strRealImgFilePath = importData.originImagePath; QString strFileName = QFileInfo(strRealImgFilePath).baseName(); // 加载参数 IMAGEPROJECT_PARAMETER stImageProjParameter; memset(&stImageProjParameter, 0, sizeof(IMAGEPROJECT_PARAMETER)); loadParameters(importData, stImageProjParameter); // 创建ImageProjectLib实例 ImageProjectInterface *pImageProjectInterface = ImageProjectLibFactory::create(); // 参数初始化 pImageProjectInterface->initParameter(stImageProjParameter); // 手动误差 CompositeError stManualTerminalError { importData.headingError.toDouble(), importData.pitchingError.toDouble(), importData.rollingError.toDouble() }; // 半透明值0-100 int iAlpha = importData.transparency.toInt(); std::string strOutputTiffPath = strAppPath.toStdString() + "\\tifMaxRect\\" + strFileName.toStdString() + ".tif"; // 与输入文件同前缀名的tiff // 新焦距 float fNewFocus = importData.cameraFocus.toFloat(); REGION_INFOR stRegion; // 将实时图投影到tiff文件,含地理信息 WF_ERROR_CODE iRet = pImageProjectInterface->projectRealImageFile(strRealImgFilePath.toStdString(), // 输入文件路径 strOutputTiffPath, // 如果输入为空,函数会回传tiff文件路径 stRegion, // 输出的图片地理范围 &stManualTerminalError, // 手动修正量 fNewFocus, // 新焦距 iAlpha); // 添加地理信息 addGeoInformationToTiff(QString::fromStdString(strOutputTiffPath), stRegion); qDebug("projectRealImageFile iRet=%d", iRet); qDebug() << "ImageProjectInterface has generated tiff file " << strOutputTiffPath.c_str(); return iRet; } bool Algorithm::FeatureMatching(ImportData importData) { // 算法程序位置 QString path = QCoreApplication::applicationDirPath(); path = path.replace("/", "\\"); std::string exeName = path.toStdString() + "\\imagePreProcess\\imagePreProcess.exe"; // 匹配底图路径 QString foldDir = QCoreApplication::applicationDirPath() + "\\defaultImage"; foldDir = foldDir.replace("/", "\\"); std::string fold_dir = foldDir.toStdString(); // 原始红外/可见光图像路径 QString imgDir = importData.originImagePath; imgDir = imgDir.replace("/", "\\"); /* 将Unix格式转成Windows格式 */ std::string img_dir = imgDir.toStdString(); // 将输入的参数信息传入到parameter.txt QFile paramFile(path + "\\parameter.txt"); paramFile.open(QIODevice::WriteOnly); // 将ui获取的参数写入到参数txt文件中 QFileInfo originFileInfo(importData.originImagePath); QString paramTxt; if(importData.centerLon.toDouble() != 0.0 && importData.centerLat.toDouble() != 0.0) { // 如果ui上有图像中心点的数据,则优先使用中心点坐标 paramTxt = originFileInfo.fileName() + " " + "0" + " " + importData.centerLon + " " + importData.centerLat + " " + importData.craftHeading + " " + importData.heading + " " + importData.alt; } else { // 如果ui上没有图像中心点的数据,则使用吊舱经纬度坐标 paramTxt = originFileInfo.fileName() + " " + "1" + " " + importData.lon + " " + importData.lat + " " + importData.craftHeading + " " + importData.heading + " " + importData.alt; } paramFile.write(paramTxt.toStdString().c_str()); paramFile.close(); // 参数txt文件路径 std::string parameter_dir; parameter_dir = paramFile.fileName().toStdString(); // 输出矫正影像路径 std::string output_tif_path = path.toStdString(); // 日志文件路径 std::string log = path.toStdString() + "\\log.txt"; // 算法执行命令 std::string command = exeName + " -fold_dir " + fold_dir + " -img " + img_dir + " -parameter " + parameter_dir + " -output_tif_path " + output_tif_path + " -log " + log; // 执行算法 int result = system(command.c_str()); if(result == 0) { return true; } else { return false; } } double Algorithm::getElevationFromTiff(double longitude, double latitude) { // 设置返回值 double altitude = 0.0; // 从路径中遍历所有tif数据 QDir dir = QCoreApplication::applicationDirPath() + "\\defaultDEM"; if(dir.exists() == false) { return altitude; } // 获取路径下的所有文件 QStringList fileType; fileType << "*.tif"; QStringList fileList = dir.entryList(fileType, QDir::Files | QDir::Readable, QDir::Name); // 遍历文件获取 for(int i = 0; i < fileList.size(); i++) { altitude = getElevationFromTiff(dir.path().toStdString() + "\\" + fileList.at(i).toStdString(), latitude, longitude); if(altitude != 0.0) { return altitude; } } return altitude; } double Algorithm::getElevationFromTiff(const std::string& tiffPath, double latitude, double longitude) { GDALAllRegister(); GDALDataset* dataset = static_cast(GDALOpen(tiffPath.c_str(), GA_ReadOnly)); if (dataset == nullptr) { std::cerr << "Failed to open TIFF file: " << tiffPath << std::endl; return 0.0; } double adfGeoTransform[6]; if (dataset->GetGeoTransform(adfGeoTransform) != CE_None) { std::cerr << "Failed to retrieve geotransform information from TIFF file." << std::endl; GDALClose(dataset); return 0.0; } int x = static_cast((longitude - adfGeoTransform[0]) / adfGeoTransform[1]); int y = static_cast((latitude - adfGeoTransform[3]) / adfGeoTransform[5]); double elevation = 0.0; float elevationData=0.0; dataset->GetRasterBand(1)->RasterIO(GF_Read, x, y, 1, 1, &elevationData, 1, 1, GDT_Float32, 0, 0); elevation = static_cast(elevationData); GDALClose(dataset); if(elevation==0.0) { qDebug("latitude/longitude[%f,%f], get elevation failed!", latitude, longitude); } else { qDebug("latitude/longitude[%f,%f],x/y[%d,%d],elevation=%f", latitude, longitude, x, y, elevation); } return elevation; } void Algorithm::addGeoInformationToTiff(const QString &tiffFilePath, REGION_INFOR stRegion) { double fLon0=stRegion.fLon0; double fLat0=stRegion.fLat0; double fLon1=stRegion.fLon1; double fLat1=stRegion.fLat1; GDALDataset *dataset = (GDALDataset *)GDALOpen(tiffFilePath.toUtf8().constData(), GA_Update); if (dataset == nullptr) { return; } // 设置地理坐标系 OGRSpatialReference srs; srs.SetWellKnownGeogCS("WGS84"); char *projection = nullptr; srs.exportToWkt(&projection); dataset->SetProjection(projection); CPLFree(projection); // 设置地理坐标范围 double geoTransform[6] = { 0 }; geoTransform[0] = fLon0; // 左上角经度 geoTransform[1] = (fLon1 - fLon0) / dataset->GetRasterXSize(); // 横向像素分辨率 geoTransform[2] = 0; // 旋转参数 geoTransform[3] = fLat0; // 左上角纬度 geoTransform[4] = 0; // 旋转参数 geoTransform[5] = (fLat1 - fLat0) / dataset->GetRasterYSize(); // 纵向像素分辨率(负值表示y轴朝下) dataset->SetGeoTransform(geoTransform); GDALRasterBand* alphaBand = dataset->GetRasterBand(4); // 假设 alpha 通道为第四个通道 alphaBand->SetColorInterpretation(GCI_AlphaBand); alphaBand->SetDescription("Alpha"); // 清理GDAL资源 GDALClose(dataset); return; } int Algorithm::calImageCenterCoord(QString strImagePath, MapPoint& mapPoint) { // 注册所有驱动 GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); GDALDataset* fin = (GDALDataset*)GDALOpen(strImagePath.toStdString().c_str(), GA_ReadOnly); if(fin == nullptr) { mapPoint = {0, 0, 0}; return 1; } std::vector geoTransform(6); if(fin->GetGeoTransform(geoTransform.data()) != CE_None) { mapPoint = {0, 0, 0}; return 2; } int imgX = fin->GetRasterXSize(); int imgY = fin->GetRasterYSize(); double centerLon = geoTransform[0] + (imgX / 2) * geoTransform[1] + (imgY / 2) * geoTransform[2]; double centerLat = geoTransform[3] + (imgX / 2) * geoTransform[4] + (imgY / 2) * geoTransform[5]; GDALClose(fin); mapPoint = {centerLon, centerLat, 2000}; return 0; } /* -------------------------------------- 参数调整 -------------------------------------- */ AdjustParam::AdjustParam(QWidget* parent) : QDialog(parent) , ui(new Ui::AdjustParam) { ui->setupUi(this); this->setWindowTitle(QObject::tr("Adjust Parameter")); this->setWindowIcon(QIcon(QCoreApplication::applicationDirPath() + "\\Resource\\dmatch.ico")); } AdjustParam::~AdjustParam() { delete ui; } void AdjustParam::initAdjustParamWidget() { ui->HeadingError->setText(QObject::tr("Heading Error:")); ui->HeadingSpinBox->setRange(-90, 90); ui->HeadingSpinBox->setValue(0); ui->HeadingSpinBox->setSingleStep(1); ui->Point1->setText("."); ui->Point1->setFixedWidth(2); ui->HeadingSpinBox1->setRange(0, 9); ui->HeadingSpinBox1->setValue(0); ui->HeadingSpinBox1->setSingleStep(1); ui->HeadingSpinBox2->setRange(0, 9); ui->HeadingSpinBox2->setValue(0); ui->HeadingSpinBox2->setSingleStep(1); ui->HeadingSpinBox1->setWrapping(true); // 值循环 ui->HeadingSpinBox2->setWrapping(true); ui->HeadingUnit->setText("°"); ui->PitchingError->setText(QObject::tr("Pitching Error:")); ui->PitchingSpinBox->setRange(-90, 90); ui->PitchingSpinBox->setValue(0); ui->PitchingSpinBox->setSingleStep(1); ui->Point2->setText("."); ui->Point2->setFixedWidth(2); ui->PitchingSpinBox1->setRange(0, 9); ui->PitchingSpinBox1->setValue(0); ui->PitchingSpinBox1->setSingleStep(1); ui->PitchingSpinBox2->setRange(0, 9); ui->PitchingSpinBox2->setValue(0); ui->PitchingSpinBox2->setSingleStep(1); ui->PitchingSpinBox1->setWrapping(true); ui->PitchingSpinBox2->setWrapping(true); ui->PitchingUnit->setText("°"); ui->RollingError->setText(QObject::tr("Rolling Error:")); ui->RollingSpinBox->setRange(-90, 90); ui->RollingSpinBox->setValue(0); ui->RollingSpinBox->setSingleStep(1); ui->Point3->setText("."); ui->Point3->setFixedWidth(2); ui->RollingSpinBox1->setRange(0, 9); ui->RollingSpinBox1->setValue(0); ui->RollingSpinBox1->setSingleStep(1); ui->RollingSpinBox2->setRange(0, 9); ui->RollingSpinBox2->setValue(0); ui->RollingSpinBox2->setSingleStep(1); ui->RollingSpinBox1->setWrapping(true); ui->RollingSpinBox2->setWrapping(true); ui->RollingUnit->setText("°"); ui->CameraFocus->setText(QObject::tr("Camera Focus:")); ui->CameraFocusSpinBox->setRange(10, 1000); if(_importData.cameraFocus.isEmpty() == false) { ui->CameraFocusSpinBox->setValue(_importData.cameraFocus.toInt()); } else { ui->CameraFocusSpinBox->setValue(100); } ui->CameraFocusSpinBox->setSingleStep(1); ui->CameraFocusUnit->setText("mm"); ui->Range->setText(QObject::tr("Range:")); ui->RangeSpinBox->setRange(0, 180); ui->RangeSpinBox1->setRange(0, 180); ui->RangeSpinBox2->setRange(0, 180); ui->Point4->setFixedWidth(2); if(_importData.range.isEmpty() == false) { int range = static_cast(_importData.range.toDouble() * 100); ui->RangeSpinBox->setValue(range % 100); ui->RangeSpinBox1->setValue((range - (range % 100)) % 10); ui->RangeSpinBox2->setValue(range - ((range - (range % 100)) % 10)); } else { ui->RangeSpinBox->setValue(0); ui->RangeSpinBox1->setValue(0); ui->RangeSpinBox2->setValue(0); } ui->RangeSpinBox->setSingleStep(1); ui->RangeSpinBox1->setSingleStep(1); ui->RangeSpinBox2->setSingleStep(1); ui->RangeSpinBox1->setWrapping(true); ui->RangeSpinBox2->setWrapping(true); ui->RangeUnit->setText("°"); ui->TransparencyLabel->setText(QObject::tr("Transparency:")); ui->TransparencySlider->setRange(0, 100); ui->TransparencySlider->setValue(100); ui->TransparencySlider->setSingleStep(1); ui->TransparencyUnit->setText("%"); ui->Cancel->setText(QObject::tr("Cancel")); // Spinbox触发算法事件 connect(ui->HeadingSpinBox, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->HeadingSpinBox1, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->HeadingSpinBox2, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->PitchingSpinBox, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->PitchingSpinBox1, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->PitchingSpinBox2, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->RollingSpinBox, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->RollingSpinBox1, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->RollingSpinBox2, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->CameraFocusSpinBox, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->RangeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->RangeSpinBox1, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->RangeSpinBox2, SIGNAL(valueChanged(int)), this, SLOT(startMatch())); connect(ui->TransparencySlider, SIGNAL(sliderReleased()), this, SLOT(startMatch())); // Spinbox小数循环事件 connect(ui->HeadingSpinBox1, SIGNAL(valueChanged(int)), this, SLOT(changeHeading1Value(int))); connect(ui->HeadingSpinBox2, SIGNAL(valueChanged(int)), this, SLOT(changeHeading2Value(int))); connect(ui->PitchingSpinBox1, SIGNAL(valueChanged(int)), this, SLOT(changePitching1Value(int))); connect(ui->PitchingSpinBox2, SIGNAL(valueChanged(int)), this, SLOT(changePitching2Value(int))); connect(ui->RollingSpinBox1, SIGNAL(valueChanged(int)), this, SLOT(changeRolling1Value(int))); connect(ui->RollingSpinBox2, SIGNAL(valueChanged(int)), this, SLOT(changeRolling2Value(int))); connect(ui->RangeSpinBox1, SIGNAL(valueChanged(int)), this, SLOT(changeRange1Value(int))); connect(ui->RangeSpinBox2, SIGNAL(valueChanged(int)), this, SLOT(changeRange2Value(int))); connect(ui->Cancel, SIGNAL(clicked(bool)), this, SLOT(close())); } void AdjustParam::setParameter(ImportData importData) { _importData = importData; } bool AdjustParam::isCorrectParam() { // 判断经纬高是否在合法范围内 double heading = ui->HeadingSpinBox->text().toDouble(); double pitching = ui->PitchingSpinBox->text().toDouble(); double rolling = ui->RollingSpinBox->text().toDouble(); // 吊舱经度:必需,-180~180 bool isHeadingValid = (heading >= -90.0 && heading <= 90.0); bool isPitchingValid = (pitching >= -90.0 && pitching <= 90.0); bool isRollingValid = (rolling >= -90.0 && rolling <= 90.0); if(!isHeadingValid || !isPitchingValid || !isRollingValid) { return false; } return true; } void AdjustParam::changeHeading1Value(int value) { if(value == 9 && heading1 == 0) { // 如果是最小值时,不做更改 if(ui->HeadingSpinBox->value() == ui->HeadingSpinBox->minimum()) { ui->HeadingSpinBox1->setValue(heading1); return; } else { // 如果不是则-1 ui->HeadingSpinBox->setValue(ui->HeadingSpinBox->value() - 1); } } if(value == 0 && heading1 == 9) { // 如果时最大值时,不做更改 if(ui->HeadingSpinBox->value() == ui->HeadingSpinBox->maximum()) { ui->HeadingSpinBox1->setValue(heading1); return; } else { // 如果不是则+1 ui->HeadingSpinBox->setValue(ui->HeadingSpinBox->value() + 1); } } heading1 = value; } void AdjustParam::changeHeading2Value(int value) { if(value == 9 && heading2 == 0) { // 如果是最小值时,不做更改 if(ui->HeadingSpinBox->value() == ui->HeadingSpinBox->minimum() && ui->HeadingSpinBox1->value() == ui->HeadingSpinBox1->minimum()) { ui->HeadingSpinBox2->setValue(heading2); return; } else { // 如果不是则-1 ui->HeadingSpinBox1->setValue(ui->HeadingSpinBox1->value() - 1); } } if(value == 0 && heading2 == 9) { // 如果时最大值时,不做更改 if(ui->HeadingSpinBox->value() == ui->HeadingSpinBox->maximum() && ui->HeadingSpinBox1->value() == ui->HeadingSpinBox1->maximum()) { ui->HeadingSpinBox2->setValue(heading2); return; } else { // 如果不是则+1 ui->HeadingSpinBox1->setValue(ui->HeadingSpinBox1->value() + 1); } } heading2 = value; } void AdjustParam::changePitching1Value(int value) { if(value == 9 && pitching1 == 0) { // 如果是最小值时,不做更改 if(ui->PitchingSpinBox->value() == ui->PitchingSpinBox->minimum()) { ui->PitchingSpinBox1->setValue(pitching1); return; } else { // 如果不是则-1 ui->PitchingSpinBox->setValue(ui->PitchingSpinBox->value() - 1); } } if(value == 0 && pitching1 == 9) { // 如果时最大值时,不做更改 if(ui->PitchingSpinBox->value() == ui->PitchingSpinBox->maximum()) { ui->PitchingSpinBox1->setValue(pitching1); return; } else { // 如果不是则+1 ui->PitchingSpinBox->setValue(ui->PitchingSpinBox->value() + 1); } } pitching1 = value; } void AdjustParam::changePitching2Value(int value) { if(value == 9 && pitching2 == 0) { // 如果是最小值时,不做更改 if(ui->PitchingSpinBox->value() == ui->PitchingSpinBox->minimum() && ui->PitchingSpinBox1->value() == ui->PitchingSpinBox1->minimum()) { ui->PitchingSpinBox2->setValue(pitching2); return; } else { // 如果不是则-1 ui->PitchingSpinBox1->setValue(ui->PitchingSpinBox1->value() - 1); } } if(value == 0 && pitching2 == 9) { // 如果时最大值时,不做更改 if(ui->PitchingSpinBox->value() == ui->PitchingSpinBox->maximum() && ui->PitchingSpinBox1->value() == ui->PitchingSpinBox1->maximum()) { ui->PitchingSpinBox2->setValue(pitching2); return; } else { // 如果不是则+1 ui->PitchingSpinBox1->setValue(ui->PitchingSpinBox1->value() + 1); } } pitching2 = value; } void AdjustParam::changeRolling1Value(int value) { if(value == 9 && rolling1 == 0) { // 如果是最小值时,不做更改 if(ui->RollingSpinBox->value() == ui->RollingSpinBox->minimum()) { ui->RollingSpinBox1->setValue(rolling1); return; } else { // 如果不是则-1 ui->RollingSpinBox->setValue(ui->RollingSpinBox->value() - 1); } } if(value == 0 && rolling1 == 9) { // 如果时最大值时,不做更改 if(ui->RollingSpinBox->value() == ui->RollingSpinBox->maximum()) { ui->RollingSpinBox1->setValue(rolling1); return; } else { // 如果不是则+1 ui->RollingSpinBox->setValue(ui->RollingSpinBox->value() + 1); } } rolling1 = value; } void AdjustParam::changeRolling2Value(int value) { if(value == 9 && rolling2 == 0) { // 如果是最小值时,不做更改 if(ui->RollingSpinBox->value() == ui->RollingSpinBox->minimum() && ui->RollingSpinBox1->value() == ui->RollingSpinBox1->minimum()) { ui->RollingSpinBox2->setValue(rolling2); return; } else { // 如果不是则-1 ui->RollingSpinBox1->setValue(ui->RollingSpinBox1->value() - 1); } } if(value == 0 && rolling2 == 9) { // 如果时最大值时,不做更改 if(ui->RollingSpinBox->value() == ui->RollingSpinBox->maximum() && ui->RollingSpinBox1->value() == ui->RollingSpinBox1->maximum()) { ui->RollingSpinBox2->setValue(rolling2); return; } else { // 如果不是则+1 ui->RollingSpinBox1->setValue(ui->RollingSpinBox1->value() + 1); } } rolling2 = value; } void AdjustParam::changeRange1Value(int value) { if(value == 9 && range1 == 0) { // 如果是最小值时,不做更改 if(ui->RangeSpinBox->value() == ui->RangeSpinBox->minimum()) { ui->RangeSpinBox1->setValue(range1); return; } else { // 如果不是则-1 ui->RangeSpinBox->setValue(ui->RangeSpinBox->value() - 1); } } if(value == 0 && range1 == 9) { // 如果时最大值时,不做更改 if(ui->RangeSpinBox->value() == ui->RangeSpinBox->maximum()) { ui->RangeSpinBox1->setValue(range1); return; } else { // 如果不是则+1 ui->RangeSpinBox->setValue(ui->RangeSpinBox->value() + 1); } } range1 = value; } void AdjustParam::changeRange2Value(int value) { if(value == 9 && range2 == 0) { // 如果是最小值时,不做更改 if(ui->RangeSpinBox->value() == ui->RangeSpinBox->minimum() && ui->RangeSpinBox1->value() == ui->RangeSpinBox1->minimum()) { ui->RangeSpinBox2->setValue(range2); return; } else { // 如果不是则-1 ui->RangeSpinBox1->setValue(ui->RangeSpinBox1->value() - 1); } } if(value == 0 && range2 == 9) { // 如果时最大值时,不做更改 if(ui->RangeSpinBox->value() == ui->RangeSpinBox->maximum() && ui->RangeSpinBox1->value() == ui->RangeSpinBox1->maximum()) { ui->RangeSpinBox2->setValue(range2); return; } else { // 如果不是则+1 ui->RangeSpinBox1->setValue(ui->RangeSpinBox1->value() + 1); } } range2 = value; } void AdjustParam::startMatch() { // 判断是否可以执行算法 bool ret = isCorrectParam(); if(ret == false) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Coordinate Not Enter or Data Illegal"), QMessageBox::Ok, QMessageBox::Ok); return; } else { // 将ui获取的值拼接 double headingError = ui->HeadingSpinBox->text().toInt() + ui->HeadingSpinBox1->text().toInt() * 0.1 + ui->HeadingSpinBox2->text().toInt() * 0.01; double pitchingError = ui->PitchingSpinBox->text().toInt() + ui->PitchingSpinBox1->text().toInt() * 0.1 + ui->PitchingSpinBox2->text().toInt() * 0.01; double rollingError = ui->RollingSpinBox->text().toInt() + ui->RollingSpinBox1->text().toInt() * 0.1 + ui->RollingSpinBox2->text().toInt() * 0.01; double range = ui->RangeSpinBox->text().toInt() + ui->RangeSpinBox1->text().toInt() * 0.1 + ui->RangeSpinBox2->text().toInt() * 0.01; _importData.headingError = QString::number(headingError, 'f', 2); _importData.pitchingError = QString::number(pitchingError, 'f', 2); _importData.rollingError = QString::number(rollingError, 'f', 2); _importData.range = QString::number(range, 'f', 2); _importData.cameraFocus = ui->CameraFocusSpinBox->text(); _importData.transparency = QString::number(ui->TransparencySlider->value()); // 执行一次算法 matchingInterface(); } } bool AdjustParam::matchingInterface() { // 执行算法 Algorithm algorithm; WF_ERROR_CODE result = algorithm.SpatialVariation(_importData); switch (result) { case WF_SUCCESS: { // 获取tif图层 ImageLayer* imageLayer = RenderNode::getInstance()->getImageLayer(); // 获取当前时间 QDateTime dateTime = QDateTime::currentDateTime(); QString strDate = dateTime.toString("yyyy-MM-dd hh:mm:ss"); // 获取文件名称 QDir dir = QCoreApplication::applicationDirPath().replace("/", "\\") + "\\tifMaxRect"; QString fileName; if(dir.isEmpty() == false) { QList list = dir.entryList(QDir::Files, QDir::Time); fileName = list.first(); } QString name = fileName.split(".").at(0); // 获取文件的类型 QString type = _importData.type; // 获取文件的中心点 MapPoint mapPoint; algorithm.calImageCenterCoord(dir.path() + "\\"+ fileName, mapPoint); double alt = algorithm.getElevationFromTiff(mapPoint._dLon, mapPoint._dLat); if(alt == 0) { mapPoint._dAlt = 1200; } else { mapPoint._dAlt = alt; } // 创建一个Image对象 if(name.isEmpty() == false && name.contains(".") == false && mapPoint._dLon != 0.0) { Image* image = imageLayer->createImage(name.toStdString(), strDate.toStdString(), type.toStdString(), mapPoint); // 将视点移动到新创建的Image的中心点位置上 double range = OSGRender::getInstance()->getRange(); OSGRender::getInstance()->setViewPoint("CorrectTif", image->getImageCenterCoord(), 0, -90.0, range); // 更新 emit OSGRender::getInstance()->updateImage(image); } else { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Cannot Create Image Object, Maybe No TIF File Generated"), QMessageBox::Ok, QMessageBox::Ok); } return true; } case WF_ERR_INPUT_FILE_OPEN_ERROR: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Input File Open Error, Maybe Some Incorrect Letters In Path"), QMessageBox::Ok, QMessageBox::Ok); break; } case WF_ERR_OUTPUT_FILE_SAVE_ERROR: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Output File Save Error"), QMessageBox::Ok, QMessageBox::Ok); break; } case WF_ERR_PROJECT: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Project Error"), QMessageBox::Ok, QMessageBox::Ok); break; } case WF_ERR_INVALID_PARAMETER: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Invalid Parameter"), QMessageBox::Ok, QMessageBox::Ok); break; } case WF_ERR_LICENSE_EXPIRED: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("License Expired"), QMessageBox::Ok, QMessageBox::Ok); break; } } return false; } /* -------------------------------------- 参数输入 -------------------------------------- */ ImageFileImport::ImageFileImport(QWidget* parent) : QDialog(parent) , ui(new Ui::ImageFileImport) { ui->setupUi(this); this->setWindowIcon(QIcon(QCoreApplication::applicationDirPath() + "\\dmatch.ico")); initImportImageFileWidget(); } ImageFileImport::~ImageFileImport() { delete ui; } void ImageFileImport::initImportImageFileWidget() { // 文件输入 ui->ImportImageLabel->setText(QObject::tr("Import Image(*.PNG *.JPEG) And Choose Image Type")); ui->OriginImageLabel->setText(QObject::tr("Origin Image File Path:")); ui->OriginImageExplore->setText(QObject::tr("Explore")); ui->ImageType->setText(QObject::tr("Image Type:")); type = new QButtonGroup(this); ui->InfraredImage->setText(QObject::tr("Infrared Image")); ui->VisibleImage->setText(QObject::tr("Visible Image")); type->addButton(ui->InfraredImage, 0); type->addButton(ui->VisibleImage, 1); // TEST:设置变量 // ui->LongitudeEdit->setText("109.625329"); // ui->LatitudeEdit->setText("40.843897"); // ui->AltitudeEdit->setText("5833"); // ui->CraftHeadingEdit->setText("307"); // ui->PitchingEdit->setText("-33.33"); // ui->HeadingEdit->setText("337.9"); // ui->CameraFocusEdit->setText("290"); // ui->CenterLongitudeEdit->setText("109.543167"); // ui->CenterLatitudeEdit->setText("40.861252"); // ui->CenterAltitudeEdit->setText("1240"); // ui->DistanceEdit->setText("8537.0"); // 飞行器参数 ui->CraftInfoLabel->setText(QObject::tr("Enter Craft Position And Posture")); ui->Longitude->setText(QObject::tr("Longitude:")); ui->LongitudeEdit->setPlaceholderText(QObject::tr("*Must(-180.0~180.0)")); ui->LongitudeUnit->setText("°"); ui->Latitude->setText(QObject::tr("Latitude:")); ui->LatitudeEdit->setPlaceholderText(QObject::tr("*Must(-90.0~90.0)")); ui->LatitudeUnit->setText("°"); ui->Altitude->setText(QObject::tr("Altitude:")); ui->AltitudeEdit->setPlaceholderText(QObject::tr("*Must(-100.0~10000.0)")); ui->AltitudeUnit->setText("m"); ui->CraftHeading->setText(QObject::tr("Craft Heading:")); ui->CraftHeadingEdit->setPlaceholderText(QObject::tr("*Must(-360.0~360.0)")); ui->CraftHeadingUnit->setText("°"); ui->CraftPitching->setText(QObject::tr("Craft Pitching:")); ui->CraftPitchingEdit->setPlaceholderText(QObject::tr("*Must(-90.0~90.0)")); ui->CraftPitchingUnit->setText("°"); ui->CraftRolling->setText(QObject::tr("Craft Rolling:")); ui->CraftRollingEdit->setPlaceholderText(QObject::tr("*Must(-180.0~180.0)")); ui->CraftRollingUnit->setText("°"); // 吊舱参数 ui->CameraInfoLabel->setText(QObject::tr("Enter Camera Position And Posture, Only ONE of 'Camera Focus' And 'Range' is Needed")); ui->Pitching->setText(QObject::tr("Pitching:")); ui->PitchingEdit->setPlaceholderText(QObject::tr("*Must(-90.0~90.0)")); ui->PitchingUnit->setText("°"); ui->Heading->setText(QObject::tr("Heading:")); ui->HeadingEdit->setPlaceholderText(QObject::tr("*Must(-360.0~360.0)")); ui->HeadingUnit->setText("°"); ui->CameraFocus->setText(QObject::tr("Camera Focus:")); ui->CameraFocusEdit->setPlaceholderText(QObject::tr("*Must(10.0~1000.0)")); ui->CameraFocusUnit->setText("mm"); ui->Range->setText(QObject::tr("Field Of View:")); ui->RangeEdit->setPlaceholderText(QObject::tr("(0.0~180.0)")); ui->RangeUnit->setText("°"); // 位置参数 ui->ImageInfoLabel->setText(QObject::tr("Enter Image Position Info")); ui->CenterLongitude->setText(QObject::tr("Center Longitude:")); ui->CenterLongitudeEdit->setPlaceholderText(QObject::tr("(-180.0~180.0)")); ui->CenterLongitudeUnit->setText("°"); ui->CenterLatitude->setText(QObject::tr("Center Latitude:")); ui->CenterLatitudeEdit->setPlaceholderText(QObject::tr("(-90.0~90.0)")); ui->CenterLatitudeUnit->setText("°"); ui->CenterAltitude->setText(QObject::tr("Center Altitude:")); ui->CenterAltitudeEdit->setPlaceholderText(QObject::tr("(-100.0~10000.0)")); ui->CenterAltitudeUnit->setText("m"); ui->Distance->setText(QObject::tr("Distance:")); ui->DistanceEdit->setPlaceholderText(QObject::tr("(100.0~50000.0)")); ui->DistanceUnit->setText("m"); // 底部按钮 ui->Clear->setText(QObject::tr("Clear")); ui->SmartMode->setText(QObject::tr("Smart Mode")); ui->ManualMode->setText(QObject::tr("Manual Mode")); ui->Cancel->setText(QObject::tr("Cancel")); // 获取文件路径 connect(ui->OriginImageExplore, SIGNAL(clicked(bool)), this, SLOT(getOriginImageFilePath())); // 确认并开始矫正 connect(ui->SmartMode, SIGNAL(clicked(bool)), this, SLOT(startSmartMode())); connect(ui->ManualMode, SIGNAL(clicked(bool)), this, SLOT(startManualMode())); // 清空输入框内容 connect(ui->Clear, SIGNAL(clicked(bool)), this, SLOT(clearParameter())); // 取消 connect(ui->Cancel, SIGNAL(clicked(bool)), this, SLOT(close())); } void ImageFileImport::getOriginImageFilePath() { QFileDialog* dialog = new QFileDialog(); // 查找上次打开的路径 QString runPath; if(lastFilePath.isEmpty() == false) { runPath = lastFilePath; } else { runPath = QCoreApplication::applicationDirPath(); } QString strPath = dialog->getOpenFileName(this, QObject::tr("Choose File"), runPath, "Image Files(*.png *.jpg *.jpeg)", nullptr); if(strPath.isEmpty() == false) { // 将路径传到ui中 ui->OriginImageEdit->setText(strPath); // 将路径所在文件夹路径记录 lastFilePath = strPath; } else { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("No file is selected"), QMessageBox::Ok, QMessageBox::Ok); } delete dialog; dialog = nullptr; } void ImageFileImport::clearParameter() { // 飞行器参数 ui->LongitudeEdit->clear(); ui->LatitudeEdit->clear(); ui->AltitudeEdit->clear(); ui->CraftHeadingEdit->clear(); ui->CraftPitchingEdit->clear(); ui->CraftRollingEdit->clear(); // 吊舱参数 ui->PitchingEdit->clear(); ui->HeadingEdit->clear(); ui->CameraFocusEdit->clear(); ui->RangeEdit->clear(); // 位置参数 ui->CenterLongitudeEdit->clear(); ui->CenterLatitudeEdit->clear(); ui->CenterAltitudeEdit->clear(); ui->DistanceEdit->clear(); } int ImageFileImport::isCorrectParam() { // 路径是否输入 if(ui->OriginImageEdit->text().isEmpty() == true) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Image File Path Not Enter."), QMessageBox::Ok, QMessageBox::Ok); return 1; } // 图像类型是否选择 if(type->checkedButton() == nullptr) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Please Choose Image Type."), QMessageBox::Ok, QMessageBox::Ok); return 2; } // 判断经纬高 if(ui->LongitudeEdit->text().isEmpty() == true || ui->LatitudeEdit->text().isEmpty() == true || ui->AltitudeEdit->text().isEmpty() == true) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Coordinate Not Enter."), QMessageBox::Ok, QMessageBox::Ok); return 3; } else { // 判断经纬高是否在合法范围内 double longitude = ui->LongitudeEdit->text().toDouble(); double latitude = ui->LatitudeEdit->text().toDouble(); double altitude = ui->AltitudeEdit->text().toDouble(); // 吊舱经度:必需,-180~180 bool isLongitudeValid = (longitude >= -180.0 && longitude <= 180.0); // 吊舱纬度:必需,-90~90 bool isLatitudeValid = (latitude >= -90.0 && latitude <= 90.0); // 吊舱高程:必需,-100~10000 bool isAltitudeValid = (altitude >= -100.0 && altitude <= 10000.0); if (!isLongitudeValid || !isLatitudeValid || !isAltitudeValid) { QMessageBox::warning(this, QObject::tr("Warning"), QObject::tr("Coordinate Data Illegal."), QMessageBox::Ok, QMessageBox::Ok); return 3; } } // 判断无人机姿态信息 if(ui->CraftHeadingEdit->text().isEmpty() == true || ui->CraftPitchingEdit->text().isEmpty() == true || ui->CraftRollingEdit->text().isEmpty() == true) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Craft Posture Not Enter."), QMessageBox::Ok, QMessageBox::Ok); return 4; } else { // 判断吊舱参数是否在合法范围内 double craftHeading = ui->CraftHeadingEdit->text().toDouble(); double craftPitching = ui->CraftPitchingEdit->text().toDouble(); double craftRolling = ui->CraftRollingEdit->text().toDouble(); // 吊舱航向角:必需,-360~360 bool isCraftHeadingValid = (craftHeading >= -360.0 && craftHeading <= 360.0); // 吊舱俯仰角:必需,-90~90 bool isCraftPitchingValid = (craftPitching >= -90.0 && craftPitching <= 90.0); // 吊舱滚转角:必需,-180~180 bool isCraftRollingValid = (craftRolling >= -180.0 && craftRolling <= 180.0); if(!isCraftHeadingValid || !isCraftPitchingValid || !isCraftRollingValid) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Craft Posture Data Illegal."), QMessageBox::Ok, QMessageBox::Ok); return 4; } } // 判断相机信息 if(ui->PitchingEdit->text().isEmpty() == true || ui->HeadingEdit->text().isEmpty() == true) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Camera Info Not Enter"), QMessageBox::Ok, QMessageBox::Ok); return 5; } else { // 判断俯仰角和航向角是否在合法范围内 double pitching = ui->PitchingEdit->text().toDouble(); double heading = ui->HeadingEdit->text().toDouble(); // 相机俯仰角:必需,-90~90 bool isPitchingValid = (pitching >= -90.0 && pitching <= 90.0); // 相机航向角:必需,-360~360 bool isHeadingValid = (heading >= -360.0 && heading <= 360.0); if(!isPitchingValid || !isHeadingValid) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Camera Info Data Illegal"), QMessageBox::Ok, QMessageBox::Ok); return 5; } // 判断相机焦距和视场角信息:二选一 if(ui->CameraFocusEdit->text().isEmpty() == true && ui->RangeEdit->text().isEmpty() == true) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Camera Info Not Totally Enter"), QMessageBox::Ok, QMessageBox::Ok); return 5; } else if(ui->CameraFocusEdit->text().isEmpty() == false && ui->RangeEdit->text().isEmpty() == false) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Camera Focus And Range Only Need ONE"), QMessageBox::Ok, QMessageBox::Ok); return 5; } else { // 判断俯仰角和航向角是否在合法范围内 double cameraFocus = 0.0; double range = 0.0; if(ui->CameraFocusEdit->text().isEmpty() == false) { // 当输入的是相机焦距 cameraFocus = ui->CameraFocusEdit->text().toDouble(); } else if(ui->CameraFocusEdit->text().isEmpty() == false) { // 当输入的是视场角 range = ui->RangeEdit->text().toDouble(); } // 相机焦距:10~1000 bool isCameraFocusValid = (cameraFocus >= 10.0 && cameraFocus <= 1000.0); // 视场角:10~1000 bool isRangeValid = (range >= 1.0 && range <= 100.0); if(!isCameraFocusValid || !isRangeValid) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Camera Info Data Illegal"), QMessageBox::Ok, QMessageBox::Ok); return 5; } } } // 判断影像信息 if(ui->DistanceEdit->text().isEmpty() == false || ui->CenterLongitudeEdit->text().isEmpty() == false || ui->CenterLatitudeEdit->text().isEmpty() == false || ui->CenterAltitudeEdit->text().isEmpty() == false) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Image Info Not Totally Enter"), QMessageBox::Ok, QMessageBox::Ok); return 6; } else if(ui->DistanceEdit->text().isEmpty() == false && ui->CenterLongitudeEdit->text().isEmpty() == false && ui->CenterLatitudeEdit->text().isEmpty() == false && ui->CenterAltitudeEdit->text().isEmpty() == false) { // 判断俯仰角和航向角是否在合法范围内 double distance = ui->DistanceEdit->text().toDouble(); double centerLongitude = ui->CenterLongitudeEdit->text().toDouble(); double centerLatitude = ui->CenterLatitudeEdit->text().toDouble(); double centerAltitude = ui->CenterAltitudeEdit->text().toDouble(); // 相机到影像中心点距离:100~50000 bool isDistanceValid = (distance >= 100.0 && distance <= 50000.0); // 影像中心点经度:-180~180 bool isCenterLongitudeValid = (centerLongitude >= -180.0 && centerLongitude <= 180.0); // 影像中心点纬度:-180~180 bool isCenterLatitudeValid = (centerLatitude >= -90.0 && centerLatitude <= 90.0); // 影像中心点高程:-100~10000 bool isCenterAltitudeValid = (centerAltitude >= -100.0 && centerAltitude <= 10000.0); if(!isDistanceValid || !isCenterLongitudeValid || !isCenterLatitudeValid || !isCenterAltitudeValid) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Image Info Data Illegal"), QMessageBox::Ok, QMessageBox::Ok); return 6; } } // 全部检验通过则返回0 return 0; } void ImageFileImport::startSmartMode() { // 判断是否可以执行算法 int ret = isCorrectParam(); if(ret != 0) { return; } else { ImportData importData; // 将参数写入到对象中 importData.originImagePath = ui->OriginImageEdit->text(); importData.type = type->checkedButton()->text(); importData.lon = ui->LongitudeEdit->text(); importData.lat = ui->LatitudeEdit->text(); importData.alt = ui->AltitudeEdit->text(); importData.craftHeading = ui->CraftHeadingEdit->text(); importData.pitching = ui->PitchingEdit->text(); importData.heading = ui->HeadingEdit->text(); // 将未输入的参数赋值0 importData.craftPitching = ui->CraftPitchingEdit->text().isEmpty() ? "0" : ui->CraftPitchingEdit->text(); importData.craftRolling = ui->CraftRollingEdit->text().isEmpty() ? "0" : ui->CraftRollingEdit->text(); importData.cameraFocus = ui->CameraFocusEdit->text().isEmpty() ? "0" : ui->CameraFocusEdit->text(); importData.range = ui->RangeEdit->text().isEmpty() ? "0" : ui->RangeEdit->text(); importData.centerLon = ui->CenterLongitudeEdit->text().isEmpty() ? "0" : ui->CenterLongitudeEdit->text(); importData.centerLat = ui->CenterLatitudeEdit->text().isEmpty() ? "0" : ui->CenterLatitudeEdit->text(); importData.centerAlt = ui->CenterAltitudeEdit->text().isEmpty() ? "0" : ui->CenterAltitudeEdit->text(); importData.distance = ui->DistanceEdit->text().isEmpty() ? "-1.0" : ui->DistanceEdit->text(); // 执行一次特征匹配算法 bool matchResult = matchingInterface(importData); this->close(); if(matchResult == true) { // 提示特征匹配算法完成 QMessageBox* msgBox = new QMessageBox(QMessageBox::Information, "Finish", "Auto Matching Interface Is Complete.\n YES - Finish Matching\n NO - Use Manual Matching", QMessageBox::Yes | QMessageBox::No, this); msgBox->setWindowModality(Qt::NonModal); // 连接按钮点击信号到槽函数 connect(msgBox, &QDialog::finished, this, [=](int result) { if(result == QMessageBox::Yes) { // 若YES则完成矫正,关闭窗口并返回 return; } else if(result == QMessageBox::No) { // 若NO则也继续执行空间变换算法 spatialTranFlow(importData); } else { // 关闭窗口也终止执行 return; } msgBox->close(); delete msgBox; }); msgBox->show(); } else { // 若不正确,则自动调用空间变换算法 spatialTranFlow(importData); } } this->close(); } void ImageFileImport::startManualMode() { // 判断是否可以执行算法 int ret = isCorrectParam(); if(ret != 0) { if(ret == 3) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Coordinate Not Enter or Data Illegal"), QMessageBox::Ok, QMessageBox::Ok); } if(ret == 4) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Craft Posture Not Enter or Data Illegal"), QMessageBox::Ok, QMessageBox::Ok); } if(ret == 5) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Camera Info Not Enter or Data Illegal"), QMessageBox::Ok, QMessageBox::Ok); } if(ret == 6) { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Image Info Not Enter or Data Illegal"), QMessageBox::Ok, QMessageBox::Ok); } return; } else { ImportData importData; // 将参数写入到对象中 importData.originImagePath = ui->OriginImageEdit->text(); importData.type = type->checkedButton()->text(); importData.lon = ui->LongitudeEdit->text(); importData.lat = ui->LatitudeEdit->text(); importData.alt = ui->AltitudeEdit->text(); importData.craftHeading = ui->CraftHeadingEdit->text(); importData.pitching = ui->PitchingEdit->text(); importData.heading = ui->HeadingEdit->text(); // 将未输入的参数赋值0 importData.craftPitching = ui->CraftPitchingEdit->text().isEmpty() ? "0" : ui->CraftPitchingEdit->text(); importData.craftRolling = ui->CraftRollingEdit->text().isEmpty() ? "0" : ui->CraftRollingEdit->text(); importData.cameraFocus = ui->CameraFocusEdit->text().isEmpty() ? "0" : ui->CameraFocusEdit->text(); importData.range = ui->RangeEdit->text().isEmpty() ? "0" : ui->RangeEdit->text(); importData.centerLon = ui->CenterLongitudeEdit->text().isEmpty() ? "0" : ui->CenterLongitudeEdit->text(); importData.centerLat = ui->CenterLatitudeEdit->text().isEmpty() ? "0" : ui->CenterLatitudeEdit->text(); importData.centerAlt = ui->CenterAltitudeEdit->text().isEmpty() ? "0" : ui->CenterAltitudeEdit->text(); importData.distance = ui->DistanceEdit->text().isEmpty() ? "-1.0" : ui->DistanceEdit->text(); // 执行空间变换算法 spatialTranFlow(importData); } this->close(); } void ImageFileImport::spatialTranFlow(ImportData importData) { // 调用空间变换算法 bool transResult = spatialTrans(importData); if(transResult == false) { // 若不正确,则终止矫正流程 return; } else { // 若正确,则继续微调步骤,打开微调窗口 if(_adjustWidget == nullptr) { _adjustWidget = new AdjustParam(this->parentWidget()); } // 将参数传给微调窗口 _adjustWidget->setParameter(importData); // 初始化微调窗口 _adjustWidget->initAdjustParamWidget(); // 打开微调窗口 _adjustWidget->show(); } } bool ImageFileImport::matchingInterface(ImportData importData) { // 加载等待窗口 WaitingWidget* wait = new WaitingWidget(); wait->show(); // 执行算法 Algorithm algorithm; bool result = algorithm.FeatureMatching(importData); if(result == true) { wait->close(); QMessageBox::information(this, QObject::tr("Finished"), QObject::tr("Correction Finished"), QMessageBox::Ok, QMessageBox::Ok); // 获取tif图层 ImageLayer* imageLayer = RenderNode::getInstance()->getImageLayer(); // 获取当前时间 QDateTime dateTime = QDateTime::currentDateTime(); QString strDate = dateTime.toString("yyyy-MM-dd-hh-mm-ss"); // 获取文件名称 QString path = QCoreApplication::applicationDirPath(); path = path.replace("/", "\\"); QDir dir(path + "\\tifMaxRect"); QString fileName = dir.entryList(QDir::Files, QDir::Time).first(); QStringList nameList = fileName.split("."); QString name = nameList.at(0); // 获取文件的类型 QString type = importData.type; // 获取文件的中心点 // 获取文件的中心点 MapPoint mapPoint; algorithm.calImageCenterCoord(dir.path() + "\\" + fileName, mapPoint); double alt = algorithm.getElevationFromTiff(mapPoint._dLon, mapPoint._dLat); if(alt == 0) { mapPoint._dAlt = 1200; } else { mapPoint._dAlt = alt; } // 创建一个tif对象 if(name.isEmpty() == false && name.contains(".") == false && mapPoint._dLon != 0.0) { Image* pImage = imageLayer->createImage(name.toStdString(), strDate.toStdString(), type.toStdString(), mapPoint); // 将视点移动到新创建的Image的中心点位置上 OSGRender::getInstance()->setViewPoint("CorrectTif", pImage->getImageCenterCoord(), 0, -90.0, mapPoint._dAlt + 2000); // 将图像更新到三维地球上 emit OSGRender::getInstance()->updateImage(pImage); } else { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Cannot Create Image Object"), QMessageBox::Ok, QMessageBox::Ok); } } else { wait->close(); QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Correction Error, Please Check Parameter Enter"), QMessageBox::Ok, QMessageBox::Ok); } return result; } bool ImageFileImport::spatialTrans(ImportData importData) { // 执行算法 Algorithm algorithm; WF_ERROR_CODE result = algorithm.SpatialVariation(importData); switch (result) { case WF_SUCCESS: { // 获取tif图层 ImageLayer* imageLayer = RenderNode::getInstance()->getImageLayer(); // 获取当前时间 QDateTime dateTime = QDateTime::currentDateTime(); QString strDate = dateTime.toString("yyyy-MM-dd hh:mm:ss"); // 获取文件名称 QDir dir = QCoreApplication::applicationDirPath().replace("/", "\\") + "\\tifMaxRect"; QString fileName; if(dir.isEmpty() == false) { fileName = dir.entryList(QDir::Files, QDir::Time).first(); } QString name = fileName.split(".").at(0); // 获取文件的类型 QString type = importData.type; // 获取文件的中心点 MapPoint mapPoint; algorithm.calImageCenterCoord(dir.path() + "\\"+ fileName, mapPoint); double alt = algorithm.getElevationFromTiff(mapPoint._dLon, mapPoint._dLat); if(alt == 0) { mapPoint._dAlt = 1200; } else { mapPoint._dAlt = alt; } // 创建一个Image对象 if(name.isEmpty() == false && name.contains(".") == false && mapPoint._dLon != 0.0) { Image* image = imageLayer->createImage(name.toStdString(), strDate.toStdString(), type.toStdString(), mapPoint); // 将视点移动到新创建的Image的中心点位置上 OSGRender::getInstance()->setViewPoint("CorrectTif", image->getImageCenterCoord(), 0, -90.0, mapPoint._dAlt + 2000); // 将图像更新到三维地球上 emit OSGRender::getInstance()->updateImage(image); } else { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Cannot Create Image Object, Maybe No TIF File Generated"), QMessageBox::Ok, QMessageBox::Ok); } return true; } case WF_ERR_INPUT_FILE_OPEN_ERROR: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Input File Open Error, Maybe Some Incorrect Letters In Path"), QMessageBox::Ok, QMessageBox::Ok); break; } case WF_ERR_OUTPUT_FILE_SAVE_ERROR: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Output File Save Error"), QMessageBox::Ok, QMessageBox::Ok); break; } case WF_ERR_PROJECT: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Project Error"), QMessageBox::Ok, QMessageBox::Ok); break; } case WF_ERR_INVALID_PARAMETER: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("Invalid Parameter"), QMessageBox::Ok, QMessageBox::Ok); break; } case WF_ERR_LICENSE_EXPIRED: { QMessageBox::warning(this, QObject::tr("Waring"), QObject::tr("License Expired"), QMessageBox::Ok, QMessageBox::Ok); break; } } return false; } WaitingWidget::WaitingWidget(QWidget* parent) : QDialog(parent) { setWindowModality(Qt::WindowModal); this->setWindowTitle(QObject::tr("Waiting")); QVBoxLayout* centerLayout = new QVBoxLayout(); this->setLayout(centerLayout); // 添加组件 QLabel* loading = new QLabel(this); loading->setText(QObject::tr("Algorithm Is Runing, Please Wait...")); centerLayout->addWidget(loading); this->show(); } WaitingWidget::~WaitingWidget() {}