"""Local-only ratio experiment: python -m uvicorn scripts.face_ratios_test_server:app --port 8190.""" import threading import base64 from pathlib import Path import cv2 from fastapi import FastAPI, UploadFile, File, HTTPException from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from face_analysis.face_ratios import detect_framed_ratio_points from face_analysis.special_points import NoFaceError, NonFrontalError static_dir = Path(__file__).resolve().parents[1] / "static" cases_dir = static_dir / "face_ratio_cases" cases_dir.mkdir(exist_ok=True) app = FastAPI() app.mount("/cases", StaticFiles(directory=cases_dir, html=True), name="cases") lock = threading.Lock() @app.get("/") def index(): return FileResponse(static_dir / "test_face_ratios.html") @app.post("/detect") def detect(image_file: UploadFile = File(...)): raw = image_file.file.read(20 * 1024 * 1024 + 1) if len(raw) > 20 * 1024 * 1024: raise HTTPException(413, "图片不能超过20MB") from hairline.framing import decode_portrait image = decode_portrait(raw) if image is None: raise HTTPException(400, "无法读取图片") try: with lock: image, data = detect_framed_ratio_points(image) data["input_image_base64"] = ( "data:image/png;base64," + base64.b64encode(cv2.imencode(".png", image)[1]).decode() ) return data except (NoFaceError, NonFrontalError, ValueError) as exc: raise HTTPException(422, str(exc)) from exc