Переглянути джерело

配置报错, 和重计算外框的漂移问题

AnlaAnla 2 тижнів тому
батько
коміт
c6f01d5c61
4 змінених файлів з 43 додано та 18 видалено
  1. 13 0
      app/api/config_api.py
  2. 1 0
      app/core/config.py
  3. 1 0
      app/main.py
  4. 28 18
      app/utils/defect_inference/AnalyzeCenter.py

+ 13 - 0
app/api/config_api.py

@@ -1,6 +1,9 @@
+import os.path
+
 from fastapi import APIRouter, File, Body, HTTPException, status
 from fastapi.responses import FileResponse, JSONResponse
 from ..core.config import settings
+import datetime
 import json
 from app.core.logger import get_logger
 
@@ -176,6 +179,16 @@ async def update_scoring_config(new_config: dict = Body(...)):
         with open(settings.SCORE_CONFIG_PATH, 'w', encoding='utf-8') as f:
             json.dump(new_config, f, indent=2, ensure_ascii=False)
         logger.info("评分配置文件已成功更新。")
+
+        logger.info("保存备份")
+        formatted_time = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
+        backup_name = f"scors_backup_{formatted_time}.json"
+        temp_path = os.path.join(settings.SCORE_BACKUP_PATH, backup_name)
+        with open(temp_path, 'w', encoding='utf-8') as f:
+            json.dump(new_config, f, indent=2, ensure_ascii=False)
+        logger.info("配置备份结束")
+
+
         return JSONResponse(
             status_code=status.HTTP_200_OK,
             content={"message": "配置已成功更新"}

+ 1 - 0
app/core/config.py

@@ -21,6 +21,7 @@ class Settings:
 
     TEMP_WORK_DIR = BASE_PATH / "_temp_work"
     SCORE_CONFIG_PATH = BASE_PATH / "app/core/scoring_config.json"
+    SCORE_BACKUP_PATH = BASE_PATH / "score_config_backup"
 
     # 图片像素与真实图片缩放比例
     PIXEL_RESOLUTION = 24.54

+ 1 - 0
app/main.py

@@ -21,6 +21,7 @@ async def lifespan(main_app: FastAPI):
     print("--- 应用启动 ---")
     # --- 文件和目录准备 ---
     os.makedirs(settings.TEMP_WORK_DIR, exist_ok=True)
+    os.makedirs(settings.SCORE_BACKUP_PATH, exist_ok=True)
 
     # --- 模型加载 ---
     load_models()

+ 28 - 18
app/utils/defect_inference/AnalyzeCenter.py

@@ -224,27 +224,37 @@ def analyze_centering_rect(inner_points: Union[str, List], outer_points: Union[s
     if isinstance(outer_points, str):
         outer_points = get_rect_from_file(outer_points)
 
-    # 转换为 numpy 数组
-    inner_contour = np.array(inner_points, dtype=np.int32)
-    outer_contour = np.array(outer_points, dtype=np.int32)
+    # --- 1. 转换为 float32 数组,保留精度 ---
+    inner_contour = np.array(inner_points, dtype=np.float32)
+    outer_contour = np.array(outer_points, dtype=np.float32)
+
+    # --- 2. 手动计算 float 级别的 boundingRect ---
+    def get_float_bounding_rect(points):
+        # points shape: (N, 2)
+        x_min = np.min(points[:, 0])
+        y_min = np.min(points[:, 1])
+        x_max = np.max(points[:, 0])
+        y_max = np.max(points[:, 1])
+
+        w = x_max - x_min
+        h = y_max - y_min
+        return x_min, y_min, w, h
 
-    # --- 1. 获取横平竖直的矩形参数 (x, y, w, h) ---
-    # 即使传入的是4个点,用 boundingRect 也能确保取出准确的边界
-    ix, iy, iw, ih = cv2.boundingRect(inner_contour)
-    ox, oy, ow, oh = cv2.boundingRect(outer_contour)
+    ix, iy, iw, ih = get_float_bounding_rect(inner_contour)
+    ox, oy, ow, oh = get_float_bounding_rect(outer_contour)
 
     # 构造标准的4点格式返回 (保持和 analyze_centering_rotated 输出一致)
     def get_box_corners(x, y, w, h):
         return [[x, y], [x + w, y], [x + w, y + h], [x, y + h]]
 
-    inner_box_corners_int = get_box_corners(ix, iy, iw, ih)
-    outer_box_corners_int = get_box_corners(ox, oy, ow, oh)
+    inner_box_corners_float = get_box_corners(ix, iy, iw, ih)
+    outer_box_corners_float = get_box_corners(ox, oy, ow, oh)
 
-    print("\n--- 基于修正矩形(横平竖直)的分析 ---")
-    print(f"内框: x={ix}, y={iy}, w={iw}, h={ih}")
-    print(f"外框: x={ox}, y={oy}, w={ow}, h={oh}")
+    print("\n--- 基于修正矩形(横平竖直, Float精度)的分析 ---")
+    print(f"内框: x={ix:.2f}, y={iy:.2f}, w={iw:.2f}, h={ih:.2f}")
+    print(f"外框: x={ox:.2f}, y={oy:.2f}, w={ow:.2f}, h={oh:.2f}")
 
-    # --- 2. 计算边距 (Margins) ---
+    # --- 3. 计算边距 (Margins) ---
     # 图像坐标系:x向右增加,y向下增加
 
     # 左边距:内框左边 - 外框左边
@@ -257,7 +267,7 @@ def analyze_centering_rect(inner_points: Union[str, List], outer_points: Union[s
     # 下边距:外框下边(y+h) - 内框下边(y+h)
     margin_bottom = (oy + oh) - (iy + ih)
 
-    # --- 3. 计算百分比 ---
+    # --- 4. 计算百分比 ---
     total_horizontal_margin = margin_left + margin_right
     total_vertical_margin = margin_top + margin_bottom
 
@@ -266,17 +276,17 @@ def analyze_centering_rect(inner_points: Union[str, List], outer_points: Union[s
     top_percent = 50.0
     bottom_percent = 50.0
 
-    if total_horizontal_margin > 0:
+    if total_horizontal_margin > 0.0001: # 避免除零
         left_percent = (margin_left / total_horizontal_margin) * 100
         right_percent = (margin_right / total_horizontal_margin) * 100
         print(f"水平边距分布: 左 {left_percent:.1f}% | 右 {right_percent:.1f}%")
 
-    if total_vertical_margin > 0:
+    if total_vertical_margin > 0.0001:
         top_percent = (margin_top / total_vertical_margin) * 100
         bottom_percent = (margin_bottom / total_vertical_margin) * 100
         print(f"垂直边距分布: 上 {top_percent:.1f}% | 下 {bottom_percent:.1f}%")
 
-    # --- 4. 角度差异 ---
+    # --- 5. 角度差异 ---
     # 因为已经是横平竖直的矩形,角度差默认为 0
     angle_diff = 0.0
 
@@ -284,7 +294,7 @@ def analyze_centering_rect(inner_points: Union[str, List], outer_points: Union[s
     # ((左%, 右%), (上%, 下%), 角度差), 内框点集, 外框点集
     return ((left_percent, right_percent),
             (top_percent, bottom_percent),
-            angle_diff), inner_box_corners_int, outer_box_corners_int
+            angle_diff), inner_box_corners_float, outer_box_corners_float
 
 
 def formate_center_data(center_result,