瀏覽代碼

简短接口注释, 去掉labelme接口

AnlaAnla 2 周之前
父節點
當前提交
caa05b1609
共有 9 個文件被更改,包括 17 次插入202 次删除
  1. 0 0
      .env
  2. 6 33
      Test/test01.py
  3. 1 1
      app/api/auto_import.py
  4. 5 5
      app/api/cards.py
  5. 3 3
      app/api/config_proxy.py
  6. 1 1
      app/api/formate_xy.py
  7. 1 1
      app/api/images.py
  8. 0 156
      app/api/labelme.py
  9. 0 2
      app/main.py

+ 0 - 0
.env


+ 6 - 33
Test/test01.py

@@ -1,36 +1,9 @@
-from PIL import Image
+import requests
+import time
 
-img = Image.open(r"C:\Code\ML\Image\Card\b2.jpg")
+t1 = time.time()
+response = requests.get("http://192.168.77.249:7755/api/formate_xy/query?card_id=132&mode=current")
+print(time.time() - t1)
 
-min_rect = [
-    [
-        1616.630615234375,
-        2060.99365234375
-    ],
-    [
-        1752.767822265625,
-        1715.654296875
-    ],
-    -62.34006881713867
-]
+print(response.json())
 
-
-img_w, img_h = img.size
-(center_x, center_y), (rect_w, rect_h), angle = min_rect
-center_x = int(center_x)
-center_y = int(center_y)
-rect_w = int(rect_w)
-rect_h = int(rect_h)
-
-# 缩放比例, 根据倾斜角度来
-resize_scale = 1.5 - abs(abs(angle % 90) - 45) / 90
-side_length = max(max(rect_w, rect_h) * resize_scale, 100)
-half_side = side_length / 2
-
-print()
-left, top = max(0, center_x - half_side), max(0, center_y - half_side)
-right, bottom = min(img_w, center_x + half_side), min(img_h, center_y + half_side)
-
-cropped_img = img.crop((left, top, right, bottom))
-
-print()

+ 1 - 1
app/api/auto_import.py

