feat(park-desktop): admin 后台新 UI + vision_yolo 手势接入(merge 自旧仓库 4e73a6b)

This commit is contained in:
Pine
2026-08-24 14:56:09 +08:00
parent 00345ae1b9
commit 63dc6b8727
6 changed files with 625 additions and 343 deletions
+39
View File
@@ -19,8 +19,12 @@ from pathlib import Path
from PIL import Image
from .config import settings
log = logging.getLogger("dpm.vision")
_frame_seq = 0
MODEL_DIR = Path(__file__).resolve().parent.parent / "models"
FACE_MODEL_PATH = MODEL_DIR / "yolov8n-face.pt"
POSE_MODEL_PATH = MODEL_DIR / "yolov8n-pose.pt"
@@ -188,6 +192,40 @@ def predict_jpeg(jpeg_bytes: bytes):
}
def _should_save(data: dict) -> bool:
"""仅当画面检测到人脸/手势时才值得落盘保存。"""
return (
int(data.get("faces") or 0) > 0
or bool(data.get("raised"))
or bool(data.get("fists"))
or bool(data.get("both_up"))
or bool(data.get("pointing"))
or bool(data.get("hands_close"))
)
def maybe_save_frame(jpeg: bytes, data: dict):
"""仅将命中(有人/有动作)的 JPEG 帧落盘到 MEDIA_DIR/video/<小时目录>/,便于排查识别链路。
目录按小时分割(YYYYMMDD_HH),不自动清理。
可通过 DPM_SAVE_VISION_FRAMES=0 关闭,或 DPM_VISION_SAVE_DIR 改目录。"""
global _frame_seq
if not settings.SAVE_VISION_FRAMES:
return
if not _should_save(data):
return
_frame_seq += 1
ts = time.strftime("%Y%m%d_%H%M%S")
hour = time.strftime("%Y%m%d_%H")
try:
save_dir = settings.VISION_FRAME_SAVE_DIR / hour
save_dir.mkdir(parents=True, exist_ok=True)
path = save_dir / f"{ts}_{_frame_seq:05d}.jpg"
with open(path, "wb") as f:
f.write(jpeg)
except Exception as e: # noqa: BLE001
log.warning("vision: 保存帧失败 %s", e)
def predict_base64(b64: str):
"""入口:base64 JPEG → 检测结果 dict(含 ok 标记,失败时带 error)"""
try:
@@ -198,6 +236,7 @@ def predict_base64(b64: str):
try:
data = predict_jpeg(jpeg)
data["ok"] = True
maybe_save_frame(jpeg, data)
return data
except Exception as e: # noqa: BLE001
log.error("vision: 推理失败 %s", e, exc_info=True)