最近把自己做的一个无人零售视觉项目重新整理了一遍。这套方案并不是单纯做一个目标检测 Demo,而是把深度相机、RGB 相机、时序判定、事件日志和语音助手串成了一条完整链路,目标很明确:稳定识别货架区域内商品的拿起与放回动作。

和常见“只看商品框有没有消失”的做法不同,这个项目更强调动作证据与状态融合。也就是说,系统不是只盯着商品框,而是同时观察手部接触、商品稳定性、短时消失恢复、实例复用等信息,再输出 take / put_back 事件。

这篇文章会从问题背景、整体方案、关键实现、运行方式和效果展示几个角度,把这个项目完整梳理一遍。

项目运行主界面

图 1 项目运行主界面

1. 这个项目要解决什么问题

如果只用单路普通摄像头做无人零售识别,往往会遇到几个很典型的问题:

  • 商品被手遮挡后,检测框容易抖动甚至消失。
  • 仅凭“框变少了”去判断拿起动作,误报率通常偏高。
  • 货架上存在多个相似商品时,事件归因容易混乱。
  • 即便识别出了结果,也很难继续接到导购播报、语音问答或后续业务逻辑里。

所以我在这个项目里采用了更适合无人零售场景的一种组合方式:

  • 深度流负责看手部动作与空间前后关系。
  • RGB 流负责识别商品类别与位置。
  • 两路信息在 ROI 范围内做融合,再输出最终事件。

这种做法的核心价值,不是“多上一个相机”,而是把“谁在动”和“什么被动了”这两件事拆开处理,再重新合并。

2. 整体方案

整个系统可以拆成 5 个部分:

  1. Astra / OpenNI 深度采集模块
  2. RGB 商品检测模块
  3. 手部与商品的时序融合判定模块
  4. 日志、会话回放与预览输出模块
  5. 商品知识库与语音助手模块

核心流程如下:

深度流 -> 手部检测 -> 手部接触/邻近证据
RGB流  -> 商品检测 -> 商品跟踪/实例状态
               \      /
                \    /
             事件融合判定
                  |
     take / put_back / cancel_take
                  |
      日志、预览视频、语音播报、问答助手

为了减少背景干扰,项目还引入了货架 ROI。后续的大部分商品统计、动作判定和信息叠加,都是围绕 ROI 区域进行的,这一点对于真实场景很重要。

3. 项目结构

目前最核心的几个文件如下:

astra_openni_ctypes.py             OpenNI/Astra 深度相机封装
dahua_video.py                     大华摄像头低延迟取流
hand_item_detector.py              拿取/放回事件判定逻辑
retail_assistant.py                语音助手、知识库和播报模块
run_astra_depth_rgb_item_fusion.py 主流程脚本
run_take_put_high_accuracy.py      高精度启动入口

其中最关键的是两个部分:

  • run_astra_depth_rgb_item_fusion.py
    负责相机初始化、深度/RGB 对齐、ROI 选择、模型调用、预览叠加和会话输出。
  • hand_item_detector.py
    负责把手部接触证据、商品出现/消失状态、时间窗和实例缓存结合起来,最终生成结构化事件。

从工程角度看,这个项目的重点已经不只是“模型推理”,而是“推理结果如何被组织成稳定事件”。

4. 核心实现思路

4.1 深度手部检测 + RGB 商品检测

项目里手部检测和商品检测是分开的:

  • 手部走深度流,重点关注动作与接触。
  • 商品走 RGB 流,重点关注类别与边界框。

这样做的直接好处是,两个任务分别使用最适合自己的视觉信息,不会互相牵制。深度图对手的前后层次更敏感,RGB 图对商品外观更友好。

4.2 ROI 限定货架区域

真实零售画面里,并不是整张图都需要参与判断。
因此项目先完成货架 ROI 选择,再在 ROI 内做商品统计和动作判定。

这样可以带来三个收益:

  • 减少背景区域误检。
  • 降低状态管理复杂度。
  • 为后续多货道、多层货架扩展留出清晰边界。

4.3 不是“框消失了”就等于拿走

这个项目最关键的一点,是没有把“商品框消失”直接等价成“拿起成功”。

