从 IoT 设备调用你的对象检测器:基于 Raspberry Pi 与虚拟 IoT 硬件(IoT-For-Beginners 库存盘点实战)
2026/9/17 7:33:28 网站建设 项目流程

从 IoT 设备调用你的对象检测器:基于 Raspberry Pi 与虚拟 IoT 硬件(IoT-For-Beginners 库存盘点实战)

【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners

导读

本文是 IoT-For-Beginners 零售项目(5-retail)第 2 课的核心实战篇,讲解如何把上一课在 Azure Custom Vision 中训练并发布的对象检测器接入物联网设备,完成"从设备拍摄货架照片 → 调用云端检测 API → 过滤低置信度预测并输出检测结果"的完整链路。读完本文,你将掌握在 Raspberry Pi 与 CounterFit 虚拟 IoT 设备上从图片分类代码平滑迁移到对象检测代码的方法,理解classify_imagedetect_image的本质差异,以及如何用概率阈值剔除误检,为后续的库存计数打下基础。

前置条件:对象检测器已发布

要开始本节内容,你需要先完成上一课(训练库存检测器)的任务,确保你的 Custom Vision 对象检测项目stock-detector已经:

  1. 完成了至少一次迭代训练;
  2. 通过Performance选项卡中的Publish按钮发布了迭代(例如发布为Iteration2);
  3. 通过Prediction URL对话框拿到了两个关键凭据:预测 API 的 URL(形如https://<location>.api.cognitive.microsoft.com/customvision/v3.0/Prediction/<id>/detect/iterations/Iteration2/image)以及Prediction-Key安全密钥。

只有持有Prediction-Key的应用才能调用模型,其他请求会被拒绝。这一点在发布的完整流程中也在 5-retail/lessons/2-check-stock-device/README.md 的 "Call your object detector from your IoT device" 一节有详细描述。

第一步:复制图片分类项目

你的库存检测器绝大部分代码与之前课程中创建的图片分类器完全相同——拍摄图像、解析预测 URL、构造客户端凭据这些基础设施都会被直接复用。因此第一步是复制分类器项目。

任务:复制图片分类项目

  1. 创建工作目录:在电脑上(虚拟 IoT 设备场景)或 Raspberry Pi 上创建一个名为stock-counter的文件夹。如果使用虚拟 IoT 设备,记得为项目创建并激活 Python 虚拟环境。

  2. 架设摄像头硬件

    • Raspberry Pi:安装并连接 PiCamera。建议把摄像头固定在固定位置,例如把排线挂在纸箱或罐子上,或用双面胶把摄像头固定到货箱上,确保拍摄角度稳定一致;
    • 虚拟 IoT 设备:安装 CounterFit 以及 CounterFit PyCamera shim(counterfit-shims-picamera)。如果计划使用静态图片,需要提前拍摄一些对象检测器从未见过的货架照片;如果计划使用网络摄像头,则需要调整摄像头位置使其能清晰拍摄要检测的库存区域。
  3. 复用拍摄图像的代码:按照 制造项目第 2 课:从 IoT 设备捕获图像 的步骤,用摄像头完成图像拍摄与落盘。

  4. 复用调用分类器的代码:按照 制造项目第 2 课:从 IoT 设备分类图像 的步骤调用图片分类器。这段代码的大部分会被原样复用到对象检测中。

第二步:从分类器改造成对象检测器

用于分类图片的代码与用于检测对象的代码非常相似,唯一的核心差异在于调用 Custom Vision SDK 时使用的方法名,以及返回结果的形态。

任务:把分类代码改成检测代码

1. 删除三段分类代码

删除以下负责分类图像并处理预测结果的三行代码:

results = predictor.classify_image(project_id, iteration_name, image) for prediction in results.predictions: print(f'{prediction.tag_name}:\t{prediction.probability * 100:.2f}%')

2. 添加对象检测代码

在原来的位置加入以下代码:

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 = 0.3作为概率阈值,用列表推导式收集所有概率大于该阈值的预测;
  • 将过滤后的预测逐条打印到控制台,格式为标签名: 概率百分比

3. 运行并验证输出

运行程序后,它会拍摄一张照片、把图像发送给对象检测器,然后打印检测到的对象。虚拟 IoT 设备场景下,请确认 CounterFit 中已设置合适的图片或已选中网络摄像头;Raspberry Pi 场景下,请把摄像头对准货架上的物品。

实际运行输出大致如下:

pi@raspberrypi:~/stock-counter $ python3 app.py tomato paste: 34.13% tomato paste: 33.95% tomato paste: 35.05% tomato paste: 32.80%

在 Custom Vision 门户的Predictions选项卡中,你同样可以看到这张被检测的图片以及对应的预测值(如下图所示,检测出 4 罐番茄酱,置信度分别为 35.8%、33.5%、25.7% 和 16.6%)。

💁提示:你可能需要根据自己图片的实际情况把threshold调整到合适值——阈值设得越低,漏检越少但误检越多;设得越高则相反。

为什么必须过滤低概率预测?

图片分类器对每个标签只返回一个预测结果(即整张图片最可能属于哪个类别);而对象检测器会在同一张图片中返回多个结果——同一类对象可能在画面中出现多次,且模型会对每个候选框给出独立的概率。如果不加过滤,这些低置信度的候选框(例如重叠框、背景误检框)会全部打印出来,导致计数严重虚高。因此用阈值把低概率预测剔除是对象检测后处理中不可或缺的一步。

源码级对照:从分类到检测的完整代码

仓库中已经提供了改造完成的可运行代码,你可以直接对照查看:

  • Raspberry Pi 版本:code-detect/pi/stock-counter/app.py
  • 虚拟 IoT 设备版本:code-detect/virtual-iot-device/stock-counter/app.py

以虚拟设备版本为例,完整的调用链是:

from counterfit_connection import CounterFitConnection CounterFitConnection.init('127.0.0.1', 5000) import io from counterfit_shims_picamera import PiCamera from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient from msrest.authentication import ApiKeyCredentials camera = PiCamera() camera.resolution = (640, 480) camera.rotation = 0 image = io.BytesIO() camera.capture(image, 'jpeg') image.seek(0) with open('image.jpg', 'wb') as image_file: image_file.write(image.read()) prediction_url = '<prediction_url>' prediction_key = '<prediction key>' parts = 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) 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}%')

