fix: 公式报告 4 项修复 — 通用章节+AI接口+图片路径+标题数字
修复一: _generate_formula_report 封面后恢复 _add_company_description_page/doc _add_data_acquisition_section/doc _add_data_processing_section/doc 修复二: _call_minimax_text / _call_minimax_vision URL 自动补齐 /chat/completions 后缀 修复三: _call_minimax_vision MIME 类型动态检测 (.png→image/png, 其他→image/jpeg) 修复四: _add_hyperspectral_images_section 航线图搜索: 多路径 + rglob 递归查找 去掉所有硬编码编号 (3.1/图3-2/3-3/3-4/3-5/3-6)
This commit is contained in:
@ -368,6 +368,8 @@ class WaterQualityReportGenerator:
|
|||||||
return "(Minimax API Key 未配置,请设置 MINIMAX_API_KEY 环境变量)"
|
return "(Minimax API Key 未配置,请设置 MINIMAX_API_KEY 环境变量)"
|
||||||
|
|
||||||
url = self.minimax_base_url
|
url = self.minimax_base_url
|
||||||
|
if not url.endswith("/chat/completions"):
|
||||||
|
url = f"{url.rstrip('/')}/chat/completions"
|
||||||
|
|
||||||
payload: Dict[str, Any] = {
|
payload: Dict[str, Any] = {
|
||||||
"model": self.minimax_text_model,
|
"model": self.minimax_text_model,
|
||||||
@ -433,6 +435,12 @@ class WaterQualityReportGenerator:
|
|||||||
return f"(读取图片失败:{e})"
|
return f"(读取图片失败:{e})"
|
||||||
|
|
||||||
url = self.minimax_base_url
|
url = self.minimax_base_url
|
||||||
|
if not url.endswith("/chat/completions"):
|
||||||
|
url = f"{url.rstrip('/')}/chat/completions"
|
||||||
|
|
||||||
|
# 动态 MIME 类型:PNG 和 JPEG 分别处理,避免 API 400
|
||||||
|
ext = image_path.suffix.lower()
|
||||||
|
mime_type = "image/png" if ext == ".png" else "image/jpeg"
|
||||||
|
|
||||||
payload: Dict[str, Any] = {
|
payload: Dict[str, Any] = {
|
||||||
"model": self.minimax_vision_model,
|
"model": self.minimax_vision_model,
|
||||||
@ -444,7 +452,7 @@ class WaterQualityReportGenerator:
|
|||||||
{"type": "text", "text": user_prompt},
|
{"type": "text", "text": user_prompt},
|
||||||
{
|
{
|
||||||
"type": "image_url",
|
"type": "image_url",
|
||||||
"image_url": {"url": f"data:image/jpeg;base64,{img_b64}"},
|
"image_url": {"url": f"data:{mime_type};base64,{img_b64}"},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -961,6 +969,11 @@ class WaterQualityReportGenerator:
|
|||||||
try: progress.update(1)
|
try: progress.update(1)
|
||||||
except Exception: pass
|
except Exception: pass
|
||||||
|
|
||||||
|
# ── 通用章节:单位介绍 / 数据采集 / 工作流程 ──
|
||||||
|
self._add_company_description_page(doc)
|
||||||
|
self._add_data_acquisition_section(doc)
|
||||||
|
self._add_data_processing_section(doc)
|
||||||
|
|
||||||
# ── 1. 项目背景 ──
|
# ── 1. 项目背景 ──
|
||||||
h1 = doc.add_heading("1 项目背景", level=1)
|
h1 = doc.add_heading("1 项目背景", level=1)
|
||||||
self._style_heading(h1, 1)
|
self._style_heading(h1, 1)
|
||||||
@ -1422,29 +1435,33 @@ class WaterQualityReportGenerator:
|
|||||||
|
|
||||||
def _add_hyperspectral_images_section(self, doc):
|
def _add_hyperspectral_images_section(self, doc):
|
||||||
"""添加高光谱图像、耀斑区域和去耀斑图像展示"""
|
"""添加高光谱图像、耀斑区域和去耀斑图像展示"""
|
||||||
h = doc.add_heading("3.1 高光谱图像处理过程", level=2)
|
h = doc.add_heading("高光谱图像处理过程", level=2)
|
||||||
self._style_heading(h, level=2)
|
self._style_heading(h, level=2)
|
||||||
|
|
||||||
work_dir_path = self.work_dir
|
work_dir_path = self.work_dir
|
||||||
vis_dir = self.visualization_dir
|
vis_dir = self.visualization_dir
|
||||||
|
|
||||||
# 0. 航线规划图
|
# 0. 航线规划图(鲁棒搜索:多路径 + rglob)
|
||||||
flight_path_img_path = work_dir_path / "12_visualization" / "flight_paths"
|
|
||||||
h3 = doc.add_heading("航线规划:", level=3)
|
h3 = doc.add_heading("航线规划:", level=3)
|
||||||
self._style_heading(h3, level=3)
|
self._style_heading(h3, level=3)
|
||||||
|
|
||||||
# 查找航线图文件
|
|
||||||
flight_map_files = []
|
flight_map_files = []
|
||||||
if flight_path_img_path.exists():
|
flight_search_dirs = [
|
||||||
flight_map_files = list(flight_path_img_path.glob("*.png")) + list(flight_path_img_path.glob("*.jpg"))
|
work_dir_path / "12_visualization" / "flight_paths",
|
||||||
|
vis_dir / "flight_paths",
|
||||||
|
vis_dir,
|
||||||
|
]
|
||||||
|
for search_dir in flight_search_dirs:
|
||||||
|
if search_dir.exists():
|
||||||
|
flight_map_files = list(search_dir.rglob("*.png")) + list(search_dir.rglob("*.jpg"))
|
||||||
|
if flight_map_files:
|
||||||
|
break
|
||||||
|
|
||||||
if flight_map_files:
|
if flight_map_files:
|
||||||
# 使用最新的航线图文件
|
|
||||||
latest_flight_map = max(flight_map_files, key=lambda p: p.stat().st_mtime)
|
latest_flight_map = max(flight_map_files, key=lambda p: p.stat().st_mtime)
|
||||||
success = self._add_image_with_caption(doc, str(latest_flight_map), "图3-1 航线规划", width=Inches(5.5))
|
success = self._add_image_with_caption(doc, str(latest_flight_map), "航线规划", width=Inches(5.5))
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
# AI 分析航线规划图
|
|
||||||
flight_analysis = self._analyze_flight_path_image(str(latest_flight_map))
|
flight_analysis = self._analyze_flight_path_image(str(latest_flight_map))
|
||||||
self._add_ai_analysis_paragraph(doc, flight_analysis)
|
self._add_ai_analysis_paragraph(doc, flight_analysis)
|
||||||
else:
|
else:
|
||||||
@ -1455,7 +1472,7 @@ class WaterQualityReportGenerator:
|
|||||||
h3 = doc.add_heading("高光谱原始影像:", level=3)
|
h3 = doc.add_heading("高光谱原始影像:", level=3)
|
||||||
self._style_heading(h3, level=3)
|
self._style_heading(h3, level=3)
|
||||||
if hyperspectral_img_path.exists():
|
if hyperspectral_img_path.exists():
|
||||||
self._add_image_with_caption(doc, str(hyperspectral_img_path), "图3-2 高光谱原始影像", width=Inches(5.5))
|
self._add_image_with_caption(doc, str(hyperspectral_img_path), "高光谱原始影像", width=Inches(5.5))
|
||||||
else:
|
else:
|
||||||
doc.add_paragraph("[高光谱原始影像 - 文件未找到]")
|
doc.add_paragraph("[高光谱原始影像 - 文件未找到]")
|
||||||
|
|
||||||
@ -1465,7 +1482,7 @@ class WaterQualityReportGenerator:
|
|||||||
self._style_heading(h3, level=3)
|
self._style_heading(h3, level=3)
|
||||||
if water_mask_overlay_path.exists():
|
if water_mask_overlay_path.exists():
|
||||||
success = self._add_image_with_caption(doc, str(water_mask_overlay_path),
|
success = self._add_image_with_caption(doc, str(water_mask_overlay_path),
|
||||||
"图3-3 水体区域识别(蓝色半透明区域为水域)",
|
"水体区域识别(蓝色半透明区域为水域)",
|
||||||
width=Inches(5.5))
|
width=Inches(5.5))
|
||||||
if success:
|
if success:
|
||||||
water_analysis = self._analyze_water_mask_overlay(str(water_mask_overlay_path))
|
water_analysis = self._analyze_water_mask_overlay(str(water_mask_overlay_path))
|
||||||
@ -1480,13 +1497,13 @@ class WaterQualityReportGenerator:
|
|||||||
h3 = doc.add_heading("耀斑区域识别结果:", level=3)
|
h3 = doc.add_heading("耀斑区域识别结果:", level=3)
|
||||||
self._style_heading(h3, level=3)
|
self._style_heading(h3, level=3)
|
||||||
if glint_img_path.exists():
|
if glint_img_path.exists():
|
||||||
self._add_image_with_caption(doc, str(glint_img_path), "图3-4 耀斑区域识别结果", width=Inches(5.5))
|
self._add_image_with_caption(doc, str(glint_img_path), "耀斑区域识别结果", width=Inches(5.5))
|
||||||
else:
|
else:
|
||||||
# 尝试查找其他可能的耀斑预览图
|
# 尝试查找其他可能的耀斑预览图
|
||||||
glint_files = list(vis_dir.glob("glint_deglint_previews/*glint*.png"))
|
glint_files = list(vis_dir.glob("glint_deglint_previews/*glint*.png"))
|
||||||
if glint_files:
|
if glint_files:
|
||||||
glint_img_path = glint_files[0]
|
glint_img_path = glint_files[0]
|
||||||
self._add_image_with_caption(doc, str(glint_img_path), "图3-4 耀斑区域识别结果", width=Inches(5.5))
|
self._add_image_with_caption(doc, str(glint_img_path), "耀斑区域识别结果", width=Inches(5.5))
|
||||||
else:
|
else:
|
||||||
doc.add_paragraph("[耀斑区域识别结果 - 文件未找到]")
|
doc.add_paragraph("[耀斑区域识别结果 - 文件未找到]")
|
||||||
|
|
||||||
@ -1497,13 +1514,13 @@ class WaterQualityReportGenerator:
|
|||||||
h3 = doc.add_heading("去除耀斑后的影像:", level=3)
|
h3 = doc.add_heading("去除耀斑后的影像:", level=3)
|
||||||
self._style_heading(h3, level=3)
|
self._style_heading(h3, level=3)
|
||||||
if deglint_img_path.exists():
|
if deglint_img_path.exists():
|
||||||
self._add_image_with_caption(doc, str(deglint_img_path), "图3-5 去除耀斑后的高光谱影像", width=Inches(5.5))
|
self._add_image_with_caption(doc, str(deglint_img_path), "去除耀斑后的高光谱影像", width=Inches(5.5))
|
||||||
else:
|
else:
|
||||||
# 尝试查找其他去耀斑预览图
|
# 尝试查找其他去耀斑预览图
|
||||||
deglint_files = list(vis_dir.glob("glint_deglint_previews/*deglint*.png"))
|
deglint_files = list(vis_dir.glob("glint_deglint_previews/*deglint*.png"))
|
||||||
if deglint_files:
|
if deglint_files:
|
||||||
deglint_img_path = deglint_files[0]
|
deglint_img_path = deglint_files[0]
|
||||||
self._add_image_with_caption(doc, str(deglint_img_path), "图3-5 去除耀斑后的影像", width=Inches(5.5))
|
self._add_image_with_caption(doc, str(deglint_img_path), "去除耀斑后的影像", width=Inches(5.5))
|
||||||
else:
|
else:
|
||||||
doc.add_paragraph("[去除耀斑后的影像 - 文件未找到]")
|
doc.add_paragraph("[去除耀斑后的影像 - 文件未找到]")
|
||||||
|
|
||||||
@ -1531,7 +1548,7 @@ class WaterQualityReportGenerator:
|
|||||||
if sampling_map_files:
|
if sampling_map_files:
|
||||||
# 使用最新的采样点分布图文件
|
# 使用最新的采样点分布图文件
|
||||||
latest_sampling_map = max(sampling_map_files, key=lambda p: p.stat().st_mtime)
|
latest_sampling_map = max(sampling_map_files, key=lambda p: p.stat().st_mtime)
|
||||||
success = self._add_image_with_caption(doc, str(latest_sampling_map), "图3-6 采样点分布图", width=Inches(5.5))
|
success = self._add_image_with_caption(doc, str(latest_sampling_map), "采样点分布图", width=Inches(5.5))
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
# AI 分析采样点分布图
|
# AI 分析采样点分布图
|
||||||
|
|||||||
Reference in New Issue
Block a user