فهرست منبع

加入edit_type字段,内外框最小外接矩形

AnlaAnla 1 ماه پیش
والد
کامیت
4317e40e97

+ 6 - 75
Test/test01.py

@@ -1,77 +1,8 @@
-import asyncio
-from contextlib import asynccontextmanager
-from fastapi import FastAPI
-import time
-import logging
+import numpy as np
 
-# 配置日志
-logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
+box = [[1,2,3],[4,5,6],[7,8,9]]
+box = np.array(box).tolist()
+data = {"11": "345"}
 
-# 创建一个 asyncio.Event 来作为关闭信号
-shutdown_event = asyncio.Event()
-
-
-async def my_background_worker(name: str):
-    """
-    一个模拟的后台工作任务,它会持续运行直到收到关闭信号。
-    """
-    logging.info(f"Worker '{name}' starting.")
-    count = 0
-    while not shutdown_event.is_set():
-        try:
-            # 你的业务逻辑
-            logging.info(f"Worker '{name}' is running, count: {count}")
-            count += 1
-
-            # 使用 asyncio.sleep 而不是 time.sleep,避免阻塞事件循环
-            await asyncio.sleep(2)
-        except asyncio.CancelledError:
-            # 当任务被取消时,正常退出循环
-            logging.warning(f"Worker '{name}' received cancellation request. Stopping.")
-            break
-    logging.info(f"Worker '{name}' has stopped gracefully.")
-
-
-@asynccontextmanager
-async def lifespan(app: FastAPI):
-    logging.info("Application startup...")
-
-    # 在应用启动时,创建并启动后台任务
-    # 将 task 存储在 app.state 中,以便在关闭时可以访问它
-    app.state.worker_task = None
-    yield  # 应用在此处运行
-
-    logging.info("Application shutdown...")
-
-    # 1. 发送关闭信号
-    logging.info("Signaling worker to shut down.")
-    shutdown_event.set()
-
-    # 2. 等待后台任务完成
-    try:
-        # 给一个超时时间,防止无限期等待
-        await asyncio.wait_for(app.state.worker_task, timeout=5.0)
-        logging.info("Worker task has been awaited.")
-    except asyncio.TimeoutError:
-        logging.error("Worker task did not finish in time, cancelling.")
-        app.state.worker_task.cancel()  # 如果超时,强制取消
-        # 等待取消操作完成
-        await asyncio.gather(app.state.worker_task, return_exceptions=True)
-    except Exception as e:
-        logging.error(f"An error occurred during worker shutdown: {e}")
-
-
-app = FastAPI(lifespan=lifespan)
-
-
-@app.get("/")
-async def root():
-    app.state.worker_task = asyncio.create_task(my_background_worker("Worker-1"))
-
-    return {"message": "Hello World"}
-
-
-if __name__ == '__main__':
-    import uvicorn
-
-    uvicorn.run(app)
+data['box'] = box
+print(data)

+ 24 - 24
Test/计算居中.py

@@ -10,30 +10,30 @@ if __name__ == "__main__":
     outer_file_path = r"C:\Code\ML\Project\CheckCardBoxAndDefectServer\temp\outer\250805_pokemon_0001.json"
 
     # center_result = analyze_centering_rotated(inner_file_path, outer_file_path)
-    # draw_rotated_bounding_boxes(img_path, inner_file_path, outer_file_path)
+    draw_rotated_bounding_boxes(img_path, inner_file_path, outer_file_path)
 
-    with open(inner_file_path, "r", encoding="utf-8") as f:
-        inner_data = json.load(f)
-    with open(outer_file_path, "r", encoding="utf-8") as f:
-        outer_data = json.load(f)
+    # with open(inner_file_path, "r", encoding="utf-8") as f:
+    #     inner_data = json.load(f)
+    # with open(outer_file_path, "r", encoding="utf-8") as f:
+    #     outer_data = json.load(f)
 
-    inner_points = inner_data['shapes'][0]['points']
-    outer_points = outer_data['shapes'][0]['points']
-    center_result = analyze_centering_rotated(inner_points, outer_points)
+    # inner_points = inner_data['shapes'][0]['points']
+    # outer_points = outer_data['shapes'][0]['points']
+    # center_result = analyze_centering_rotated(inner_points, outer_points)
 
