在树莓派与虚拟 IoT 设备上调用 IoT Edge 图像分类器:水果质量检测端侧推理实战(IoT-For-Beginners)

发布时间:2026/9/17 1:13:49

在树莓派与虚拟 IoT 设备上调用 IoT Edge 图像分类器:水果质量检测端侧推理实战(IoT-For-Beginners) 在树莓派与虚拟 IoT 设备上调用 IoT Edge 图像分类器水果质量检测端侧推理实战IoT-For-Beginners【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本篇技术指南围绕微软开源课程 IoT-For-Beginners 中《在边缘运行水果检测器》4-manufacturing 第 3 课的树莓派/虚拟 IoT 设备分支展开讲解如何将物联网设备从把图片上传云端分类切换到调用本网络内 IoT Edge 设备上托管的图像分类器。读完本文你将掌握 IoT Edge 分类器的 REST 调用地址格式、为什么必须用 REST API 替代 Custom Vision Python SDK、如何改造app.py完成端侧推理以及如何解读返回的 JSON 预测结果。文档定位与适用范围本文对应的原始文档为 translations/da/4-manufacturing/lessons/3-run-fruit-detector-edge/single-board-computer.md英文原版位于 single-board-computer.md。它是本课使用你的 IoT Edge 设备环节的硬件分支指南适用于两类设备树莓派Raspberry Pi使用真实 PiCamera 拍摄并分类图片虚拟 IoT 设备Virtual IoT device通过 CounterFit 模拟摄像头在本机运行代码。同一课程下还有面向 Wio Terminal 的独立指南 wio-terminal.md以及创建承载 IoT Edge 的云端虚拟机的 vm-iotedge.md。本指南的前置条件是已完成本课前半部分——在 IoT Hub 注册 IoT Edge 设备、将 Custom Vision 训练出的分类器导出为容器、推送至容器注册表、并通过部署清单下发到边缘设备且ImageClassifier模块处于运行状态验证方法见 README.md 的 Verify the classifier is running 一节。核心概念Edge 分类器的调用地址与 REST 接口上一课2-check-fruit-from-device中IoT 设备把摄像头拍到的图片经互联网发送到 Custom Vision 云端服务进行分类这种做法存在延迟、费用与隐私三方面问题。本课的做法是把分类器以容器形式部署到本网络内的 IoT Edge 设备上让图片在局域网内完成推理。一旦ImageClassifier模块在边缘设备上运行它就通过容器暴露的 REST API 提供服务。文档明确给出调用地址格式http://IP address or name/image其中IP address or name替换为运行 IoT Edge 的计算机的 IP 地址或主机名。例如在 IoT Edge 设备本机上测试时可直接使用localhosthttp://localhost/image说明该容器同时会通过createOptions中的PortBindings把容器内80/tcp端口映射到宿主机的80端口因此上述 URL 中的/image路径即容器内 Web 服务暴露的推理端点。完整的部署清单可参考仓库中的 deployment.json。为什么必须改用 REST API 调用文档特别强调了一个关键约束Python-biblioteket til Custom Vision fungerer kun med modeller, der er hostet i skyen, ikke med modeller hostet på IoT Edge.Custom Vision 的 Python 库只适用于云端托管的模型不适用于托管在 IoT Edge 上的模型。也就是说上一课使用的azure.cognitiveservices.vision.customvision.prediction与msrest.authentication这两个依赖在此处不再适用必须改用通用的requests库直接发起 HTTP POST 请求。这在源码中得到了印证——仓库中两个修改完成版的 pi/app.py 与 virtual-iot-device/app.py 均只保留io、requests、time与摄像头相关导入不再出现任何 Custom Vision SDK 导入。另一个与云端调用截然不同的点是调用 Edge 分类器无需Prediction-Key。因为请求不会打到 Azure 公共端点而是在内部网络中完成安全交由内网策略负责而不是依赖公共端点加 API Key。操作任务改造 app.py 调用 IoT Edge 分类器以下步骤严格继承自关联文档的任务清单并结合仓库源码给出了每一步的落点与说明。第 1 步打开项目并激活环境在 VS Code 中打开fruit-quality-detector项目如果使用虚拟 IoT 设备确保虚拟环境.venv已激活。第 2 步移除 Custom Vision 相关导入打开app.py删除来自azure.cognitiveservices.vision.customvision.prediction和msrest.authentication的 import 语句。第 3 步添加 requests 导入在文件顶部添加import requests第 4 步删除云端分类代码删除图片保存之后的所有代码即从image_file.write(image.read())之后一直到文件末尾的全部内容。这意味着原本构建预测请求、携带Prediction-Key、调用云端端点并打印结果的逻辑全部移除。第 5 步追加 Edge 分类调用代码将以下代码追加到文件末尾prediction_url URL headers { Content-Type : application/octet-stream } image.seek(0) response requests.post(prediction_url, headersheaders, dataimage) results response.json() for prediction in results[predictions]: print(f{prediction[tagName]}:\t{prediction[probability] * 100:.2f}%)将URL替换为你的分类器地址形如http://IP address or name/image。这段代码的含义是代码行作用prediction_url URL指向 IoT Edge 设备上分类器容器的 REST 端点headers {Content-Type: application/octet-stream}声明请求体为原始二进制流图片字节image.seek(0)将图片缓冲区的读写指针重置到开头确保发送完整图片数据requests.post(prediction_url, headersheaders, dataimage)以图片二进制内容作为请求体发起 REST POST 请求response.json()将响应解码为 JSON 结构for prediction in results[predictions]遍历分类结果按标签打印百分比概率第 6 步运行并观察控制台输出运行代码将摄像头对准水果虚拟设备则让水果出现在 CounterFit 的 Web 摄像头画面中。控制台输出类似(.venv) ➜ fruit-quality-detector python app.py ripe: 56.84% unripe: 43.16%每一行对应一个标签ripe/unripe及其置信度百分比。源码佐证两份完整版 app.py仓库中提供了两个硬件分支的最终完整代码可直接对照参考树莓派版code-classify/pi/fruit-quality-detector/app.py虚拟设备版code-classify/virtual-iot-device/fruit-quality-detector/app.py树莓派版完整代码如下其核心思路与文档描述完全一致import io import requests import time from picamera import PiCamera camera PiCamera() camera.resolution (640, 480) camera.rotation 0 time.sleep(2) 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 URL headers { Content-Type : application/octet-stream } image.seek(0) response requests.post(prediction_url, headersheaders, dataimage) results response.json() for prediction in results[predictions]: print(f{prediction[tagName]}:\t{prediction[probability] * 100:.2f}%)从源码结构可以看出两个值得注意的细节camera.resolution (640, 480)将拍摄分辨率设为 640×480图片以 JPEG 格式捕获到io.BytesIO内存缓冲区随后既落盘保存为image.jpg又复用同一缓冲区作为 POST 请求体通过seek(0)重置指针图片同时以文件形式保存方便本地核对拍摄内容但这并不是调用分类器所必需的步骤。虚拟设备版virtual-iot-device/app.py的差异仅在于设备初始化部分它使用CounterFitConnection.init(127.0.0.1, 5000)连接 CounterFit 仿真服务并通过counterfit_shims_picamera的PiCamera替代真实摄像头从image.seek(0)之后的分类调用逻辑与树莓派版完全一致。部署上下文分类器是如何跑到 Edge 上的虽然本指南聚焦如何使用 Edge 分类器但理解调用地址的由来有助于排查问题。整条部署链路见 README.md 的 Prepare your container for deployment 与 Deploy your container 两节为在 Custom Vision 门户将项目域名切换为Food (compact)并重新训练导出为 DockerFile 容器使用docker build --platform platform -t Container registry name.azurecr.io/classifier:v1 .构建镜像树莓派目标平台为linux/armhf其余为linux/amd64使用docker push推送至 Azure Container Registry编写部署清单 deployment.json其中ImageClassifier模块的镜像地址为Container registry name.azurecr.io/classifier:v1并通过createOptions暴露80/tcp端口执行az iot edge set-modules --device-id fruit-quality-detector-edge --content deployment.json --hub-name hub_name下发模块在边缘设备上使用iotedge list确认ImageClassifier、edgeAgent、edgeHub三个模块均为running状态。调用地址http://IP address or name/image正是步骤 4 中映射到宿主机80端口的容器 REST 端点。在正式改造app.py之前可以先用 curl 做一次冒烟测试curl --location \ --request POST http://IP address or name/image \ --header Content-Type: image/png \ --data-binary file_Name返回的 JSON 中predictions数组即为app.py中遍历打印的数据来源例如{ predictions: [ { probability: 0.9995615482330322, tagName: ripe }, { probability: 0.0004384400090202689, tagName: unripe } ] }与 Wio Terminal 方案的差异对照同一任务在 Wio TerminalArduino 平台上的改法见 wio-terminal.md反映了硬件差异带来的关键区别项目树莓派/虚拟设备PythonWio TerminalC/Arduino通信库requestsPythonWiFiClient替代WiFiClientSecure证书无删除config.h中的CERTIFICATE预测密钥无删除config.h中的PREDICTION_KEY及Prediction-Key请求头调用方式requests.post发送图片字节classifyImage函数内 POST 到PREDICTION_URL两者的共同点是因为 Edge 分类器走 HTTP而非 HTTPS均不再需要 TLS 证书与云端 API Key。端侧推理的取舍与重训练注意事项使用 Edge 分类器后有一个容易被忽略的行为变化Edge 上分类过的图片不会回传云端。因此 Custom Vision 门户的Predictions标签页里看不到这些推理样本模型也就无法像纯云端方案那样自动积累标注素材用于再训练。这既是隐私与离线能力的优势图片不出内网、无网也能工作也是模型持续改进的代价——需要另行设计图片采集与人工复分类的机制来补充训练集。从整体架构看这正体现了边缘计算在速度、远程可用性、成本、隐私、兼容设备接入等方面的收益以及其在弹性伸缩、冗余可靠性、运维维护上的劣势详见 README.md 的 Edge computing 一节。实际 IoT 系统通常按需混合使用云与边缘。小结通过本指南的改造你的fruit-quality-detector程序已经完成从云端推理到边缘推理的切换Custom Vision 分类器以容器形式驻留在 IoT Edge 设备上IoT 设备仅需把图片 POST 到http://IP address or name/image即可在局域网内获得ripe/unripe的概率结果。整个改动只涉及删除 SDK 依赖、引入requests、替换调用地址三步却换来了更低的延迟、更省的云资源开销与更好的数据隐私。相关完整代码可进一步查看 code-classify/pi 与 code-classify/virtual-iot-device部署清单参考 code-deployment/deployment/deployment.json。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/17 1:13:49

