diff --git a/src/postprocessing/report_word.py b/src/postprocessing/report_word.py index 382f9f0..88fc44b 100644 --- a/src/postprocessing/report_word.py +++ b/src/postprocessing/report_word.py @@ -368,6 +368,8 @@ class WaterQualityReportGenerator: return "(Minimax API Key 未配置,请设置 MINIMAX_API_KEY 环境变量)" url = self.minimax_base_url + if not url.endswith("/chat/completions"): + url = f"{url.rstrip('/')}/chat/completions" payload: Dict[str, Any] = { "model": self.minimax_text_model, @@ -433,6 +435,12 @@ class WaterQualityReportGenerator: return f"(读取图片失败:{e})" 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] = { "model": self.minimax_vision_model, @@ -444,7 +452,7 @@ class WaterQualityReportGenerator: {"type": "text", "text": user_prompt}, { "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) except Exception: pass + # ── 通用章节:单位介绍 / 数据采集 / 工作流程 ── + self._add_company_description_page(doc) + self._add_data_acquisition_section(doc) + self._add_data_processing_section(doc) + # ── 1. 项目背景 ── h1 = doc.add_heading("1 项目背景", level=1) self._style_heading(h1, 1) @@ -1422,29 +1435,33 @@ class WaterQualityReportGenerator: 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) work_dir_path = self.work_dir vis_dir = self.visualization_dir - # 0. 航线规划图 - flight_path_img_path = work_dir_path / "12_visualization" / "flight_paths" + # 0. 航线规划图(鲁棒搜索:多路径 + rglob) h3 = doc.add_heading("航线规划:", level=3) self._style_heading(h3, level=3) - # 查找航线图文件 flight_map_files = [] - if flight_path_img_path.exists(): - flight_map_files = list(flight_path_img_path.glob("*.png")) + list(flight_path_img_path.glob("*.jpg")) + flight_search_dirs = [ + 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: - # 使用最新的航线图文件 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: - # AI 分析航线规划图 flight_analysis = self._analyze_flight_path_image(str(latest_flight_map)) self._add_ai_analysis_paragraph(doc, flight_analysis) else: @@ -1455,7 +1472,7 @@ class WaterQualityReportGenerator: h3 = doc.add_heading("高光谱原始影像:", level=3) self._style_heading(h3, level=3) 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: doc.add_paragraph("[高光谱原始影像 - 文件未找到]") @@ -1465,7 +1482,7 @@ class WaterQualityReportGenerator: self._style_heading(h3, level=3) if water_mask_overlay_path.exists(): success = self._add_image_with_caption(doc, str(water_mask_overlay_path), - "图3-3 水体区域识别(蓝色半透明区域为水域)", + "水体区域识别(蓝色半透明区域为水域)", width=Inches(5.5)) if success: water_analysis = self._analyze_water_mask_overlay(str(water_mask_overlay_path)) @@ -1480,13 +1497,13 @@ class WaterQualityReportGenerator: h3 = doc.add_heading("耀斑区域识别结果:", level=3) self._style_heading(h3, level=3) 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: # 尝试查找其他可能的耀斑预览图 glint_files = list(vis_dir.glob("glint_deglint_previews/*glint*.png")) if glint_files: 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: doc.add_paragraph("[耀斑区域识别结果 - 文件未找到]") @@ -1497,13 +1514,13 @@ class WaterQualityReportGenerator: h3 = doc.add_heading("去除耀斑后的影像:", level=3) self._style_heading(h3, level=3) 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: # 尝试查找其他去耀斑预览图 deglint_files = list(vis_dir.glob("glint_deglint_previews/*deglint*.png")) if deglint_files: 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: doc.add_paragraph("[去除耀斑后的影像 - 文件未找到]") @@ -1531,7 +1548,7 @@ class WaterQualityReportGenerator: if sampling_map_files: # 使用最新的采样点分布图文件 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: # AI 分析采样点分布图