代码中的几个关键实现细节值得注意:

  • 从 URL 解析端点与项目信息:预测 URL 的结构是https://<endpoint>/customvision/v3.0/Prediction/<project_id>/detect/iterations/<iteration_name>/image。通过按/分割,parts[2]是主机名(拼出endpoint),parts[6]project_idparts[9]iteration_name,从而无需硬编码这三项配置。
  • 认证方式ApiKeyCredentials(in_headers={"Prediction-key": prediction_key})把预测密钥放在 HTTP 头中传给 Custom Vision 服务,这是官方 SDK 的标准认证方式。
  • PiCamera 与 shim 的差异:Raspberry Pi 版本使用真实的picamera.PiCamera,并在拍摄前time.sleep(2)等待摄像头感光元件稳定;虚拟设备版本使用counterfit_shims_picamera.PiCamera,图像来源由 CounterFit 应用界面控制。二者的其余逻辑完全一致。

下一步:把检测结果变成库存计数

当检测代码可以稳定输出"哪些对象、置信度多少"之后,你还可以基于返回结果中的bounding box(边界框)做更多事。边界框由lefttopwidthheight四个 0~1 之间的归一化值定义(0 为图片左上角原点,1 为图片的 100% 宽度/高度),既可用于在照片上绘制红色框调试,也可用于处理重叠框。

在 IoT-For-Beginners 的同一课中,从 IoT 设备统计库存(Raspberry Pi / 虚拟设备) 一节展示了如何:

  1. 用 Pillow 库把每个预测的边界框画回image.jpg
  2. 用 Shapely 库(Raspberry Pi 需先sudo apt install libgeos-dev)把边界框转成多边形,计算两两之间的重叠面积;
  3. 设定overlap_threshold(例如 0.2 表示允许 20% 重叠),删除重叠超过阈值的重复检测,最终打印Counted N stock items

仓库中对应的完整实现见 code-count/pi/stock-counter/app.py 与 code-count/virtual-iot-device/stock-counter/app.py。计数结果随后可以被发送到 IoT 服务,在库存不足时触发补货告警——这正是本课"库存检查"业务场景的落地点。

小结与清理提醒

至此,你的库存检测程序已经能够在 IoT 设备上调用已发布的 Custom Vision 对象检测器,输出货架上的库存对象及置信度。需要提醒的是:

  • 迭代模型:和图片分类器一样,你可以用 IoT 设备实拍的真实照片重新训练模型——在 Custom Vision 的Predictions选项卡中逐个校对边界框、修正标签、删除误检框,再重新训练、发布新迭代并更新设备端 URL 即可;
  • 资源清理:这是本项目的最后一课。完成本课及课后作业后,请参考 项目清理指南 删除云服务资源,避免产生持续费用。

后续若希望把检测能力扩展到 Arduino(Wio Terminal)平台,可参考同课的 Wio Terminal 对象检测指南;本仓库 code-detect/wio-terminal 中提供了 C++ 实现——它通过 HTTP POST 上传 JPEG 字节流、解析 JSON 响应中的predictions数组并按同一阈值过滤,原理与 Python 版本完全一致。

【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询