IoT-For-Beginners 零售篇:使用 IoT 与对象检测模型管理货架库存 IoT-For-Beginners 零售篇使用 IoT 与对象检测模型管理货架库存【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本篇技术指南围绕微软 Azure 开源课程 IoT-For-Beginners 的第 5 个模块「零售」展开讲解如何利用运行在 IoT 设备上的 AI 对象检测Object Detection模型自动盘点货架库存。你将掌握对象检测与图像分类的本质区别、使用 Azure Custom Vision 在云端训练库存检测器的完整流程、从 IoT 设备调用已发布模型的方法以及如何利用边界框Bounding Box数据实现可靠的库存计数。零售模块概览为什么库存盘点需要 IoT食品从生产到消费者手中最后一段旅程发生在零售环节——农贸市场、生鲜店、超市和各类商店。对食品零售店尤其是大型超市而言最耗费人力与时间的工作之一就是保证货架不缺货员工需要逐排检查货架发现空位后从仓库补货。本模块的思路是让 IoT 设备上的 AI 模型承担这项重复性劳动不是对整张图片做分类而是检测并计数图片中的单个对象。该模块共包含 2 节课训练一个库存检测器——学习对象检测原理并在云端训练对象检测模型从 IoT 设备检查库存——将模型部署到 IoT 设备上实现库存计数。 这两节课会用到部分云资源。如果未完成整个项目的全部课程请在实验结束后参考 清理你的项目 释放资源。对象检测从整图分类到逐物定位在之前的制造模块中你已经用 AI 训练过图像分类器——它能判断一张图片里是否包含某类东西例如成熟/未成熟的香蕉。对象检测则是另一类图像 AI 模型它不按标签对整张图分类而是被训练去识别物体并在图中定位它们不仅检测到对象存在还能给出它出现在图中的位置从而支持对图片中的对象进行计数。对象检测与图像分类的对比图像分类对整张图片做判断——输出模型训练所用每个标签的匹配概率。以本模块配套的示例图 image-classifier-cashews-tomato.png 为例用训练好的模型分别分类腰果罐和番茄酱罐头两类图片标签图片 1腰果罐概率图片 2番茄酱罐头概率cashew nuts腰果98.4%0.7%tomato paste番茄酱1.6%99.3%你可以设定一个概率阈值来推断图片内容。但如果一张图里同时有多个番茄酱罐头、或者既有腰果又有番茄酱呢分类器的输出将无法满足需求——这正是对象检测的用武之地。对象检测的训练方式完全不同不是告诉模型这张图是标签 A 或标签 B而是在包含目标对象的图片上框出对象所在区域并打上标签一张图可以标注一个或多个对象。模型因此学到对象本身长什么样而不仅是包含对象的图片长什么样。预测时模型返回的不是标签概率列表而是一系列已检测对象每个对象附带边界框和与所分配标签匹配的概率。上图中同时存在一罐腰果和三罐番茄酱。检测器识别出腰果返回包含腰果的边界框及其概率97.6%同时识别出三罐番茄酱为每一罐返回独立的边界框和对应概率。边界框Bounding Box包围对象的方框用于界定对象在图中的位置。对象检测的工作原理对象检测依赖复杂的机器学习模型。从简化模型理解其工作方式大致是将图像划分成多个单元格检查每个单元格的中心是否与训练数据中某个对象的中心匹配可以近似理解为在图像的不同区域反复运行分类器寻找匹配。需要说明的是这是大幅简化的描述实际存在多种对象检测技术。对象检测领域有不少知名模型其中最有名的当属YOLOYou Only Look Once——它以极快的速度著称可检测人、狗、瓶子、汽车等 20 类常见对象。这类模型还可以通过**迁移学习Transfer Learning**重新训练以检测自定义对象这正是本模块训练番茄酱罐头库存检测器所依赖的机制。对象检测在零售中的典型应用对象检测在零售场景有多个实际用途本模块列举了四类库存检查与计数识别货架何时缺货库存过低时向店员或补货机器人发送通知口罩检测在公共卫生事件期间识别佩戴口罩与未佩戴口罩的人员自动结账在无人商店中检测顾客从货架取走的商品并自动计费危险物检测识别地面上的破损商品或洒落的液体提醒清洁人员处理。用 Azure Custom Vision 训练库存检测器训练对象检测器的流程与训练图像分类器类似但需要额外完成框选对象并打标签的步骤。创建对象检测项目为该模块创建资源组stock-detector在资源组中创建免费的 Custom Vision 训练资源和预测资源分别命名为stock-detector-training和stock-detector-prediction。每个账号只能各有一个免费训练/预测资源因此务必先清理前面课程使用的资源登录 Custom Vision 门户customvision.ai参考官方「构建对象检测器快速入门」的创建新项目部分新建项目将项目命名为stock-detector关键配置如下Resource资源选择前面创建的stock-detector-trainingProject Type项目类型选择Object Detection对象检测Domain领域选择Products on Shelves货架商品——该领域专为检测货架上的库存商品而优化相关界面可参考 custom-vision-create-object-detector-project.png。✅ 每个对象至少需要 15 张图片且拍摄角度和光照条件应多样化越多越好。既然领域是 Products on shelves请尽量模拟货架陈列的方式摆放对象。上传并标注训练图片收集包含待检测对象的图片。对每个待检测对象至少准备 15 张来自不同角度、不同光照条件的图片越多越好另外再准备少量用于测试的图片如果检测多个对象测试图片中应尽量同时包含所有对象。图片要求与注意事项格式为 PNG 或 JPEG单张小于 6MBiPhone 等设备拍摄的 HEIC 高分辨率照片需要先转换、必要时压缩同时包含多个不同对象的图片会计入图中所有对象的 15 张最低数量要求模型面向货架商品设计尽量拍摄对象摆放在货架上的照片仓库 5-retail/lessons/1-train-stock-detector/images 目录下提供了腰果与番茄酱的示例图片分training/与testing/两组可直接使用。上传后为对象创建标签并绘制边界框绘制边界框时尽量紧贴对象边缘工具会自动给出它认为的边界框可在此基础上微调以加快标注速度如果每个对象的图片超过 15 张可以先训练到 15 张再使用Suggested tags建议标签功能让已训练模型自动检测未标注图片中的对象人工确认或修正边界框能大幅节省标注时间。训练、测试与再训练训练时选择Quick Training快速训练模型会在几分钟内完成训练。训练完成后用Quick Test快速测试按钮上传未曾用于训练的测试图片验证检测效果。与图像分类器一样初次训练的结果可能不达预期。每次通过 Quick Test 预测时图片与结果都会被保存可用于迭代改进打开Predictions预测标签页定位测试图片确认正确的检测结果、删除错误的边界框、补上漏检的对象重新训练并再次测试。训练完成页面上还会给出Precision精确率、Recall召回率与mAP三个评估指标用于量化模型质量。 挑战如果两个外观相似的商品如同品牌番茄酱罐头和切块番茄罐头同时出现检测器会如何表现可以尝试向检测器加入相似商品的图片来验证。从 IoT 设备调用对象检测器发布模型迭代模型训练完成后需要先发布Publish才能在 IoT 设备上调用在 Custom Vision 门户打开stock-detector项目选择顶部Performance性能标签页在侧边Iterations迭代列表中选择最新迭代点击迭代的Publish发布按钮在对话框中把Prediction resource设为stock-detector-prediction发布名保留默认的Iteration2发布完成后点击Prediction URL按钮从底部If you have an image file区域复制预测 API URL形如https://location.api.cognitive.microsoft.com/customvision/v3.0/Prediction/id/detect/iterations/Iteration2/image其中location是创建 Custom Vision 资源时选择的地域id是一长串字母数字标识。同时复制Prediction-Key预测密钥——调用模型时必须携带此密钥未携带密钥的请求会被拒绝。树莓派 / 虚拟设备端从分类到检测Python 侧的检测代码与分类代码几乎一致核心差异在于Custom Vision SDK 调用的方法与返回结果的结构。删除分类代码results predictor.classify_image(project_id, iteration_name, image) for prediction in results.predictions: print(f{prediction.tag_name}:\t{prediction.probability * 100:.2f}%)替换为对象检测代码results predictor.detect_image(project_id, iteration_name, image) threshold 0.3 predictions list(prediction for prediction in results.predictions if prediction.probability threshold) for prediction in predictions: print(f{prediction.tag_name}:\t{prediction.probability * 100:.2f}%)detect_image是预测客户端上的对象检测方法与分类器每个标签只返回一个结果不同检测器会返回多个结果因此需要用阈值过滤掉低概率项。运行后控制台输出类似piraspberrypi:~/stock-counter $ python3 app.py tomato paste: 34.13% tomato paste: 33.95% tomato paste: 35.05% tomato paste: 32.80% 阈值threshold需要根据实际图片调整。完整代码见 code-detect/pi/stock-counter/app.py树莓派版与 code-detect/virtual-iot-device/stock-counter/app.py虚拟设备版。从源码可以看到设备端先通过 URL 解析出endpoint、project_id和iteration_name再用ApiKeyCredentials携带预测密钥构建CustomVisionPredictionClient最后将摄像头拍摄的图片字节流传给detect_imageparts prediction_url.split(/) endpoint https:// parts[2] project_id parts[6] iteration_name parts[9] prediction_credentials ApiKeyCredentials(in_headers{Prediction-key: prediction_key}) predictor CustomVisionPredictionClient(endpoint, prediction_credentials) image.seek(0) results predictor.detect_image(project_id, iteration_name, image)Wio TerminalArduino端从分类到检测在 Wio Terminal 的main.cpp中改造步骤为文件顶部添加#include vector将classifyImage函数改名为detectStock函数定义与buttonPressed中的调用处都要改在函数上方声明概率阈值const float threshold 0.3f;新增processPredictions函数遍历预测结果并把tagName、probability打印到串口监视器在detectStock中改用带阈值的过滤循环只保留概率高于阈值的预测再交给processPredictions。按 C 键触发拍摄后串口输出Connecting to WiFi.. Connected! Image captured Image read to buffer with length 17416 tomato paste: 35.84% tomato paste: 35.87% tomato paste: 34.11% tomato paste: 35.16%完整代码见 code-detect/wio-terminal/stock-counter/src/main.cpp。边界框位置数据与计数基础调用对象检测器返回的结果不仅包含标签和概率还包含每个对象的边界框用于定义检测到对象的位置区域。边界框由 4 个值定义top上、left左、height高、width宽取值范围均为0–1表示相对图片尺寸的百分比位置。原点 (0,0) 位于图片左上角top是距顶边的距离框底为top height。以官方文档示例 bounding-box.png 为例图片宽 600 像素、高 800 像素。边界框距顶 320 像素 →top 0.4800 × 0.4 320距左 240 像素 →left 0.4600 × 0.4 240高 240 像素 →height 0.3宽 120 像素 →width 0.2。坐标值Top0.4Left0.4Height0.3Width0.2采用 0–1 的相对值意味着无论图片缩放到多大边界框都保持距上/距左 0.4、占高 0.3、占宽 0.2的相对位置。Custom Vision 的Predictions标签页会直接在预测图片上叠加红色方框展示这些边界框例如 custom-vision-stock-prediction.png 中一次检测出 4 罐番茄酱。边界框结合概率还能用于评估检测是否可信。例如检测器可能在同一个对象上给出两个重叠框一个 78.3% 概率的框内又套着一个 64.3% 概率的小框。代码可以检查到两个框完全重叠从而忽略低概率的那个——因为一个物体不可能装在另一个物体里。用边界框实现库存计数场景一缺货检测把摄像头对准货架例如可容纳 8 罐番茄酱的位置检测器只找到 7 罐就说明缺了 1 罐需要补货。IoT 设备不仅能发送补货通知还能结合边界框给出缺货位置——这对使用机器人补货的场景至关重要。 实际运营中是否补货取决于店铺、商品热度等条件通常不会因为缺 1 罐就立即补货需要设计基于商品、客流量等因素的补货判定算法。场景二错放商品检测货架上可能出现放错位置的商品——人工补货失误或顾客改变主意随手放回。对罐头等耐储存商品这只是小麻烦但对冷冻、冷藏等生鲜商品放错位置可能导致无法继续销售。对象检测可以识别出异常商品并立刻通知人工或机器人归位例如 stock-rogue-corn.png 展示的玉米罐头误放番茄酱货架场景。计数时的重叠过滤当边界框之间存在显著重叠时很可能两个框指向的是同一个对象例如一个框套在另一个框内直接计数会产生重复。因此正确计数的关键是忽略重叠超过阈值的框。树莓派 / 虚拟设备Python的做法安装依赖pip3 install pillow shapely树莓派需先执行sudo apt install libgeos-dev用 Pillow 将边界框绘制到保存的图片上把 0–1 相对坐标乘以图片宽高换算成像素坐标再用红色矩形画出见 rpi-stock-with-bounding-boxes.jpg用 Shapely 计算重叠把每个边界框转为多边形定义overlap_threshold 0.20允许 20% 重叠两两比较若重叠面积超过较小框面积的阈值百分比则删除其一输出最终数量print(fCounted {len(predictions)} stock items)。核心实现见 code-count/pi/stock-counter/app.py其中create_polygon将预测的边界框转成 Shapely 多边形Polygon.intersection(...).area计算重叠面积由于不能在遍历列表时删除元素代码先把待删预测放入to_delete列表遍历结束后统一移除。控制台输出示例piraspberrypi:~/stock-counter $ python3 app.py tomato paste: 33.42% {additional_properties: {}, left: 0.3455171, top: 0.09916268, width: 0.14175442, height: 0.29405564} tomato paste: 34.41% {additional_properties: {}, left: 0.48283678, top: 0.10242918, width: 0.11782813, height: 0.27467814} Counted 4 stock itemsWio TerminalC的实现思路相同定义Point、Rect结构体与area、overlappingArea函数计算矩形重叠面积rectFromBoundingBox从预测的boundingBoxJSON 对象提取left/top/width/height构造成矩形最后在processPredictions中两两比较、剔除重叠超限的预测并输出计数。串口输出示例tomato paste: 35.84% {left:0.395631,top:0.215897,width:0.180768,height:0.359364} tomato paste: 35.87% {left:0.378554,top:0.583012,width:0.14824,height:0.359382} Counted 4 stock items.完整代码见 code-count/wio-terminal/stock-counter/src/main.cpp。 文中展示的是非常简化的重叠去除方式——直接删除重叠对中的第一个框。生产级代码需要更精细的逻辑例如考虑多个对象之间的重叠、一个框被另一个框完全包含等情况。计数结果可进一步发送到 IoT 服务在库存过低时触发告警。用真实设备数据再训练模型与图像分类器类似可以使用 IoT 设备采集的真实数据再训练模型确保模型在设备端实际使用时表现良好。区别在于对象检测无法仅给图片打标签而必须逐一审查模型给出的每个边界框用 IoT 设备采集一批新图片在Predictions标签页选中图片逐个检查红色边界框框住的对象不对就删除该框位置不准就用四角手柄调整标签错误则移除并重新添加正确标签完成审查后图片会从 Predictions 移到 Training Images对全部预测重复此过程点击Train重新训练发布新迭代并把 IoT 设备中的 URL 更新为新迭代的地址重新部署代码并测试设备。✅ 提示每次发布新迭代都会获得新的迭代名IoT 设备调用哪个迭代由调用 URL 中的迭代名决定切换设备所用迭代只需要更新 URL。小结与延伸本模块完整演示了一条云端训练 → 设备推理 → 边界框计数的零售库存管理链路先用 Azure Custom Vision 的Products on Shelves领域训练对象检测器再通过预测 API 从树莓派或虚拟 IoT 设备、Wio Terminal调用最后利用边界框的 0–1 相对坐标实现重叠过滤与库存计数。仓库为两种硬件平台单板计算机/虚拟设备、Wio Terminal分别提供了仅检测与计数两套完整可运行代码。相关资源模块入口5-retail/README.md课程一训练检测器5-retail/lessons/1-train-stock-detector/README.md 及其作业课程二设备端检查5-retail/lessons/2-check-stock-device/README.md设备端分步指南树莓派/虚拟设备检测与计数Wio Terminal 检测与计数云资源清理clean-up.md 挑战延伸尝试用对象检测识别错误库存——训练模型识别多个对象当检测到错误商品时让应用发出告警更进一步还可以对同一货架并排摆放的同类商品设定边界框范围限制判断商品是否被放错位置。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考