旧 GUI 张冠李戴修复:step6/step8 ML 训练 CSV 强制读 Step 6 特征结果 + step3 默认算法切到 goodman

This commit is contained in:
DXC
2026-06-16 17:53:55 +08:00
parent afe9eaff2c
commit bd4263d2ca
4 changed files with 77 additions and 36 deletions

View File

@ -199,7 +199,43 @@ class Step6FeaturePanel(QWidget):
glint_path = os.path.join(self.work_dir or '', glint_path).replace('\\', '/')
self.glint_mask_file.set_path(glint_path)
# 4. 自动填充输出路径(基于工作目录
# 4. 自动填充去耀斑影像路径(上游 Step 3 的输出,修复张冠李戴
deglint_path = None
if pipeline and hasattr(pipeline, 'step_outputs'):
step3_outputs = getattr(pipeline, 'step_outputs', {}).get('step3', {})
deglint_path = (
step3_outputs.get('deglint_image')
or step3_outputs.get('output_path')
or step3_outputs.get('output_file')
or step3_outputs.get('deglint_img_path')
)
# 回退:从 step3 面板 widget 直接读取(可能是相对路径)
if not deglint_path and hasattr(main_window, 'step3_panel'):
step3_widget = getattr(main_window.step3_panel, 'output_file', None)
if step3_widget is not None and hasattr(step3_widget, 'get_path'):
deglint_path = step3_widget.get_path() or ""
# 兜底:扫描 3_deglint 目录下的 .bsq优先 goodman兼容 kutser/插值)
if not deglint_path and self.work_dir:
deglint_dir = resolve_subdir(self.work_dir, 'deglint')
if os.path.isdir(deglint_dir):
bsq_files = [
f for f in os.listdir(deglint_dir)
if f.lower().endswith('.bsq')
]
# 优先匹配 goodman默认算法其次按文件名排序保证稳定
bsq_files.sort(key=lambda n: (0 if 'goodman' in n.lower() else 1, n))
if bsq_files:
deglint_path = os.path.join(deglint_dir, bsq_files[0]).replace('\\', '/')
if deglint_path:
# 若为相对路径,使用 work_dir 合成为绝对路径
if not os.path.isabs(deglint_path):
deglint_path = os.path.join(self.work_dir or '', deglint_path).replace('\\', '/')
existing_deglint = self.deglint_img_file.get_path()
if not existing_deglint or not existing_deglint.strip():
self.deglint_img_file.set_path(deglint_path)
# 5. 自动填充输出路径(基于工作目录)
if self.work_dir:
output_dir = resolve_subdir(self.work_dir, 'spectral_feature')
os.makedirs(output_dir, exist_ok=True)
@ -208,7 +244,7 @@ class Step6FeaturePanel(QWidget):
else:
self.output_file.set_path("")
# 5. 尝试从 Step5 Clean 界面读取已处理的清洗后 CSV 路径,自动填入本面板
# 6. 尝试从 Step5 Clean 界面读取已处理的清洗后 CSV 路径,自动填入本面板
main_window = self.window()
if main_window and hasattr(main_window, 'step5_clean_panel'):
step5_clean_output_path = main_window.step5_clean_panel.output_file.get_path()

View File