@@ -141,7 +141,7 @@ async def upload_gray_image(session: aiohttp.ClientSession, base_url: str, card_
 
 # --- 暴露的API接口 ---
 
-@router.post("/process_and_import", summary="自动化处理并导入卡牌数据")
+@router.post("/process_and_import", summary="自动化处理并导入卡牌数据[相机后台调用]")
 async def auto_import_script_api(
         request: Request,
         card_name: str = Form(..., description="卡牌名称"),

+ 5 - 5
app/api/cards.py

@@ -60,7 +60,7 @@ def create_card(
         raise HTTPException(status_code=500, detail="数据库插入失败。")
 
 
-@router.get("/query", response_model=CardDetailResponse, summary="获取指定卡牌的详细信息")
+@router.get("/query", response_model=CardDetailResponse, summary="获取指定卡牌的详细信息 [用户调用]")
 def get_card_details(card_id: int, db_conn: PooledMySQLConnection = db_dependency):
     """获取卡牌元数据以及所有与之关联的图片信息,包含 id_prev 和 id_next。"""
 
@@ -122,7 +122,7 @@ def get_next_card_details(card_id: int, db_conn: PooledMySQLConnection = db_depe
         raise HTTPException(status_code=500, detail="服务器内部错误,查询数据库失败。")
 
 
-@router.get("/card_list_filter", response_model=CardListResponseWrapper, summary="获取卡牌列表和总数")
+@router.get("/card_list_filter", response_model=CardListResponseWrapper, summary="获取卡牌列表和总数 [用户调用]")
 def card_list_filter(
         card_id: Optional[int] = Query(None, description="筛选:卡牌ID"),
         cardNo: Optional[str] = Query(None, description="筛选:卡牌编号"),
@@ -187,7 +187,7 @@ def card_list_filter(
         raise HTTPException(status_code=500, detail="获取数据列表失败。")
 
 
-@router.delete("/delete/{id}", status_code=200, summary="删除卡牌及其所有关联图片")
+@router.delete("/delete/{id}", status_code=200, summary="删除卡牌及其所有关联图片 [用户调用]")
 def delete_card(id: int, db_conn: PooledMySQLConnection = db_dependency):
     """
     删除一张卡牌及其所有关联的图片记录和物理文件。
@@ -230,7 +230,7 @@ def delete_card(id: int, db_conn: PooledMySQLConnection = db_dependency):
         raise HTTPException(status_code=500, detail="删除卡牌失败。")
 
 
-@router.put("/review_state/{id}", status_code=200, summary="修改卡牌的审核状态")
+@router.put("/review_state/{id}", status_code=200, summary="修改卡牌的审核状态 [用户调用]")
 def update_review_state(
         id: int,
         data: ReviewUpdate,
@@ -271,7 +271,7 @@ def update_review_state(
         raise HTTPException(status_code=500, detail="修改审核状态失败,数据库操作错误。")
 
 
-@router.post("/batch_query/id_score", status_code=200, summary="批量查询id和分数")
+@router.post("/batch_query/id_score", status_code=200, summary="批量查询id和分数 [评级后端调用]")
 def batch_query_id_score(
         data: CardNoList,
         db_conn: PooledMySQLConnection = db_dependency

+ 3 - 3
app/api/config_proxy.py

@@ -15,7 +15,7 @@ router = APIRouter()
 http_client = httpx.AsyncClient(timeout=10.0, limits=httpx.Limits(max_keepalive_connections=20, max_connections=100))
 
 
-@router.get("/scoring_config", summary="[代理] 获取评分配置")
+@router.get("/scoring_config", summary="[代理] 获取评分配置 [用户调用]")
 async def proxy_get_scoring_config(current_user: dict = Depends(require_admin_user)):
     target_url = settings.SCORE_SERVER_CONFIG_URL
 
@@ -36,7 +36,7 @@ async def proxy_get_scoring_config(current_user: dict = Depends(require_admin_us
         raise HTTPException(status_code=503, detail=str(exc))
 
 
-@router.put("/scoring_config", summary="[代理] 更新评分配置")
+@router.put("/scoring_config", summary="[代理] 更新评分配置 [用户调用]")
 async def proxy_update_scoring_config(
         config_data: dict = Body(...),
         current_user: dict = Depends(require_admin_user)
@@ -58,7 +58,7 @@ async def proxy_update_scoring_config(
         raise HTTPException(status_code=503, detail=str(exc))
 
 
-@router.get("/severity_names", summary="[代理] 获取缺陷严重程度列表")
+@router.get("/severity_names", summary="[代理] 获取缺陷严重程度列表 [用户调用]")
 async def proxy_get_severity_names(defect_label: str = Query(..., description="缺陷标签")):
     target_url = f"{settings.SCORE_SERVER_CONFIG_URL.replace('/scoring_config', '')}/severity_names"
 

+ 1 - 1
app/api/formate_xy.py

@@ -53,7 +53,7 @@ def _process_images_to_xy_format(card_data: dict):
     return card_data
 
 
-@router.get("/query", response_model=CardDetailResponse, summary="获取卡牌详细信息(格式化xy), 支持前后翻页")
+@router.get("/query", response_model=CardDetailResponse, summary="获取卡牌详细信息(格式化xy), 支持前后翻页 [用户调用]")
 def get_card_details(
         card_id: int = Query(..., description="基准卡牌ID"),
         mode: QueryMode = Query(QueryMode.current, description="查询模式: current(当前), next(下一个), prev(上一个)"),

+ 1 - 1
app/api/images.py

@@ -234,7 +234,7 @@ async def upload_gray_image_for_card(
         if cursor: cursor.close()
 
 
-@router.get("/jsons/{id}", response_model=ImageJsonPairResponse, summary="获取图片的原始和修改后JSON")
+@router.get("/jsons/{id} [用户调用]", response_model=ImageJsonPairResponse, summary="获取图片的原始和修改后JSON")
 def get_image_jsons(id: int, db_conn: PooledMySQLConnection = db_dependency):
     # 此接口主要用于主图,灰度图没有实体的 JSON 存储,暂不支持直接通过此 ID 查询 JSON
     # 如果前端通过 format_xy 里的 query 接口获取,已经能在 list 里拿到了。

+ 0 - 156
app/api/labelme.py

@@ -1,156 +0,0 @@
-import json
-import requests
-from typing import Optional, Dict, Any, List
-from fastapi import APIRouter, File, UploadFile, Depends, HTTPException, Body
-from fastapi.concurrency import run_in_threadpool
-from mysql.connector.pooling import PooledMySQLConnection
-
-from app.core.config import settings
-from app.core.logger import get_logger
-from app.core.database_loader import get_db_connection
-from app.crud import crud_card
-from app.utils.scheme import IMAGE_TYPE_TO_SCORE_TYPE
-from app.utils.labelme_process import convert_internal_to_labelme, convert_labelme_to_internal
-
-logger = get_logger(__name__)
-router = APIRouter()
-db_dependency = Depends(get_db_connection)
-
-
-@router.get("/export/{image_id}", summary="获取指定图片的 LabelMe 格式 JSON")
-def export_labelme_json(image_id: int, db_conn: PooledMySQLConnection = db_dependency):
-    """
-    获取图片的 JSON 数据并转换为 LabelMe 格式。
-    优先读取 modified_json,如果没有则读取 detection_json。
-    """
-    cursor = None
-    try:
-        cursor = db_conn.cursor(dictionary=True)
-        # 查询图片路径和JSON
-        query = "SELECT image_path, detection_json, modified_json FROM card_images WHERE id = %s"
-        cursor.execute(query, (image_id,))
-        row = cursor.fetchone()
-
-        if not row:
-            raise HTTPException(status_code=404, detail=f"图片 ID {image_id} 未找到")
-
-        # 优先使用已修改的数据
-        source_json_str = row['modified_json'] if row['modified_json'] else row['detection_json']
-
-        if isinstance(source_json_str, str):
-            source_json = json.loads(source_json_str)
-        else:
-            source_json = source_json_str  # 已经是 dict (如果是从 Pydantic 模型来的话,但在原生 cursor 里通常是 str 或 dict)
-            if source_json is None: source_json = {}
-
-        image_path = row['image_path']
-
-        # 转换
-        labelme_data = convert_internal_to_labelme(image_path, source_json)
-
-        return labelme_data
-
-    except Exception as e:
-        logger.error(f"导出 LabelMe JSON 失败 (id={image_id}): {e}")
-        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")
-    finally:
-        if cursor:
-            cursor.close()
-
-
-@router.put("/import/{image_id}", summary="接收 LabelMe JSON,重计算分数并保存")
-async def import_labelme_json(
-        image_id: int,
-        labelme_data: Dict[str, Any] = Body(..., description="LabelMe 格式的 JSON 数据"),
-        db_conn: PooledMySQLConnection = db_dependency
-):
-    """
-    1. 接收 LabelMe JSON。
-    2. 转换为系统内部 JSON 格式。
-    3. 调用项目1的 API 进行重计算 (re-inference & score)。
-    4. 更新数据库 (modified_json)。
-    """
-    cursor = None
-    try:
-        cursor = db_conn.cursor(dictionary=True)
-
-        # 1. 获取图片基础信息 (用于获取 image_type 和原始 JSON 结构参考)
-        query = "SELECT card_id, image_type, detection_json FROM card_images WHERE id = %s"
-        cursor.execute(query, (image_id,))
-        row = cursor.fetchone()
-
-        if not row:
-            raise HTTPException(status_code=404, detail=f"图片 ID {image_id} 未找到")
-
-        card_id = row['card_id']
-        image_type = row['image_type']
-
-        # 解析原始 JSON 用于辅助转换 (例如获取宽高作为兜底)
-        detection_json = row['detection_json']
-        if isinstance(detection_json, str):
-            detection_json = json.loads(detection_json)
-
-        # 2. 转换格式: LabelMe -> Internal
-        # 注意:这里生成的 JSON 只有 points 和 labels,面积和分数需要服务端计算
-        internal_payload = convert_labelme_to_internal(detection_json, labelme_data)
-
-        # 确定 score_type
-        score_type = IMAGE_TYPE_TO_SCORE_TYPE.get(image_type)
-        if not score_type:
-            raise HTTPException(status_code=400, detail=f"不支持的图片类型: {image_type}")
-
-        logger.info(f"正在调用计算服务: {settings.SCORE_RECALCULATE_ENDPOINT}, type={score_type}")
-
-        # 3. 调用项目1的分数重计算接口
-        try:
-            response = await run_in_threadpool(
-                lambda: requests.post(
-                    settings.SCORE_RECALCULATE_ENDPOINT,
-                    params={"score_type": score_type},
-                    json=internal_payload,
-                    timeout=30  # 稍微增加超时时间,因为可能涉及推理
-                )
-            )
-        except Exception as e:
-            logger.error(f"连接分数计算服务失败: {e}")
-            raise HTTPException(status_code=502, detail="无法连接到分数计算服务")
-
-        if response.status_code != 200:
-            logger.error(f"分数计算服务返回错误: {response.text}")
-            raise HTTPException(status_code=response.status_code, detail=f"分数计算失败: {response.text}")
-
-        recalculated_json = response.json()
-        logger.info("分数重计算完成")
-
-        # 4. 更新数据库
-        recalculated_json_str = json.dumps(recalculated_json, ensure_ascii=False)
-        update_query = (
-            "UPDATE card_images "
-            "SET modified_json = %s, is_edited = TRUE "
-            "WHERE id = %s"
-        )
-        cursor.execute(update_query, (recalculated_json_str, image_id))
-        db_conn.commit()
-
-        # 5. 更新 Card 维度的总分状态
-        try:
-            crud_card.update_card_scores_and_status(db_conn, card_id)
-        except Exception as e:
-            logger.error(f"更新卡牌总分失败: {e}")
-            # 不阻断主流程
-
-        return {
-            "success": True,
-            "message": "LabelMe 数据导入并重计算成功",
-            "image_id": image_id
-        }
-
-    except HTTPException as he:
-        raise he
-    except Exception as e:
-        db_conn.rollback()
-        logger.error(f"导入 LabelMe 数据失败: {e}")
-        raise HTTPException(status_code=500, detail=f"系统内部错误: {str(e)}")
-    finally:
-        if cursor:
-            cursor.close()

+ 0 - 2
app/main.py

@@ -7,7 +7,6 @@ import os
 from .core.database_loader import init_database, load_database_pool, close_database_pool
 from app.api import cards as cards_router
 from app.api import images as images_router
-from app.api import labelme as labelme_router
 from app.api import formate_xy as formate_xy_router
 from app.api import config_proxy as config_proxy_router
 from app.api import rating_report as rating_report_router
@@ -46,7 +45,6 @@ app.add_middleware(
 
 app.include_router(cards_router.router, prefix=f"{settings.API_PREFIX}/cards", tags=["Cards"])
 app.include_router(images_router.router, prefix=f"{settings.API_PREFIX}/images", tags=["Images"])
-app.include_router(labelme_router.router, prefix=f"{settings.API_PREFIX}/labelme", tags=["Labelme"])
 app.include_router(formate_xy_router.router, prefix=f"{settings.API_PREFIX}/formate_xy", tags=["Formate"])
 app.include_router(auto_import_router.router, prefix=f"{settings.API_PREFIX}/import", tags=["AutoImport"])
 app.include_router(config_proxy_router.router, prefix=f"{settings.API_PREFIX}/config", tags=["ConfigProxy"])