真正的事件判断会综合下面这些证据:

  • 手是否与商品产生接触或近邻关系
  • 接触持续了多少帧
  • 商品在消失前是否已经稳定存在
  • 商品消失后是否在短时间内恢复
  • 同类商品是否需要复用实例 ID

这部分逻辑集中在 hand_item_detector.py 中,也是整个系统最值得打磨的地方。很多实际项目不是模型本身不够强,而是事件层缺少足够稳的规则组织。

4.4 输出的不只是结果,还有可追溯材料

项目运行后,不仅会显示实时预览窗口,还会把过程材料保存到 runs/ 目录,例如:

  • fusion_events.jsonl
  • frame_trace.jsonl
  • summary.json
  • annotated_preview.avi

这对后续调参非常有帮助,因为你可以回到某一帧重新分析:问题到底出在模型、对齐、ROI,还是事件判定逻辑。

拿起动作识别效果

图 2 拿起动作识别效果

5. 语音助手是怎么接进去的

这个项目里我还加了一层零售助手能力,用来把“识别结果”进一步转成“交互能力”。

它目前支持的内容包括:

  • 读取商品知识库
  • 根据识别到的商品生成播报内容
  • 处理语音提问
  • 接入大模型生成更自然的导购话术
  • 可选接入大华摄像头画面做辅助理解

这部分并不是必须,但它让系统从“能识别”进一步走向“能交互”。如果是做课程设计、比赛答辩、演示系统或者展会 Demo,这一层体验会非常加分。

6. 如何运行

6.1 环境依赖

项目主要运行环境为:

  • Windows
  • Python 3.10+
  • Astra / OpenNI SDK
  • 可选:大华 SDK、麦克风、音箱

Python 依赖安装:

pip install -r requirements.txt

6.2 权重与配置准备

  • 手部权重放在 weights/hand_depth/best.pt
  • 商品权重放在 weights/item_rgb/best.pt
  • 根据本地环境配置 retail_assistant_config.json
  • 如需显式指定 OpenNI SDK,设置环境变量 OPENNI_SDK_DIR

6.3 启动命令

高精度模式启动:

python run_take_put_high_accuracy.py

也可以直接运行主流程:

python run_astra_depth_rgb_item_fusion.py --sdk-dir "你的 OpenNI SDK 路径"

7. 当前样例效果

基于已有一次会话记录,我整理了一组样例统计数据:

  • 共处理 1754 帧
  • 平均单帧总耗时约 170.12 ms
  • 估算处理速度约 5.88 FPS
  • 已成功记录拿起和放回事件

从演示原型的角度看,这个结果已经能比较稳定地支撑“看得见动作变化、能输出结构化事件、还能接播报与问答”的整套链路。

放回动作识别效果

图 3 放回动作识别效果

8. 还可以继续优化什么

如果后续继续往前做,我觉得最值得投入的方向有这几个:

  • 提升多商品同类场景下的实例稳定性
  • 增加更轻量的推理配置,进一步提高 FPS
  • 把 ROI 从手工框选升级成自动货架定位
  • 做更规范的数据集和评测集,量化 take / put_back 准确率
  • 把运行结果继续接到 Web 面板、库存系统或结算逻辑中

换句话说,这个项目现在已经具备了“原型系统”的骨架,下一步就是往稳定性、性能和业务闭环方向迭代。

9. 这次整理时做了哪些工作

为了方便公开分享,我这次专门做了下面这些整理:

  • 增加 README.md
  • 补充 requirements.txt
  • 生成对外可用的示例配置文件
  • 补了发布前检查清单
  • 去掉默认代码里的敏感配置,改成环境变量或空值
  • 重新整理了文章结构和演示配图

如果你也在做类似项目,我非常建议在发布前把真实密钥、设备账号、私有知识库和运行日志做一次脱敏处理,这一步往往比想象中更重要。

10. 总结

这个项目最有价值的地方,不只是“识别到了商品”,而是把深度相机、RGB 视觉、时序规则和语音交互真正组合成了一个可运行、可解释、可扩展的无人零售原型。

对于毕业设计、比赛项目、技术博客或者面试展示来说,这种完成度通常会比单点模型演示更有说服力。因为别人看到的不是某个模型跑通了,而是一整套系统已经开始具备落地雏形。

如果你也在做无人零售、货架识别或者多模态视觉融合,欢迎交流。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