复杂环境下车牌识别技术实战:从检测到识别的完整方案解析

1. 复杂环境下车牌识别到底难在哪:先看清问题再动手做车牌识别这个方向,很多人一开始都会觉得“不就是先检测车牌,再识别上面的字符吗”,等自己拿真实数据跑一遍才发现完全不是那么回事。我最初也是在干净数据集上把准确率刷到95%…

2026/9/17 1:13:49

Hyper-V内部网络外网连通:路由模式替代NAT的实战方案

1. 这不是“配个IP”那么简单:Hyper-V内部网络固定IP外网连通的真实场景与核心矛盾你搜到这个标题,大概率正卡在某个具体环节:虚拟机里装好了CentOS Stream 10,nmcli配了静态IP,ping 192.168.137.1通了,但p…

2026/9/17 1:13:49

Ubuntu 20.04/Debian 10安装向日葵远程控制:依赖问题排查全攻略

Ubuntu 20.04和Debian 10这两套系统,我前后装了不下十次向日葵远程控制。为什么反复装?因为每次换一台机器,依赖问题都会以新的姿势出现——有的缺libminizip1,有的报libxss1找不到,还有的干脆连dpkg都卡在半路。这篇文…

2026/9/17 2:13:53

232元4年WPS超级会员值不值?拆解六项高频权益与避坑指南

