betty0's picture
Deploy fall-detection-pose Gradio demo
11fab85 verified
Raw
History Blame Contribute Delete
3.42 kB
"""config.yaml 的載入與驗證。
所有閾值的單位與選擇理由以 config.yaml 內的註解為準;本模組只負責型別與
一致性檢查。非法組合(例如遲滯出口閾值不低於進入閾值)直接 fail-fast,
不做隱式修正——評估數字的可信度建立在設定檔與程式行為完全一致之上。
"""
from __future__ import annotations
from pathlib import Path
import yaml
from pydantic import BaseModel, Field, model_validator
class ModelConfig(BaseModel):
"""推論模型與追蹤器參數(僅 extract 階段使用)。"""
name: str = "yolo26n-pose.pt"
conf: float = Field(0.25, gt=0.0, lt=1.0)
iou: float = Field(0.5, gt=0.0, lt=1.0)
tracker: str = "bytetrack.yaml"
kpt_conf_min: float = Field(0.35, ge=0.0, lt=1.0)
class RulesConfig(BaseModel):
"""規則引擎閾值。長度單位=軀幹長 L̃、時間單位=秒、角度單位=度。"""
smooth_s: float = Field(gt=0.0)
velocity_window_s: float = Field(gt=0.0)
v_fall_enter: float = Field(gt=0.0)
omega_enter: float = Field(gt=0.0)
theta_lying_enter: float = Field(gt=0.0, lt=90.0)
theta_upright_exit: float = Field(gt=0.0, lt=90.0)
r_lying: float = Field(gt=0.0)
h_hip_lying: float = Field(gt=0.0)
h_hip_upright_exit: float = Field(gt=0.0)
posture_votes_required: int = Field(ge=1, le=3)
window_confirm_s: float = Field(gt=0.0)
vote_ratio: float = Field(gt=0.0, le=1.0)
t_falling_timeout_s: float = Field(gt=0.0)
t_confirm_fallen_s: float = Field(ge=0.0)
t_recover_s: float = Field(gt=0.0)
max_kpt_gap_s: float = Field(ge=0.0)
track_lost_timeout_s: float = Field(gt=0.0)
track_stitch_iou: float = Field(gt=0.0, lt=1.0)
track_stitch_window_s: float = Field(gt=0.0)
track_stitch_window_falling_s: float = Field(gt=0.0)
@model_validator(mode="after")
def _check_consistency(self) -> "RulesConfig":
if self.theta_upright_exit >= self.theta_lying_enter:
raise ValueError(
"theta_upright_exit 必須小於 theta_lying_enter(遲滯出口需低於進入閾值)"
)
if self.h_hip_upright_exit <= self.h_hip_lying:
raise ValueError(
"h_hip_upright_exit 必須大於 h_hip_lying(遲滯出口需高於進入閾值)"
)
if self.max_kpt_gap_s > self.track_lost_timeout_s:
raise ValueError(
"max_kpt_gap_s 不可大於 track_lost_timeout_s(hold-last 不能比 track 終結還久)"
)
if self.track_stitch_window_falling_s < self.track_stitch_window_s:
raise ValueError(
"track_stitch_window_falling_s 不可小於 track_stitch_window_s"
"(前者是後者在 FALLING/FALLEN 時的放寬版本)"
)
return self
class EventsConfig(BaseModel):
"""事件後處理參數。"""
min_event_duration_s: float = Field(ge=0.0)
merge_gap_s: float = Field(ge=0.0)
class Config(BaseModel):
model: ModelConfig
rules: RulesConfig
events: EventsConfig
def load_config(path: str | Path) -> Config:
"""讀取並驗證 YAML 設定檔;任何缺欄位或非法值都拋出例外。"""
with open(path, "r", encoding="utf-8") as f:
raw = yaml.safe_load(f)
return Config.model_validate(raw)