# 冷藏展示柜食品批次计时报警 这是一个独立项目,用于单摄像头监控冷藏展示柜和同画面垃圾桶,记录每个展示区域内食品批次的放置时长,并发现超过自定义报警时间后的异常处理行为。 ## 已确认业务规则 - 摄像头同时看到展示柜和垃圾桶。 - 展示柜食品区域支持 1 到 10 个自定义区域。 - 食品区域使用阿拉伯数字标注:`1`、`2`、`3` ... - 垃圾桶 ROI 独立标定,不占用食品区域编号。 - 每个区域可以放多份食品,但这些食品按同一批次计时。 - 同一区域不允许混批,必须清空后才能放入新批次。 - 食品放入区域时记录开始时间。 - 区域清空时记录结束时间。 - 未达到报警阈值前清空视为正常消耗。 - 食品在区域内达到 `max_dwell_seconds` 时先产生 `time_alarm`。 - 已报警食品从区域移出后,必须在确认窗口内看到垃圾桶投放动作。 - 如果已报警食品移出后没有丢到垃圾桶里,报警事件升级为 `warning_escalated` 警告事件。 - 已报警食品拿出后又放回展示柜,触发违规事件。 ## 当前实现范围 当前版本已经接入可运行的轻量视觉流程:区域占用、垃圾桶动作和 v1.2 的轻量 motion trajectory 都使用启发式图像差分实现,不使用 YOLO。后续训练好的 YOLO 食品检测模型会通过统一的 `disposal_evidence` / backend 合约接入,不改变批次计时状态机的业务输入形态。 视觉或 backend 模块需要输出标准观察数据: ```json { "ts": "2026-04-27T10:00:00+08:00", "zone_counts": { "1": 1, "2": 0 }, "trash_deposit": false, "disposal_evidence": [ { "source_zone_id": "1", "target": "trash", "confidence": 0.9, "method": "motion", "track_points": [ {"x": 0.22, "y": 0.30}, {"x": 0.48, "y": 0.58}, {"x": 0.76, "y": 0.78} ], "item_class": null, "detector_score": null, "observed_at": "2026-04-27T10:00:03+08:00" } ] } ``` 程序会输出 JSONL 事件,例如: - `batch_started` - `time_alarm` - `batch_consumed` - `batch_pending_disposal` - `batch_discarded` - `warning_escalated` - `mixed_batch_violation` - `overdue_return_violation` ## 配置 示例配置在 `config/example.toml`。 默认阈值: - 时间报警阈值:`10800` 秒,也就是 3 小时;管理页按分钟输入,例如 20 分钟会保存为 `1200` 秒 - 垃圾桶投放确认窗口:`120` 秒 食品区域配置示例: ```toml [layout] zone_count = 3 zone_ids = ["1", "2", "3"] [[zones]] id = "1" label = "区域 1" polygon = [[0.1, 0.1], [0.3, 0.1], [0.3, 0.3]] [trash] roi = [[0.7, 0.7], [0.9, 0.7], [0.9, 0.9]] ``` ## 区域标定 项目现在有正式管理页,前端默认 `23000`,后端默认 `19080`。 ```bash scripts/run_manage_api.sh ``` 另开一个终端: ```bash scripts/run_web.sh ``` 打开: ```text http://127.0.0.1:23000 ``` 管理页支持: - 配置 RTSP 地址和阈值 - 从 RTSP 拉取一帧截图 - 设置 1 到 10 个食品区域 - 标定数字食品区域和垃圾桶 ROI - 直接保存标定结果到项目配置文件 - 查看事件汇总、区域序号、停留时间、报警和警告事件 项目仍保留 `tools/calibrator` 作为轻量单页标定工具,但正式使用建议走 `23000` 管理页。 ## 管理 API 默认后端: ```text http://127.0.0.1:19080 ``` 主要接口: - `GET /api/manage/health` - `GET /api/manage/config` - `PUT /api/manage/config` - `POST /api/manage/snapshot` - `PUT /api/manage/calibration` - `GET /api/manage/summary` - `GET /api/manage/events` ## 运行识别计时进程 管理页只负责配置和查看数据。要产生数据,还需要启动运行进程: ```bash scripts/run_runtime.sh ``` 运行进程会: 1. 按配置读取 RTSP。 2. 用 `ffmpeg` 周期抓取小尺寸 RGB 帧。 3. 按标定区域做占用变化检测。 4. 判断垃圾桶区域是否有明显投放动作。 5. 对刚清空的来源区域运行轻量 motion trajectory,生成可选的 `disposal_evidence`。 6. 调用批次计时状态机,优先使用匹配 `source_zone_id` 的 `disposal_evidence` 确认丢弃,再回退到通用垃圾桶动作。 7. 写入 `logs/events.jsonl`,管理页会读取这个文件。 当前视觉版本是可运行的启发式版本: - 每个格口输出 `0/1` 占用状态,不识别单份数量。 - 启动后的前几帧用于建立空柜基线,默认 `3` 帧。 - 如果启动时格口里已经有食品,系统会把它当作基线,后续要等画面变化后才会产生计时事件。 - v1.2 轨迹识别是轻量 motion trajectory,不加载 YOLO,不要求模型文件。 - 训练好的 YOLO 模型后续应作为新的 backend 接入,并继续输出统一的 `disposal_evidence`。 可选运行参数可以放在配置文件的 `[runtime]` 中: ```toml [runtime] sample_interval_seconds = 5.0 frame_width = 640 frame_height = 360 capture_timeout_seconds = 12.0 baseline_frames = 3 sample_stride_pixels = 4 occupancy_mean_delta = 55.0 occupancy_texture_delta = 18.0 occupancy_dark_luma_threshold = 80.0 occupancy_dark_fraction = 0.06 occupancy_texture_dark_fraction = 0.04 occupancy_bright_luma_threshold = 220.0 occupancy_bright_reflection_fraction = 0.18 occupancy_reflection_dark_fraction = 0.10 occupancy_reflection_bright_dark_ratio = 2.0 occupancy_confirm_frames = 2 empty_confirm_frames = 2 lighting_shift_guard_enabled = true lighting_shift_min_regions = 3 lighting_shift_region_fraction = 0.6 lighting_shift_mean_delta = 45.0 trash_motion_delta = 18.0 trash_sustained_motion_delta = 8.0 trash_sustained_motion_frames = 2 trash_motion_cooldown_seconds = 3 trajectory_enabled = true trajectory_window_seconds = 8 trajectory_sample_interval_seconds = 1.0 trajectory_min_points = 3 trajectory_min_confidence = 0.72 trajectory_motion_delta = 20.0 trajectory_min_blob_area = 12 trajectory_max_blob_area_fraction = 0.35 trajectory_trash_entry_margin = 0.04 trajectory_backend = "motion" yolo_enabled = false yolo_model_path = "" yolo_min_confidence = 0.65 diagnostics_path = "logs/runtime_diagnostics.jsonl" ``` `trajectory_backend = "motion"` 表示当前使用轻量轨迹 backend。`yolo_enabled`、`yolo_model_path` 和 `yolo_min_confidence` 是为后续训练模型预留的配置项;当前版本即使保留这些字段,也不会启用 YOLO 推理。 运行诊断写入 `logs/runtime_diagnostics.jsonl`。每行包含顶层 `disposal_evidence`,以及 `diagnostics.trajectory`: - 顶层 `disposal_evidence`:本帧实际输出给状态机的来源区域到垃圾桶证据。 - `diagnostics.lighting_shift`:多数区域同时同方向亮度漂移时启用,防止灯光/曝光变化被当成食品进出。 - `diagnostics.trajectory`:轻量轨迹 backend 的候选、过期、拒绝和已发出证据等调试信息。 ## 本地测试 ```bash PYTHONPATH=src python3 -m unittest discover -s tests -v ``` 前端测试和构建: ```bash node --test web/test/zone-state.test.js cd web && pnpm build ```