@ -137,6 +137,15 @@ class Step8MlTrainPanel(QWidget):
self.feature_start.setText("374.285004")
params_layout.addRow("特征起始列:", self.feature_start)
# 特征起始列名提示:用记事本打开 training_spectra.csv 确认首个波长的精确表头
feature_start_hint = QLabel(
"提示:请使用记事本打开 training_spectra.csv 确认首个波长的精确表头名称"
"(如 374.285 或 374.285004)并在此填入,避免因浮点精度差异导致列名匹配失败。"
)
feature_start_hint.setWordWrap(True)
feature_start_hint.setStyleSheet("color: #666; font-size: 10px;")
params_layout.addRow(feature_start_hint)
self.cv_folds = QSpinBox()
self.cv_folds.setRange(2, 10)
self.cv_folds.setValue(3)
@ -357,30 +366,20 @@ class Step8MlTrainPanel(QWidget):
else:
self.work_dir = None
# 1. 尝试从 Step5 界面读取训练数据路径,并确保为绝对路径
# 修复张冠李戴:原代码 main_window.step5_panel 不存在,正确属性是 step5_clean_panel
# 1. 强制读 Step 6 的 training_spectra.csv光谱特征提取结果
# 修复张冠李戴:原链路 STEP_DATA_SOURCE['training_spectra_csv'] → step5_clean_panel
# 错误地指向了 Step 5 的 processed_data.csv纯清洗数据不含光谱特征
# 实际 ML 训练需要的特征数据来自 Step 6 的 6_Spectral_Feature_Extraction/training_spectra.csv
main_window = self.window()
step5_output = get_step_output_path(
main_window, 'training_spectra_csv', work_dir=self.work_dir,
widget_attr='output_file', fallback_key='step6_feature',
)
if step5_output:
self.training_csv_file.set_path(step5_output)
else:
# 回退:从 Step5 的 config 字典中查找可能的键名
step5_panel = getattr(main_window, 'step5_clean_panel', None)
if step5_panel and hasattr(step5_panel, 'get_config'):
step5_cfg = step5_panel.get_config()
step5_csv = (
step5_cfg.get('training_csv_path')
or step5_cfg.get('output_file')
or step5_cfg.get('csv_path')
or step5_cfg.get('output_csv')
)
if step5_csv:
if not os.path.isabs(step5_csv):
step5_csv = os.path.join(self.work_dir or '', step5_csv).replace('\\', '/')
self.training_csv_file.set_path(step5_csv)
existing_training_csv = self.training_csv_file.get_path()
if not existing_training_csv or not existing_training_csv.strip():
if self.work_dir:
step6_dir = resolve_subdir(self.work_dir, 'spectral_feature')
step6_training_csv = os.path.join(
step6_dir, 'training_spectra.csv'
).replace('\\', '/')
if step6_training_csv:
self.training_csv_file.set_path(step6_training_csv)
# 2. 自动填充输出文件路径(基于工作目录和输入文件名)
# 输入是 training_spectra.csv → 输出 {work_dir}/7_Water_Quality_Indices/training_spectra_indices.csv

View File

@ -238,15 +238,19 @@ class Step8NonEmpiricalPanel(QWidget):
# 借用父组件的 window() 方法,安全绕过当前类的命名冲突
parent_widget = self.parentWidget()
main_window = parent_widget.window() if parent_widget else None
# 1. 尝试从 Step5数据清洗读取训练光谱 CSV修复张冠李戴原 main_window.step5_panel 不存在
step5_output_path = get_step_output_path(
main_window, 'training_spectra_csv', work_dir=self.work_dir,
widget_attr='output_file', fallback_key='step6_feature',
)
if step5_output_path:
existing = self.training_csv_file.get_path()
if not existing or not existing.strip():
self.training_csv_file.set_path(step5_output_path)
# 1. 强制读 Step 6 的 training_spectra.csv光谱特征提取结果
# 修复张冠李戴:原链路 STEP_DATA_SOURCE['training_spectra_csv'] → step5_clean_panel
# 错误地指向 Step 5 的 processed_data.csv纯清洗数据不含光谱特征
# 实际非经验建模需要的特征数据来自 Step 6 的 6_Spectral_Feature_Extraction/training_spectra.csv
existing_csv = self.training_csv_file.get_path()
if not existing_csv or not existing_csv.strip():
if self.work_dir:
step6_dir = resolve_subdir(self.work_dir, 'spectral_feature')
step6_training_csv = os.path.join(
step6_dir, 'training_spectra.csv'
).replace('\\', '/')
if step6_training_csv:
self.training_csv_file.set_path(step6_training_csv)
# 2. 自动填充输出目录8_Regression_Modeling
if self.work_dir:

View File

@ -1367,7 +1367,7 @@ class WaterQualityGUI(QMainWindow):
self.step_default_outputs = {
'step1': "1_water_mask/water_mask_from_ndwi.dat",
'step2': "2_Glint_Detection/severe_glint_area.dat",
'step3': "3_deglint/deglint_kutser.bsq",
'step3': "3_deglint/deglint_goodman.bsq",
'step4_sampling': "4_sampling/sampling_spectra.csv",
'step5_clean': "5_Data_Cleaning/processed_data.csv",
'step6_feature': "6_Spectral_Feature_Extraction/training_spectra.csv",
@ -2361,9 +2361,11 @@ class WaterQualityGUI(QMainWindow):
deglint_path = work_path / rel_path
if deglint_path.exists():
return str(deglint_path)
# 还要检查插值方法生成的文件
# 还要检查 Kutser 算法输出与插值方法生成的文件
deglint_dir = work_path / "3_deglint"
if deglint_dir.exists():
for file_path in deglint_dir.glob("deglint_*.bsq"):
return str(file_path)
for file_path in deglint_dir.glob("interpolated_*.bsq"):
return str(file_path)
elif rel_path: