45 lines
1.5 KiB
Python
45 lines
1.5 KiB
Python
"""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
|