上个月帮同事整理一份报销单据,她盯着 PDF 里的一串数字想直接改,免费版只能把文件转成图片再对着发愁。她顺口问我一句:WPS会员到底值不值?我把手机里那份232 元 4 年的 WPS 超级会员订单翻出来给她看——平均下来一年 58 块&…

2026/9/17 2:13:53

WPS与WPS 365的本质区别:从个人工具到企业办公平台

1. 产品定位差异:一套办公软件和一个办公平台,根本不是一回事先说个我实际遇到的情况。去年有个朋友的公司准备采购办公套件,行政提了两个方案上来:一个是WPS,一个是WPS 365,预算差了不少。行政自己也说不清…

2026/9/17 2:13:53

IP获取、伪造、隐藏与挖掘:网络安全基本功实战指南

搞网络安全的,不管你是做红队渗透、蓝队防守,还是日常搞等保测评、应急响应,天天打交道最多的就是IP。围绕IP,我被人问过无数次的问题无非四类:IP怎么拿到手,能不能伪造,怎么藏起来,…

2026/9/17 2:13:53

国产PLM选型指南:从研发数据管理到落地避坑全解析

1. 选型先想清楚:你真的需要PLM,还是需要把设计流程理顺做PLM选型这些年,我见过太多企业一上来就问“哪个国产PLM系统最好”,开口就要对比厂商名单。但真正走进车间和研发部看一圈下来,一半以上的企业其实还没到选型阶…

2026/9/17 2:13:53

gPTP时间同步原理与工程实践:IEEE 802.1AS与TSN网络

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/17 2:08:52

case24_ieee_rts.m解析:IEEE-RTS 24节点可靠性评估与N-1校验实践

简介:面向电力系统可靠性与规划研究的MATLAB源码资源,基于IEEE RTS-24节点标准测试系统构建,适用于学习可靠性评估、潮流计算、故障模拟与状态估计等场景。压缩包仅含1个m文件,大小约2KB,代码精简且可读性强&#xff0…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码