-    data = {
-        "img_id": 2,
-        "img_url": "",
-        "inference_result": {
-            "center_inference": {
-                "angel_diff": center_result[2],
-                "center_left": center_result[0][0],
-                "center_right": center_result[0][1],
-                "center_top": center_result[1][0],
-                "center_bottom": center_result[1][1]
-            }
-        }
-    }
-    data['inference_result']['inner_box'] = inner_data
-    data['inference_result']['outer_box'] = outer_data
-    print(data)
+    # data = {
+    #     "img_id": 2,
+    #     "img_url": "",
+    #     "inference_result": {
+    #         "center_inference": {
+    #             "angel_diff": center_result[2],
+    #             "center_left": center_result[0][0],
+    #             "center_right": center_result[0][1],
+    #             "center_top": center_result[1][0],
+    #             "center_bottom": center_result[1][1]
+    #         }
+    #     }
+    # }
+    # data['inference_result']['inner_box'] = inner_data
+    # data['inference_result']['outer_box'] = outer_data
+    # print(data)

+ 13 - 5
app/services/defect_service.py

@@ -3,18 +3,19 @@ import numpy as np
 from ..core.model_loader import get_predictor
 from app.utils.defect_inference.CardDefectAggregator import CardDefectAggregator
 from app.utils.defect_inference.arean_anylize_draw import DefectProcessor, DrawingParams
-from app.utils.defect_inference.AnalyzeCenter import analyze_centering_rotated
+from app.utils.defect_inference.AnalyzeCenter import analyze_centering_rotated, formate_center_data
 from app.utils.defect_inference.DrawCenterInfo import draw_boxes_and_center_info
 from app.utils.defect_inference.ClassifyEdgeCorner import ClassifyEdgeCorner
-from app.utils.json_data_formate import formate_center_data, formate_face_data
+from app.utils.json_data_formate import formate_face_data, formate_add_edit_type
 from app.core.config import settings
 from app.core.logger import get_logger
 import json
 
 logger = get_logger(__name__)
 
+
 class DefectInferenceService:
