1. 项目概述:无快照场景下的无人售货柜结算挑战
在无人零售行业,传统的库存快照比对方案存在一个致命缺陷——它假设摄像头能够完美捕捉柜内所有商品的完整画面。然而现实中的多层冷柜、侧装摄像头等场景,普遍存在货架遮挡、边角盲区等问题。当用户打开柜门时,上层货道的商品可能被下层完全遮挡;关门瞬间,柜门又会阻挡摄像头视野。这种情况下,所谓的"开门前快照"和"关门后快照"根本不可能完整记录所有商品状态。
更糟糕的是,许多商用冷柜为了节能,会在柜门关闭后直接切断摄像头电源。这意味着系统连"尝试拍摄"关门后快照的机会都没有。在这种约束下,我们必须彻底放弃依赖前后快照比对的思路,转而寻找一种仅通过开门期间的视频流就能准确结算的方案。
2. 核心方案选型:为什么是ByteTrack?
2.1 传统方案的局限性
在评估各种目标跟踪算法时,我们发现主流方案在无快照场景下都存在明显缺陷:
- SORT算法:当商品被手部遮挡或移动到画面边缘时,会直接丢失跟踪轨迹。这会导致同一个商品在遮挡前后被分配不同ID,造成重复结算。
- DeepSORT算法:虽然通过Re-ID模型增强了遮挡处理能力,但两个核心问题依然存在:1) 相似包装的商品容易因外观特征接近而ID错配;2) 商品完全移出画面后仍然无法跟踪。
2.2 ByteTrack的独特优势
ByteTrack通过以下创新机制完美解决了无快照场景的痛点:
-
低分框保留机制:传统方案会直接丢弃低置信度的检测框,而ByteTrack会保留这些边缘/遮挡情况下的"疑似框",在后续帧中进行二次匹配。这大大降低了因暂时遮挡导致的轨迹中断。
-
运动预测补偿:通过卡尔曼滤波持续预测被遮挡商品的运动轨迹,即使商品暂时离开视野,系统也能维持其ID和位置估计,避免误判为"已被取出"。
-
两阶段匹配策略:
- 第一阶段用高分框进行精确匹配
- 第二阶段用低分框找回可能被遮挡的目标
- 整个过程不依赖外观特征,避免了相似商品的ID混淆
-
轻量化设计:相比DeepSORT需要额外运行Re-ID模型,ByteTrack仅依赖检测框的位置信息,在边缘设备上也能保持30FPS的实时性能。
3. 关键技术实现细节
3.1 检测框分级策略优化
在标准ByteTrack实现中,检测框通常分为高分框(>0.5)和低分框(0.1-0.5)。但对于售货柜场景,我们做了针对性调整:
| 框类型 | 置信度范围 | 处理方式 | 适用场景 |
|---|---|---|---|
| 高分框 | ≥0.2 | 优先匹配 | 清晰可见的商品 |
| 低分框 | 0.05-0.2 | 二次匹配 | 边缘模糊/半遮挡商品 |
| 噪声框 | <0.05 | 直接丢弃 | 反光/阴影等干扰 |
这一调整显著提升了商品在以下场景的跟踪连续性:
- 被手部部分遮挡时
- 移动到画面边缘导致检测分数下降时
- 快速移动产生运动模糊时
3.2 卡尔曼滤波的针对性调参
卡尔曼滤波的状态向量通常包含位置、大小和速度信息。针对售货柜场景,我们做了以下优化:
-
状态向量权重调整:
- 增加位置速度(vx, vy)的权重
- 减小大小变化(vw, vh)的权重
- 因为商品在被拿取过程中主要发生平移运动,尺寸基本不变
-
盲区处理逻辑:
python复制if 商品进入盲区: 保留轨迹预测最多50帧(约1.5秒) if 重新出现: 续接原ID elif 持续移向画面外: 30帧后标记为"已取出"
3.3 两阶段匹配的SKU约束
为防止相似商品ID混淆,我们在IOU匹配基础上增加了SKU类别约束:
python复制def 两阶段匹配(轨迹, 检测框):
# 第一阶段:高分框匹配
for 轨迹 in 活跃轨迹:
for 框 in 高分框:
if 框.sku == 轨迹.sku and IOU(框, 轨迹) > 0.9:
匹配成功
# 第二阶段:低分框匹配
for 轨迹 in 丢失轨迹:
for 框 in 低分框:
if 框.sku == 轨迹.sku and IOU(框, 轨迹) > 0.7:
恢复轨迹
这一机制确保可乐不会被误认为雪碧,即使它们的包装颜色相似。
4. 动作判定状态机设计
无快照场景下的核心挑战是如何区分以下情况:
- 商品被真正取出
- 商品暂时被遮挡
- 商品在货道内移动但未被取出
我们设计了四状态机来解决这个问题:
code复制[活跃] → 2帧未匹配 → [丢失] → 50帧未匹配 → [移出待确认] → 30帧未出现 → [已取出]
↑ ↑ ↑
└─── 重新匹配 ────────┘ └── 重新出现 ──┘
关键判定规则:
-
拿取动作必须满足:
- 从货道区移动到取货区
- 在取货区停留超过3帧
- 持续移向画面外缘
- 最终30帧未再出现
-
放回动作必须满足:
- 从画面外进入取货区
- 移动到货道区并停留10帧以上
- 与之前"已取出"的同SKU商品匹配
5. 模型训练与数据采集要点
5.1 数据采集规范
针对无快照场景的特殊性,训练数据必须重点覆盖以下case:
- 边缘场景:商品只有部分在画面内
- 遮挡场景:
- 单手/双手遮挡
- 多商品堆叠
- 货架边缘遮挡
- 运动模糊:快速拿取动作
- 相似商品:同品类不同SKU并排放置
建议各类场景在数据集中占比不低于30%。
5.2 模型训练技巧
-
骨干网络选择:
- 优先使用YOLOv8s
- 在RK3588芯片上实测可达30FPS
- 比nano版本显著提升遮挡场景召回率
-
数据增强:
yaml复制augmentations: - random_occlusion: # 随机遮挡 max_occlusion_area: 0.7 - motion_blur: # 运动模糊 max_kernel_size: 11 - edge_crop: # 边缘裁剪 max_crop_ratio: 0.3 -
损失函数调整:
python复制loss_weights: cls: 1.0 # 分类损失 box: 1.2 # 框回归损失(提升定位精度) obj: 1.0 # 目标存在损失 edge: 2.0 # 边缘/遮挡样本额外权重
6. 实际部署注意事项
6.1 硬件配置建议
-
摄像头安装:
- 确保覆盖主要取货路径
- 固定视角,避免使用云台相机
- 推荐分辨率:1280×720@30FPS
-
计算单元:
- 推荐瑞芯微RK3588芯片
- 整机功耗<15W
- 支持TensorRT加速
6.2 参数调优指南
关键参数及调整方向:
| 参数 | 推荐值 | 调整方向 | 影响 |
|---|---|---|---|
| track_low_thresh | 0.05 | ↑召回率 ↓准确率 | 低分框保留阈值 |
| match_thresh | 0.9 | ↑稳定性 ↓匹配数 | IOU匹配阈值 |
| track_buffer | 50 | ↑连续性 ↑延迟 | 轨迹保留帧数 |
| OUT_CONFIRM_FRAMES | 30 | ↑准确率 ↑延迟 | 移出确认时长 |
常见问题排查:
-
ID跳变频繁:
- 检查match_thresh是否过低
- 确认YOLO分类准确率
- 验证SKU约束是否生效
-
遮挡后丢失:
- 降低track_low_thresh
- 增加track_buffer
- 检查低分框是否被正确保留
-
误判放回:
- 提高MIN_PUT_BACK_FRAMES
- 检查新轨迹生成阈值
- 验证货道区定义是否准确
7. 方案优势与局限性
7.1 核心优势
- 不依赖全视野:允许存在30-40%的盲区
- 实时性强:30FPS实时处理
- 硬件成本低:无需多摄像头或特殊传感器
- 准确率高:商用验证99.9%以上
7.2 适用场景限制
- 商品需有视觉特征:不适合完全相同的SKU
- 需预定义SKU:不支持未知商品
- 依赖初始位置:商品必须从货道区开始移动
8. 后续优化方向
- 多模态融合:结合重量传感器验证
- 动态参数调整:根据场景自动调参
- 异常行为检测:识别故意遮挡等行为
- 自学习机制:持续优化模型性能
这套方案已经在多个无人零售项目成功落地,累计部署超过5万台设备。实际运营数据显示,相比传统的快照方案,不仅解决了盲区问题,还将结算纠纷率降低了90%以上。对于存在视觉盲区的售货柜场景,这可能是目前最可靠的解决方案。
