"""本地视频分析模块的集中配置:路径、阈值、模型名、词表等所有可调参数。""" from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parent.parent # 录像来源目录:recordings/{设备号}/{YYYYMMDD}/*.mp4 RECORDINGS_DIR = PROJECT_ROOT / "recordings" # 分析结果落地位置 DB_PATH = PROJECT_ROOT / "analysis.db" THUMBNAILS_DIR = PROJECT_ROOT / "thumbnails" # 网页播放按需转码缓存(源文件mp4容器HEVC轨道sample entry编码标签缺失, # 浏览器无法直接播放,第一次点击时转码为标准H264并缓存在此,避免重复转码) TRANSCODED_DIR = PROJECT_ROOT / "transcoded" # 活动语义打标的限定词表(供 VLM 分类 prompt 和 events.label 取值域共用) ACTIVITY_LABELS = ["走动", "进食", "坐下", "站立", "离开", "其他"] # Ollama 本地模型 OLLAMA_MODEL = "qwen2.5vl:7b" # 活动窗口检测(MOG2 背景建模)参数 # 帧差法对"人物占画面小、动作幅度小"的场景(如老人在客厅整理东西)容易漏检, # 改用 MOG2 自适应背景建模:背景随时间缓慢更新,前景掩码对小幅度/慢速运动更敏感。 MOTION_RESIZE_WIDTH = 320 # 缩放到此宽度再做背景建模,加速计算 MOTION_HISTORY = 120 # MOG2 背景模型参考的历史帧数 MOTION_VAR_THRESHOLD = 16 # 像素值与背景模型的马氏距离阈值,越小越敏感(越容易判定为前景) MOTION_WARMUP_FRAMES = 15 # 背景模型尚未收敛的前N个采样帧不计入判断,避免开场误判为"全员活动" MOTION_SHORT_CLIP_SEC = 2.0 # 短于此时长的视频(约占全量一半,中位时长仅0.56秒)帧数不够MOG2预热, # 触发即录的告警片段本身就是一次完整活动,直接整段视为活动窗口,不跑MOG2 MOTION_PIXEL_RATIO = 0.015 # 一帧里前景像素(不含阴影)占比超过此值才算"有活动" MOTION_MERGE_GAP_SEC = 1.5 # 两段活动间隔小于此秒数则合并为一段 MOTION_MIN_DURATION_SEC = 0.5 # 短于此秒数的活动段视为噪声,丢弃 MOTION_SAMPLE_STRIDE = 2 # 每隔几帧采样一次(2=隔帧,长视频提速且不影响活动窗口检测精度) # 人物出现次数统计(YOLO11n 检测 + ByteTrack 跟踪)参数 # 只在 motion_filter 找出的活动窗口内跑,空场景直接跳过,省算力。 PERSON_MODEL_NAME = "yolo11n.pt" # ultralytics 官方COCO预训练权重,首次运行自动下载 PERSON_DEVICE = "mps" # M系列芯片走Metal加速 PERSON_CONF_THRESHOLD = 0.4 # 检测置信度阈值,低于此值的框直接丢弃 PERSON_SAMPLE_STRIDE = 2 # 每隔几帧检测一次(视频多为15fps,隔帧检测足够跟踪连续性) PERSON_MIN_TRACK_DURATION_SEC = 0.3 # 持续时间短于此值的track视为误检噪声,丢弃 # 摔倒检测(MediaPipe Pose 关键点 + 规则引擎)参数 # 只在 person_tracker 已确认"有人"的时间段内跑姿态估计,空场景不跑。 # 安全信号宁可多报不漏报:判定摔倒 = 短时间内从"直立"骤变为"横躺",且横躺状态持续一段时间 # (躯干角度变水平这个单一条件区分不了"摔倒"和"弯腰/坐下",必须叠加"骤变"+"持续"两个条件) FALL_MODEL_PATH = PROJECT_ROOT / "analysis" / "models" / "pose_landmarker_lite.task" FALL_SAMPLE_STRIDE = 2 # 每隔几帧跑一次姿态估计 FALL_MIN_VISIBILITY = 0.5 # 关键点可见度低于此值不参与姿态计算,视为遮挡/未检出 FALL_ASPECT_RATIO_THRESH = 1.3 # 人体关键点bbox 宽/高 超过此值才可能是"横躺" FALL_TORSO_ANGLE_UPRIGHT = 35 # 躯干(肩中点→髋中点连线)与垂直方向夹角(度),低于此值判定"直立" FALL_TORSO_ANGLE_PRONE = 55 # 高于此值判定"趋于水平/横躺" FALL_TRANSITION_MAX_SEC = 1.5 # "直立"变"横躺"必须在此时间内完成,排除缓慢弯腰/坐下/趟下 FALL_SUSTAIN_MIN_SEC = 1.0 # "横躺"状态至少持续这么久才确认为摔倒,排除弯腰瞬间的误判 FALL_GAP_TOLERANCE_SEC = 5.0 # 一次疑似摔倒事件期间,允许多久检测不到"横躺"样本仍视为 # 事件在继续(真实摔倒后姿态/角度常导致关键点长时间漏检, # 不代表已经爬起来);超过此时长且中途也没等到"直立"信号, # 才判定事件跟丢并结算 # 活动语义打标(本地 Ollama + Qwen2.5-VL 限定词表分类)参数 # 只在 motion_filter 找出的活动窗口内抽帧,VLM推理比传统CV慢得多,不能逐帧跑。 ACTIVITY_SAMPLE_INTERVAL_SEC = 2.0 # 每隔多少秒抽一帧送VLM分类 ACTIVITY_MERGE_GAP_SEC = 3.0 # 连续同标签采样点之间允许的最大间隔,超过则视为新的一段活动