""" 尿检试纸识别 API 路由 POST /api/urinecheck/analyze - 上传试纸图片并识别 POST /api/urinecheck/analyze-json - JSON数据格式识别 """ from fastapi import APIRouter, UploadFile, File, HTTPException import tempfile import os import sys import json as json_lib # 导入核心算法 sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from urine_recognizer import analyze_urine_strip from json_recognizer import get_recognizer from schemas import JsonDataRequest router = APIRouter(prefix="/api/urinecheck", tags=["尿检识别"]) # 允许的图片格式 ALLOWED_CONTENT_TYPES = {"image/jpeg", "image/png"} MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB @router.post("/analyze") async def analyze_image( file: UploadFile = File(...), ): """ 上传尿检试纸图片并分析颜色 - 支持格式: JPG, PNG - 最大文件大小: 10MB - 支持规格: 8联/11联/14联 (S型/L型) """ # 验证文件类型 if file.content_type not in ALLOWED_CONTENT_TYPES: raise HTTPException( status_code=400, detail=f"不支持的文件格式: {file.content_type},仅支持 JPG 和 PNG" ) # 读取文件内容 image_data = await file.read() # 检查文件大小 if len(image_data) > MAX_FILE_SIZE: raise HTTPException( status_code=400, detail=f"文件大小超过10MB限制 (当前: {len(image_data) / (1024*1024):.1f}MB)" ) if len(image_data) == 0: raise HTTPException( status_code=400, detail="上传的文件为空" ) # 保存到临时文件 with tempfile.NamedTemporaryFile( suffix=os.path.splitext(file.filename or "image.jpg")[1], delete=False, ) as tmp: tmp.write(image_data) tmp_path = tmp.name # 执行识别 result = analyze_urine_strip(image_data) # 清理临时文件 try: os.unlink(tmp_path) except OSError: pass return result @router.post("/analyze-json") async def analyze_json( request: JsonDataRequest, ): """ JSON数据格式尿检识别 输入格式与客户端上传的txt文件一致: ```json { "extend": {"color_14i": "2"}, "data": [ [{"id": 0, "value": "7.62,146.43,..."}, ...], [{"id": 0, "value": "6.75,139.44,..."}, ...] ] } ``` - value: "H,S,V,L,A,B" 6个颜色通道值 - data: 多帧颜色数据(通常2-5帧) - extend.color_14i: 试纸类型 (1=绿, 2=红, 3=蓝4联, 5=蓝14联) """ recognizer = get_recognizer() # 转换为dict传给识别器 body = json_lib.loads(request.model_dump_json()) result = recognizer.recognize(body) return result