-    def defect_inference(self, inference_type: str , img_bgr: np.ndarray,
+    def defect_inference(self, inference_type: str, img_bgr: np.ndarray,
                          is_draw_image=True) -> dict:
         """
         执行卡片识别推理。
@@ -65,6 +66,7 @@ class DefectInferenceService:
                 area_json = processor.analyze_from_json(json_data)
 
             face_json_result = formate_face_data(area_json)
+            face_json_result = formate_add_edit_type(face_json_result)
 
             with open(area_json_path, 'w', encoding='utf-8') as f:
                 json.dump(face_json_result, f, ensure_ascii=False, indent=2)
@@ -113,6 +115,7 @@ class DefectInferenceService:
             classifier = ClassifyEdgeCorner(settings.PIXEL_RESOLUTION, settings.CORNER_SIZE_MM)
             edge_corner_data = classifier.classify_defects_location(area_json, outer_result)
 
+            edge_corner_data = formate_add_edit_type(edge_corner_data)
             with open(area_json_path, 'w', encoding='utf-8') as f:
                 json.dump(edge_corner_data, f, ensure_ascii=False, indent=2)
             logger.info("边角面积计算结束")
@@ -137,9 +140,14 @@ class DefectInferenceService:
 
             inner_points = inner_result['shapes'][0]['points']
             outer_points = outer_result['shapes'][0]['points']
-            center_result = analyze_centering_rotated(inner_points, outer_points)
+            center_result, inner_rect_box, outer_rect_box = analyze_centering_rotated(inner_points, outer_points)
+
+            logger.info(f"inner_rect_box: {type(inner_rect_box)}, {inner_rect_box}")
+            logger.info(f"outer_rect_box: , {outer_rect_box}")
             logger.info("格式化居中数据")
-            center_result = formate_center_data(center_result, inner_result, outer_result)
+            center_result = formate_center_data(center_result,
+                                                inner_result, outer_result,
+                                                inner_rect_box, outer_rect_box)
 
             draw_img = draw_boxes_and_center_info(img_bgr, center_result)
             temp_center_img_path = settings.TEMP_WORK_DIR / f'{inference_type}-center_result.jpg'

+ 32 - 1
app/utils/defect_inference/AnalyzeCenter.py

@@ -4,7 +4,9 @@ import json
 import matplotlib.pyplot as plt
 import math
 from typing import Union, List
+from app.core.logger import get_logger
 
+logger = get_logger(__name__)
 
 def get_points_from_file(json_file):
     """辅助函数,从JSON文件加载点"""
@@ -101,6 +103,13 @@ def analyze_centering_rotated(inner_points: Union[str, List], outer_points: Unio
     inner_rect = cv2.minAreaRect(inner_contour)
     outer_rect = cv2.minAreaRect(outer_contour)
 
+    # 获取矩形的4个角点, 并转化为坐标
+    outer_box_corners = cv2.boxPoints(outer_rect)
+    outer_box_corners_int = np.intp(outer_box_corners).tolist()
+
+    inner_box_corners = cv2.boxPoints(inner_rect)
+    inner_box_corners_int = np.intp(inner_box_corners).tolist()
+
     # --- 1. 标准化矩形尺寸,确保宽度总是长边 ---
     def standardize_rect(rect):
         (cx, cy), (w, h), angle = rect
@@ -182,7 +191,29 @@ def analyze_centering_rotated(inner_points: Union[str, List], outer_points: Unio
 
     return ((left_percent, right_percent),
             (top_percent, bottom_percent),
-            angle_diff)
+            angle_diff), inner_box_corners_int, outer_box_corners_int
+
+
+def formate_center_data(center_result,
+                        inner_data: dict, outer_data: dict,
+                        inner_rect_points: List, outer_rect_points: List):
+    data = {
+        "box_result": {
+            "center_inference": {
+                "angel_diff": center_result[2],
+                "center_left": center_result[0][0],
+                "center_right": center_result[0][1],
+                "center_top": center_result[1][0],
+                "center_bottom": center_result[1][1]
+            }
+        }
+    }
+    data['box_result']['inner_box'] = inner_data
+    data['box_result']['outer_box'] = outer_data
+    data['box_result']['inner_box']['shapes'][0]['rect_box'] = inner_rect_points
+    data['box_result']['outer_box']['shapes'][0]['rect_box'] = outer_rect_points
+
+    return data
 
 # if __name__ == "__main__":
 #     img_path = r"C:\Code\ML\Project\CheckCardBoxAndDefectServer\temp\250805_pokemon_0001.jpg"

+ 10 - 0
app/utils/defect_inference/DrawCenterInfo.py

@@ -27,16 +27,26 @@ def draw_boxes_and_center_info(image:Union[str, np.ndarray], json_data:dict):
                 points = np.array(shape_info["points"], dtype=np.int32)
                 # 绘制多边形
                 cv2.polylines(img, [points], isClosed=True, color=(0, 230, 130), thickness=2)  # 绿色
+                # 绘制外接矩形
+                rect_box = np.array(shape_info['rect_box'], dtype=np.int32)
+                cv2.drawContours(image, [rect_box], 0, (0, 180, 120), thickness=2)
+
                 # 标记内框的标签
                 cv2.putText(img, "Inner Box", tuple(points[0]), cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 255, 0), 5,
                             cv2.LINE_AA)
 
+
         # --------------------- 绘制外框 (outer_box) ---------------------
         if "outer_box" in json_data["box_result"] and json_data["box_result"]["outer_box"]["num"] > 0:
             for shape_info in json_data["box_result"]["outer_box"]["shapes"]:
                 points = np.array(shape_info["points"], dtype=np.int32)
                 # 绘制多边形
                 cv2.polylines(img, [points], isClosed=True, color=(120, 130, 250), thickness=2)
+
+                # 绘制外接矩形
+                rect_box = np.array(shape_info['rect_box'], dtype=np.int32)
+                cv2.drawContours(image, [rect_box], 0, (100, 120, 220), thickness=2)
+
                 # 标记外框的标签
                 cv2.putText(img, "Outer Box", tuple(points[0] + [0, -50]), cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 0, 255), 5,
                             cv2.LINE_AA)

+ 5 - 17
app/utils/json_data_formate.py

@@ -2,23 +2,6 @@ import json
 import logging
 
 
-def formate_center_data(center_result, inner_data: dict, outer_data: dict):
-    data = {
-        "box_result": {
-            "center_inference": {
-                "angel_diff": center_result[2],
-                "center_left": center_result[0][0],
-                "center_right": center_result[0][1],
-                "center_top": center_result[1][0],
-                "center_bottom": center_result[1][1]
-            }
-        }
-    }
-    data['box_result']['inner_box'] = inner_data
-    data['box_result']['outer_box'] = outer_data
-    return data
-
-
 def formate_face_data(area_json: dict):
     for defect in area_json['defects']:
         # 添加新标签
@@ -26,6 +9,11 @@ def formate_face_data(area_json: dict):
     return area_json
 
 
+def formate_add_edit_type(area_json: dict):
+    for defect in area_json['defects']:
+        defect['edit_type'] = ""
+    return area_json
+
 # if __name__ == '__main__':
 #     json_path = r"C:\Code\ML\Project\CheckCardBoxAndDefectServer\_temp_work\pokemon_front_face_no_reflect_defect-area_result.json"
 #     with open(json_path, 'r') as f: