
树莓派实战指南调用 Custom Vision 目标检测完成货架库存盘点【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners在 IoT-For-Beginners 的零售项目中stock-detector目标检测模型已经训练并发布接下来要让树莓派或虚拟 IoT 设备把摄像头对准货架调用 Custom Vision 目标检测接口给每罐番茄酱标出边界框再按重叠面积去重、输出商品数量完成一次库存盘点。这份实战指南从 3 行代码的改动讲起覆盖树莓派调用目标检测、边界框相对坐标换算以及用 Shapely 剔除重复预测的完整库存统计流程。一张表看懂图像分类 vs 目标检测stock-counter程序的骨架直接复用自制造项目从设备检查水果的流程拍照 → 调模型 → 解析输出。分类与检测的区别集中在下面这张表对比维度图像分类器目标检测器SDK 调用方法predictor.classify_image(project_id, iteration_name, image)predictor.detect_image(project_id, iteration_name, image)返回结构每个标签一条tag_nameprobability一张图返回多条每条含tag_name、probability和bounding_box是否必须阈值通常不用每标签返回最高置信度必须同一物体可能被重复框出要过滤低概率结果典型用途判断图里是什么判断物体在哪、有几个进而盘点库存环境与设备准备Raspberry Pi 与虚拟设备对照项目Raspberry Pi虚拟 IoT 设备项目位置在 Pi 上创建stock-counter文件夹在电脑上创建并先建好虚拟环境摄像头安装 PiCamera固定对准货架排线搭在盒子上方或双面胶固定均可安装 CounterFit 与counterfit_shims_picamera用静态图就准备检测器没见过的货架照片用网络摄像头则保证视野拍全库存依赖安装直接执行pip3 install在激活的虚拟环境内执行所有pip3 install 拍照、调用模型这两段的代码与制造项目完全一致直接复用即可本指南只讲改的部分。三行代码从 classify_image 切到 detect_image拍照和创建predictor客户端的代码不动把分类调用整段替换掉即可。改动前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运行目标检测器用列表推导式收集所有概率大于threshold的预测遍历打印标签名和百分比概率。虚拟设备版本只在开头多一行CounterFitConnection.init(127.0.0.1, 5000)连接 CounterFit 服务、并把摄像头换成counterfit_shims_picamera里的PiCamera其余完全一致。完整实现见 Pi 版 app.py 和 虚拟设备版 app.py。Custom Vision 阈值设置哪些检测概率可信为什么检测必须过阈值分类器每个标签只给一条结果而检测器一张图能返回多个框同一罐货可能被重复框出。threshold 0.3就是把低于 30% 的不太像预测全部丢掉只留下可信的。跑起来后树莓派上的典型输出是这样的piraspberrypi:~/stock-counter $ python3 app.py tomato paste: 34.13% tomato paste: 33.95% tomato paste: 35.05% tomato paste: 32.80% 阈值过低会带入大量误检过高又会漏检请按自己的货架照片调整threshold。设备拍的照片和这些概率都能在 Custom Vision 门户的Predictions页逐条复核边界框相对坐标top、left、height、width 换算每个检测结果除了标签和概率还带一个bounding_box由top、left、height、width四个 0~1 的相对值定义分别表示框距图片上边、左边的距离及框本身高宽占图像对应维度的比例。原点(0, 0)在图片左上角框的下边缘等于top height。拿一张宽 600 像素、高 800 像素的图来算账框从上边 320 像素处开始top 0.4800 × 0.4 320距左边 240 像素left 0.4600 × 0.4 240框高 240 像素height 0.3800 × 0.3 240框宽 120 像素width 0.2600 × 0.2 120。坐标值Top0.4Left0.4Height0.3Width0.2用相对值而不是像素值好处是同一组数字无论图片缩放到 640×480 还是 1280×960 都能按原比例定位不用跟着分辨率重算。把边界框画出来看效果先打印核对把for循环里的输出改成带框信息——print(f{prediction.tag_name}:\t{prediction.probability * 100:.2f}%\t{prediction.bounding_box})控制台就会多出left、top、width、height四个 0~1 的值。想直观看到框在哪用 Pillow 把相对坐标换算成像素再画上去。安装依赖虚拟设备请在激活的虚拟环境里执行pip3 install pillow顶部加导入文件末尾追加绘制代码from PIL import Image, ImageDraw, ImageColorwith Image.open(image.jpg) as im: draw ImageDraw.Draw(im) for prediction in predictions: scale_left prediction.bounding_box.left scale_top prediction.bounding_box.top scale_right prediction.bounding_box.left prediction.bounding_box.width scale_bottom prediction.bounding_box.top prediction.bounding_box.height left scale_left * im.width top scale_top * im.height right scale_right * im.width bottom scale_bottom * im.height draw.rectangle([left, top, right, bottom], outlineImageColor.getrgb(red), width2) im.save(image.jpg)换算原理就是相对值 × 图像尺寸left为 0.5、图宽 600 像素时得到 300 像素0.5 × 600 300右下两个角由left width、top height先算出相对值再乘尺寸。保存时直接覆盖image.jpg在 VS Code 资源管理器里点开就能看到红色矩形Shapely 重叠面积去重数出货架上的商品数货架上罐头前后排摆放时框会互相重叠重叠越大越可能两个框指向同一罐货。统计前先安装依赖树莓派要先装系统库sudo apt install libgeos-dev pip3 install shapely顶部导入from shapely.geometry import Polygon然后在画框代码之前加两段。第一段定义重叠阈值和框转多边形的辅助函数overlap_threshold 0.20 def create_polygon(prediction): scale_left prediction.bounding_box.left scale_top prediction.bounding_box.top scale_right prediction.bounding_box.left prediction.bounding_box.width scale_bottom prediction.bounding_box.top prediction.bounding_box.height return Polygon([(scale_left, scale_top), (scale_right, scale_top), (scale_right, scale_bottom), (scale_left, scale_bottom)])第二段做两两比较并输出库存数to_delete [] for i in range(0, len(predictions)): polygon_1 create_polygon(predictions[i]) for j in range(i1, len(predictions)): polygon_2 create_polygon(predictions[j]) overlap polygon_1.intersection(polygon_2).area smallest_area min(polygon_1.area, polygon_2.area) if overlap (overlap_threshold * smallest_area): to_delete.append(predictions[i]) break for d in to_delete: predictions.remove(d) print(fCounted {len(predictions)} stock items)要点逐条说清overlap_threshold 0.20允许 20% 的重叠比例阈值不是绝对面积而是相对两框中较小者smallest_area的比例Polygon.intersection返回两框的交集多边形取.area就是重叠面积比较顺序是第 1 个 vs 第 2、3、4…个第 2 个 vs 第 3、4…个即i与j i1的嵌套循环判定重复后立即breakPython 不允许遍历列表时删元素所以先收集进to_delete循环结束后统一remove这段逻辑放在画框之前生成的图片只画出去重后幸存的框Counted N stock items输出的数量可以直接发给 IoT 服务库存偏低时触发补货告警。 这是刻意简化的方案——遇到重叠就删掉配对中的第一个。生产环境需要更细的策略比如多个物体之间的复杂重叠、一个框完全包含在另一个框里的情形。仓库里 code-count 虚拟设备版 app.py 把overlap_threshold设为 0.002可以对比不同阈值对剔除结果的影响。接下来完整代码与 IoT Edge 迁移作业计数版完整代码Pi 版 code-count app.py、虚拟设备版 code-count app.py分步文档单板机目标检测调用、单板机库存计数进阶作业把目标检测器导出为紧凑模型并部署到 Azure IoT Edge再从 IoT 设备访问边缘版本见 assignment.md零售项目到这里就完整了从训练stock-detector到树莓派上的库存盘点。作业做完后记得按 clean-up.md 清理云端资源。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考