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 and processing),系统讲解如何用 IoT 技术改善食品加工环节中的水果质量检测:从训练基于图像的 AI 分类模型(Custom Vision)、在 IoT 设备上调用云端分类 API,到把模型下沉到 IoT Edge 设备本地推理,最后用接近传感器触发完整的质量检测流程。读完本文,你将掌握图像分类模型训练、IoT 摄像头取图、模型发布与端点调用、边缘计算部署(容器 + Azure IoT Edge + 部署清单)以及复杂 IoT 应用架构设计的完整实战链路,并能在仓库源码的支撑下直接复现每一步。
一、食品加工中的 IoT 质量检测:从人工分拣到 AI 分拣
当食物抵达中央集散中心或加工厂后,并不总是直接发往超市。大量食物要经过一系列加工步骤,其中最重要的就是按质量分拣。这个流程在过去完全依赖人工:田间采收时工人只摘取成熟的果实,工厂里果实沿传送带运输,员工手动剔除碰伤或腐烂的水果。课程作者在描述中坦言,自己学生时代曾在暑期工中亲手分拣过草莓——这显然不是一份轻松的差事。
更现代的方案则依赖 IoT 完成分拣。早期设备(例如 Weco 的分拣机)使用光学传感器检测农产品质量,例如剔除青色番茄。这类设备既可以部署在农场内的收割机上,也可以部署在加工厂中。随着人工智能(AI)与机器学习(ML)的进步,这些机器可以做得更高级:使用 ML 模型来区分水果与石块、泥土、昆虫等异物,甚至识别碰伤、疾病等早期问题。
🎓ML 模型是指在数据集上训练机器学习软件后得到的产物。例如,你可以训练一个 ML 模型区分成熟与未成熟的番茄,然后用它对新图片做判断。
围绕这一主题,制造篇共包含 4 个递进式课程(对应仓库 4-manufacturing/lessons 目录),构成一条完整的工程链路:
| 课程 | 核心任务 | 仓库目录 |
|---|---|---|
| 1. 训练水果质量检测器 | 用 Custom Vision 训练图像分类模型 | 1-train-fruit-detector |
| 2. 从 IoT 设备检测水果质量 | 摄像头取图并调用云端分类 API | 2-check-fruit-from-device |
| 3. 在边缘运行检测器 | 用 Azure IoT Edge 把模型部署到本地设备 | 3-run-fruit-detector-edge |
| 4. 用传感器触发检测 | 用接近传感器编排完整质量检测流程 | 4-trigger-fruit-detector |
💁 这些课程会使用部分云资源。若未完成本项目所有课程,务必按 clean-up.md 中的指引清理云资源,避免产生持续费用。
二、第一课:训练水果质量检测器(图像分类模型)
2.1 为什么需要 AI/ML 分拣
养活全球人口并不容易,尤其是要让价格对所有人都可负担。人力是最大成本之一,因此农民越来越依赖自动化与 IoT 工具来降低人工成本。机械收割虽省钱,却带来了新问题——收割时分拣能力的缺失。并非所有作物都均匀成熟:例如番茄,当大部分已可采摘时,藤上可能仍有青果。提前采收是浪费,但对农民来说,用机械统一收割、事后弃置未熟果实反而更便宜、更省事。
自动化收割把分拣从田间转移到了工厂:食物沿长长的传送带移动,成队的工人人工剔除不达标的果实。下一阶段是使用机器分拣——无论是内置于收割机还是在加工厂。第一代这类机器使用光学传感器检测颜色,通过杠杆或气流把青色番茄推进废料箱,让红色番茄继续在传送带网络上前进。
最新的分拣机则利用 AI/ML,用模型区分优劣农产品——不再仅仅依靠「青 vs 红」这样明显的颜色差异,而是识别疾病或碰伤这类更细微的外观特征。
2.2 什么是图像分类:传统编程 vs 机器学习
传统编程是「输入数据 → 应用算法 → 得到输出」;而机器学习把这个过程反转过来——从数据和已知输出出发,让算法从数据中学习,得到被称为machine learning model(ML 模型)的训练结果,再用它接收新输入并产生新输出。
🎓 机器学习算法从数据中学习的过程叫training(训练),输入与已知输出合称training data(训练数据);ML 模型给出的结果被称为predictions(预测)。
例如,用数百万张未熟香蕉图片作为输入训练数据(输出标记为unripe),再用数百万张熟香蕉图片(输出标记为ripe),算法便建立起模型。之后给模型一张全新的香蕉照片,它就能预测该香蕉是熟还是未熟。
ML 模型并不给出二元答案,而是给出概率。例如模型可能预测ripe为 99.7%、unripe为 0.3%,你的代码再挑选最佳预测并判定香蕉成熟。这类用于图像检测的 ML 模型称为image classifier(图像分类器):它接受带标签的图像,然后基于标签对新图像分类。
💁 这是简化说法,还存在无需标签输出的其他训练方式(如无监督学习)。想深入可参考课程 ML for beginners(24 节机器学习课程)。
2.3 迁移学习(Transfer Learning)
训练图像分类器通常需要数百万张图片。但事实是:一旦你有了一个在数百万甚至数十亿张杂项图像上训练好的分类器,就可以用少量新图片复用它并重新训练,得到极佳结果——这个过程叫transfer learning(迁移学习)。
🎓 迁移学习是把现有 ML 模型已学到的知识,迁移到基于新数据构建的新模型上。
可以把它类比为儿童积木书:一旦你认识半圆、矩形和三角形,就能根据它们的组合识别帆船或猫。分类器已经会识别形状,迁移学习则教会它什么组合构成船或猫——或是一根熟香蕉。这类模型的训练通常需要大量算力(GPU),而云端可以按需租用带 GPU 的强算力机器。
2.4 Custom Vision:云端训练图像分类器
Custom Vision是一款基于云的图像分类器训练工具,只需少量图片即可训练:通过 Web 门户、Web API 或 SDK 上传图片,为每张图片打上tag(分类标签),训练模型并测试其表现;满意后即可发布模型,通过 Web API 或 SDK 访问。
💁 Custom Vision 每个分类最少 5 张图即可训练,但越多越好;至少 30 张图效果更佳。免费层足够完成创建模型、训练与开发使用。
Custom Vision 隶属微软 Cognitive Services(认知服务)系列 AI 工具,包含语音识别与翻译、语言理解、图像分析等能力,在 Azure 中以免费层提供服务。
实操:创建认知服务资源
使用 Custom Vision 前,需要先用 Azure CLI 创建两个认知服务资源——一个用于训练、一个用于预测。
- 创建名为
fruit-quality-detector的资源组; - 创建免费版 Custom Vision训练资源:
az cognitiveservices account create --name fruit-quality-detector-training \ --resource-group fruit-quality-detector \ --kind CustomVision.Training \ --sku F0 \ --yes \ --location <location>F0即免费层;--yes表示同意认知服务的条款。若你的账号已在任何 Cognitive Services 上用过免费额度,则改用S0计费层。
- 创建免费版 Custom Vision预测资源:
az cognitiveservices account create --name fruit-quality-detector-prediction \ --resource-group fruit-quality-detector \ --kind CustomVision.Prediction \ --sku F0 \ --yes \ --location <location>实操:创建分类器项目
在 CustomVision.ai 用你的 Azure 账号登录,新建项目fruit-quality-detector,并注意:
- 资源选择
fruit-quality-detector-training; - 项目类型选择Classification(分类);
- 分类类型选择Multiclass(多分类);
- 域(Domain)选择Food(食物域)。
✅ 多花点时间熟悉 Custom Vision 门户中图像分类器的界面。
实操:采集并上传训练图片
训练需要多张不同质量的果实照片,分别标记为 good 与 bad(例如一根熟香蕉与一根过熟香蕉)。图片采集要点:
- 每张图片应只包含目标果实,背景保持一致或足够多样,且背景中不能存在与「熟/未熟」相关的专属特征——课程举了一个著名反例:皮肤癌分类器曾因恶性痣图片中都放了直尺而被训练成「识别直尺」;
- 图像分类器在极低分辨率下运行:Custom Vision 可接收最大 10240×10240 的训练与预测图,但模型实际按227×227训练与推理,大图会被缩小,因此被分类物体要占画面足够大的比例;
- 每个标签至少 5 张训练图(越多越好),另留几张用于测试;建议熟/未熟各准备两根香蕉,从多个角度拍摄,至少凑出 5 张训练 + 2 张测试;
- 图片须为 PNG 或 JPEG、小于 6MB;iPhone 拍摄的 HEIC 高分辨率图需要转换与缩小。
仓库 1-train-fruit-detector/images 目录下已经准备了现成的熟/未熟香蕉样本(如 training/ripe 与 training/unripe),可直接用于练习。上传时把熟果标记为ripe、未熟果标记为unripe,然后选择Quick Training(快速训练),训练通常需要几分钟完成。
🍌 如果你决定在训练期间把水果吃掉,请确保测试图已足够。
实操:测试与重新训练分类器
训练完成后,用未曾用于训练的测试图片测试模型,观察各标签的概率输出(例如未熟香蕉可能被预测为unripe98.9%、ripe1.1%)。分类器并不「理解」图片内容——它只是基于图像特征与标签的匹配概率做预测,因此预测结果可能出乎意料。改进方法是用预测错误的图片重新训练:每次 Quick Test 的图片与结果都会被存储,你可以在 Custom Vision 的预测结果中为图片打上正确标签并重新训练迭代。
三、第二课:从 IoT 设备检测水果质量
3.1 摄像头传感器原理
图像分类器要用于 IoT 应用,就必须用某种摄像头采集图片并发送到云端分类。摄像头传感器(Camera sensor)就是可连接到 IoT 设备的摄像头:能拍静止图像或流视频,有的返回原始图像数据,有的压缩为 JPEG/PNG 文件。大多数摄像头传感器采用图像传感器,每个像素是一个光电二极管:镜头把图像聚焦到传感器上,数百万个光电二极管检测落在其上的光并记录为像素数据。
🎓 图像传感器即 Active-Pixel Sensor(APS),最常见类型是互补金属氧化物半导体传感器,即CMOS传感器。
摄像头传感器属于数字传感器,通常借助通信库发送数字图像数据,并通过 SPI 等协议连接——因为图像数据量远大于温度传感器输出的单个数值。课程设计了思考题:微控制器硬件上,图像大小的限制是什么?(需要考虑内存与带宽约束。)
3.2 发布图像分类器(Model Iterations)
上一课训练好的模型还不能直接调用,必须先发布(Publish)。每次训练都会产生一个新的iteration(迭代,例如Iteration 1、Iteration 2),用于追踪不同数据集上的模型版本;Quick Test 时可用下拉框切换迭代对比结果。
发布步骤(在 Custom Vision 门户):
- 打开
fruit-quality-detector项目,选择顶部Performance页签; - 在侧边Iterations列表选中最新迭代;
- 点击该迭代的Publish按钮;
- 在发布对话框中把Prediction resource设为
fruit-quality-detector-prediction,名称保持Iteration2,点击发布; - 发布后点击Prediction URL,取If you have an image file区块中的 URL 与Prediction-Key。
预测 URL 形如:
https://<location>.api.cognitive.microsoft.com/customvision/v3.0/Prediction/<id>/classify/iterations/Iteration2/image其中<location>是创建资源时使用的区域,<id>是字母数字组成的长 ID。Prediction-Key 是安全密钥,只有携带该密钥的应用才被允许调用模型。
✅ 发布新迭代时名字会不同。想想:如何让 IoT 设备切换使用新的迭代?(答案:更新代码中的预测 URL 端点。)
3.3 从 IoT 设备调用分类 API:仓库源码剖析
调用分类器需要针对不同硬件写设备端代码,仓库提供了三种硬件的完整实现:
Raspberry Pi / 虚拟 IoT 设备(Python)
仓库 app.py(虚拟设备版在 virtual-iot-device/fruit-quality-detector/app.py)展示了一条完整的「取图 → 解析端点 → 调用分类」链路:
import io import time from 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 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 = '<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.classify_image(project_id, iteration_name, image) for prediction in results.predictions: print(f'{prediction.tag_name}:\t{prediction.probability * 100:.2f}%')关键点:
- 摄像头分辨率设为640×480、JPEG 格式;
- 通过字符串解析把预测 URL 拆解为
endpoint(https://+ 主机名)、project_id(URL 第 7 段)与iteration_name(第 10 段),无需手工配置三个独立参数; ApiKeyCredentials把Prediction-key放入请求头;- 打印每个标签的百分比概率。虚拟设备版仅将
PiCamera替换为counterfit_shims_picamera,并先行初始化 CounterFit 连接,逻辑完全一致。
Wio Terminal(Arduino / C++)
微控制器版在 main.cpp 中:用WiFiClientSecure建立 HTTPS 连接,按 C 键触发buttonPressed(),通过camera.readImageToBuffer()读取图像字节流,再以POST方式把原始字节发到PREDICTION_URL,响应用 ArduinoJson 解析出predictions数组并打印标签与概率:
int httpResponseCode = httpClient.POST(buffer, length); if (httpResponseCode == 200) { String result = httpClient.getString(); DynamicJsonDocument doc(1024); deserializeJson(doc, result.c_str()); JsonObject obj = doc.as<JsonObject>(); JsonArray predictions = obj["predictions"].as<JsonArray>(); // 逐条打印 tagName 与 probability }其中PREDICTION_URL、PREDICTION_KEY与 WiFi 凭据都在 config.h 中通过占位符配置;该文件还内置了Microsoft Azure DigiCert Global Root G2根证书用于 TLS 握手,保证请求不会被中间人窃听。请求头同时包含Content-Type: application/octet-stream与Prediction-Key。
💁 三类硬件的取图说明分别见 wio-terminal-camera.md、pi-camera.md、virtual-device-camera.md;分类调用说明见 wio-terminal-classify-image.md 与 single-board-computer-classify-image.md。
3.4 用设备实拍图改进模型
设备实拍的预测结果未必符合预期——因为训练数据与预测数据的成像环境不同。想让分类器表现最佳,训练图片应尽量接近预测图片:手机拍摄的清晰度、锐度与色彩,和 IoT 设备摄像头拍摄的差异明显(课程对比图中 Raspberry Pi Camera 与 iPhone 拍摄同一根香蕉,画质差异肉眼可辨)。
改进流程:
- 用 IoT 设备分类多张熟/未熟果实图片;
- 在 Custom Vision 门户的Predictions页签中用这些实拍图重新训练(参考 第一课的重新训练章节);
- 若实拍图与原始训练图差异过大,可在Training Images页签勾选旧图并Delete删除;
- 训练新迭代并按上文步骤发布;
- 更新代码中的端点 URL,重新运行应用,重复直到结果满意。
四、第三课:在边缘运行水果检测器
4.1 边缘计算 vs 云计算
前几课把图片经互联网发给云端服务分类,这些调用耗时、花钱,且对某些图像数据存在隐私顾虑。边缘计算(Edge computing)把数据处理移到离数据产生地尽可能近的地方——即你自己的内部网络,而不是云端。
边缘计算的优势:
- 速度——动作在同一网络内完成,无需跨互联网往返;数据走更短距离、更快到达。课程举了一个直观例子:从欧洲向美国云服务发数据,仅跨大西洋光缆至少就要 28ms(还没算光电转换与排队)。此外边缘计算网络流量更少,不易被有限的互联网带宽拥塞拖慢;
- 远程可达性——在连接受限、无连接或连接费用过高的场景(如人道主义灾区、发展中地区)依然可用;
- 更低成本——在边缘设备上完成数据采集、存储、分析与动作触发,减少云服务用量;近年还出现了专为边缘计算的 AI 加速板卡;
- 隐私与安全——数据留在本地网络,不上传云端;分析后无需长期存储,大幅降低数据泄露风险(典型如医疗数据、安防监控画面);
- 处理不安全设备——有已知安全缺陷的设备可接入独立网络,通过网关 IoT Edge 设备再连主网/互联网,由边缘设备管理数据流;
- 支持不兼容设备——只能走 HTTP 或仅支持蓝牙、无法直连 IoT Hub 的设备,可通过 IoT Edge 网关转发消息。
边缘计算的劣势(本质是云优势的反面):
- 规模与弹性——云可实时增减服务器应对需求;边缘扩容需要人工添加设备;
- 可靠性与韧性——云通常多地域多服务器冗余;边缘要达到同等冗余需要大量投入与配置;
- 维护——云服务商负责系统维护与更新。
课程同时指出,部分风险会被边缘计算的性质天然缓解:例如工厂里处理机械数据的边缘设备,若工厂断电,生成数据的机器也断电,并不需要额外备份边缘设备。实际 IoT 系统往往采用云 + 边缘的混合架构,按系统、客户与维护者需求各取所长。
4.2 Azure IoT Edge 与模块/容器机制
Azure IoT Edge帮助你把工作负载从云端下沉到边缘:把一台设备设为边缘设备,即可从云端向它部署代码。例如在云端训练图像分类器,再从云端部署到边缘设备;IoT 设备向边缘设备发图分类,而非把图发到互联网。需要新模型时,在云端重新训练并借助 IoT Edge 更新边缘设备上的模型。
🎓Workloads(工作负载)指做某种工作的任何服务(AI 模型、应用、serverless 函数);部署到 IoT Edge 的软件称为modules(模块),默认运行与 IoT Hub 通信的
edgeAgent与edgeHub模块。
IoT Edge 内建于 IoT Hub,因此可以用管理 IoT 设备的同一服务(同一安全级别)管理边缘设备。IoT Edge 运行的代码来自容器(containers)——在计算机上隔离运行的自包含应用,像「电脑中的另一台电脑」,默认无法访问主机资源,通过开放端口对外提供或暴露服务。Custom Vision 模型可导出为容器,运行时对外暴露与云版本相同的 REST API,只是端点指向运行容器的边缘设备。
4.3 注册并设置 IoT Edge 设备
先在fruit-quality-detector资源组创建 IoT Hub(唯一名称,基于fruit-quality-detector),再注册边缘设备(与普通设备命令几乎相同,仅多一个--edge-enabled标志):
az iot hub device-identity create --edge-enabled \ --device-id fruit-quality-detector-edge \ --hub-name <hub_name>获取连接字符串:
az iot hub device-identity connection-string show --device-id fruit-quality-detector-edge \ --output table \ --hub-name <hub_name>IoT Edge 运行时只运行 Linux 容器,可跑在 Linux 上,或 Windows 上通过 Linux 虚拟机运行。选型参考:
- Raspberry Pi(树莓派 OS 是 Debian Linux 变体)→ 按官方 Linux 安装指南安装 IoT Edge 并写入连接字符串;
- 其他 Linux 电脑 → 同上;
- Windows → 在 Linux 虚拟机中安装 IoT Edge 运行时;
- macOS → 按仓库 vm-iotedge.md 在云端创建装有 IoT Edge 的 Linux 虚拟机。
4.4 导出模型并构建容器
要在边缘运行分类器,必须先从 Custom Vision导出。Custom Vision 能生成标准模型与compact 模型(紧凑模型)——后者通过各种技术压缩模型体积,使其小到可以下载部署到 IoT 设备。创建项目时用的Food域在 Custom Vision 中同时提供 standard 与 compact 两种形态,只需在项目Settings中把域切换为Food (compact),勾选Basic platforms (Tensorflow, CoreML, ONNX, ...)导出能力,保存后重新用Quick training训练。
训练完成后进入Performance页签,对最新迭代点Export,选择DockerFile:
- Linux 电脑 / Windows / 虚拟机运行 IoT Edge → 选Linux版本;
- Raspberry Pi 运行 IoT Edge → 选ARM (Raspberry Pi 3)版本。
🎓 Docker 是最流行的容器管理工具之一,DockerFile 是构建容器的指令集。导出后你会得到一个包含 DockerFile 与模型托管应用代码(内含 REST API)的 zip 包。
接下来需要把模型构建成容器并推送到容器注册表(container registry)——本课使用Azure Container Registry(非免费服务,使用完务必按 clean-up.md 清理)。整体流程为「构建容器 → 推送到注册表 → IoT Edge 从注册表拉取并部署到设备」。
# 创建容器注册表(名称需全局唯一,仅限字母数字) az acr create --resource-group fruit-quality-detector \ --sku Basic \ --name <Container registry name> # 登录 az acr login --name <Container registry name> # 开启管理员模式以便生成密码 az acr update --admin-enabled true \ --name <Container registry name> # 生成密码并记下 PASSWORD az acr credential renew --password-name password \ --output table \ --name <Container registry name>在解压后的模型目录中构建并打标签:
docker build --platform <platform> -t <Container registry name>.azurecr.io/classifier:v1 .- 平台:Raspberry Pi 用
linux/armhf,其余用linux/amd64;若就在 IoT Edge 设备本机构建可省略--platform(默认当前平台); - Linux/树莓派 OS 上可能需要
sudo; - 容器标签
classifier:v1定义名称与版本,更新时可换新版本号重新构建。
课程给出了真实构建日志示例,其中 Dockerfile 内部执行了pip install numpy~=1.17.5 tensorflow~=2.0.2 flask~=1.1.2 pillow~=7.2.0与mscviplib==2.200731.16等依赖安装——说明导出的容器是一个内置 TensorFlow 推理 + Flask REST API 的完整服务。
推送容器到注册表并验证:
docker push <Container registry name>.azurecr.io/classifier:v1 az acr repository list --output table --name <Container registry name>4.5 部署清单(deployment.json)详解
部署到边缘设备需要一个deployment manifest(部署清单)——列出要部署到边缘设备的模块的 JSON 文档。仓库提供了完整可用的示例 deployment.json,其结构包含四大部分:
$edgeAgent.properties.desired:运行时配置。runtime.type为docker,minDockerVersion为v1.25;registryCredentials声明拉取私有镜像所需的注册表凭据(用户名、密码、地址);systemModules指定系统模块edgeAgent与edgeHub的镜像(mcr.microsoft.com/azureiotedge-agent:1.1、azureiotedge-hub:1.1,后者用createOptions暴露 5671/8883/443 三个端口);modules:业务模块ImageClassifier,镜像为<Container registry name>.azurecr.io/classifier:v1,restartPolicy为always,createOptions中ExposedPorts与HostConfig.PortBindings把容器 80 端口映射到主机 80 端口,使分类 REST API 可通过http://<edge设备>/image访问;$edgeHub.properties.desired:路由upstream: FROM /messages/* INTO $upstream把消息转发到云端,storeAndForwardConfiguration.timeToLiveSecs设为 7200(离线时消息缓存存活时间)。
使用前把三处<Container registry name>(ImageClassifier模块与registryCredentials内)和<Container registry password>替换为实际值,然后执行:
az iot edge set-modules --device-id fruit-quality-detector-edge \ --content deployment.json \ --hub-name <hub_name>部署后 SSH 连接边缘设备,用iotedge list查看模块状态,用iotedge logs ImageClassifier查看日志(日志中应出现Loading model...Success!与Running on http://0.0.0.0:80/)。接着用 curl 本地测试分类接口:
curl --location \ --request POST 'http://<IP address or name>/image' \ --header 'Content-Type: image/png' \ --data-binary '@<file_Name>'返回的 JSON 中包含predictions数组(如ripe0.9996、unripe0.0004)。值得注意的是:这里不需要 Prediction-Key,因为不经过 Azure 资源,安全交由内部网络策略管理,而不是依赖公共端点与 API 密钥。
💁 在边缘运行分类器的代价是:模型与 Custom Vision 项目不再连接,Predictions 页签看不到边缘分类的图片——因为图片从未离开你的网络。这正是隐私与离线能力的来源,但「用新图片改进模型」就需要另想存储与重标注的方案。
五、第四课:用传感器触发水果质量检测
5.1 复杂 IoT 应用的架构:Things → Insights → Actions
IoT 应用由大量组件构成,可以被概括为:things(物,设备)发送数据并产生insights(洞察),洞察驱动actions(动作)以改进业务或流程。例如发动机(thing)发送温度数据,用数据评估发动机是否正常(insight),据此主动安排维护计划(action)。
课程给出的参考架构(Reference IoT architecture,详见 iot-reference-architecture.png)中:
- Things:从传感器采集数据、可能借助边缘服务解释数据(如图像分类器解释图像),数据发往 IoT 服务;
- Insights:来自 serverless 应用,或对存储数据的分析;
- Actions:发给设备的命令,或供人决策的数据可视化。
Azure 生态对应关系(见 iot-reference-architecture-azure.png):设备代码采集传感器数据、用 Custom Vision(云端与边缘)分析图像并发往 IoT Hub(Things);Azure Functions 响应 IoT Hub 消息、Azure Storage 存储数据供后续分析(Insights);根据云端决策控制执行器、用 Azure Maps 可视化数据(Actions)。在架构设计时必须持续考虑数据与安全:设备收发什么数据?如何保护这些数据?如何控制设备与云服务的访问?
5.2 设计水果质量控制系统原型
假设要为加工厂构建质量检测系统:果实沿传送带到达,需要检测到果实后拍照、用边缘 AI 模型检查,结果发送到云端存储,若未熟则发出告警以便剔除。按 Things/Insights/Actions 拆解:
| Things | 检测果实到达的探测器;拍照并分类的摄像头;运行分类器的边缘设备;通知未熟果实的设备 |
| Insights | 决定检查果实成熟度;存储成熟度分类结果;判断是否需要告警 |
| Actions | 向设备发送「拍照并用分类器检查」的命令;向设备发送「告警果实未熟」的命令 |
原型的工作流:带接近传感器的 IoT 设备检测到果实到达 → 发消息到云端 → 云端 serverless 应用向另一设备发命令拍照并分类 → 带摄像头的设备拍照、发送给边缘图像分类器,结果发回云端 → 云端 serverless 应用存储数据供后续分析(如统计未熟果实占比),若未熟则向另一台设备发命令用 LED 告警工厂工人。
💁 整个应用也可用单台设备实现(把触发、分类、LED 控制逻辑内建,IoT Hub 仅用于统计与配置),本课拆分为多设备是为了演示大规模 IoT 应用的架构理念。
5.3 接近传感器:触发检测的时机
IoT 设备需要一个「果实就位」的触发信号——一个自然的选择是测量果实与传感器之间的距离。接近传感器(proximity sensor)通常发射一束电磁辐射(激光或红外光),检测物体反射的辐射,通过发射到反弹的时延计算距离。
💁 你大概率用过接近传感器而不自知:智能手机通话时贴近耳朵会自动熄屏、防止误触挂断,靠的就是接近传感器。
仓库中虚拟设备的距离传感器实现位于 distance_sensor.py,通过 CounterFit 模拟 VL53L0X 激光测距传感器,循环读取距离(毫米)并打印:
from counterfit_shims_rpi_vl53l0x.vl53l0x import VL53L0X distance_sensor = VL53L0X() distance_sensor.begin() while True: distance_sensor.wait_ready() print(f'Distance = {distance_sensor.get_distance()} mm') time.sleep(1)Wio Terminal 的 C++ 版(main.cpp)与树莓派版(distance_sensor.py)实现同样的循环读数逻辑。各硬件的接线与配置见 wio-terminal-proximity.md、pi-proximity.md、virtual-device-proximity.md。
5.4 提前定义消息数据结构
原型中多个组件互相通信:距离传感器把距离发给 IoT Hub;IoT Hub 向摄像头设备发拍照命令;分类结果发回 IoT Hub;IoT Hub 向 LED 设备发未熟告警命令。动手构建前应先定义好消息结构——课程提醒:几乎所有资深开发者都曾因「发送的数据与预期不符」而花费数小时甚至数周排查 bug。
以温度数据为例,字段命名(temperaturevstemp)与单位(°C vs °F)都必须事先约定并保持一致:
{ "temperature": 20.7 }对质量检测器而言,关键设计问题包括:距离的判断在哪里做?是设备自行判断「果实足够近」后通知 IoT Hub 触发分类,还是持续上报距离、由 IoT Hub 决定?课程给出的答案是「看情况」:
- 由 IoT Hub 决策 → 需要发送多次距离测量值;
- 消息过多 → 增加 IoT Hub 费用与设备带宽需求(工厂里可能有数百万设备),还可能拖慢设备;
- 由设备决策 → 需要提供配置手段以便现场微调(例如不同果实触发距离不同)。
5.5 用开发板模拟多台 IoT 设备
构建原型时,需要让一块开发板扮演多台设备(发遥测、响应命令):
- 树莓派/虚拟硬件(单板计算机):可以同时运行多个应用,因此为每个「IoT 设备」创建一个 Python 文件、在不同终端会话中分别运行即可。注意有些硬件不支持多应用同时访问;
- 微控制器:无法同时运行多个应用,必须把多个设备逻辑写进单一应用。建议:为每个 IoT 设备建一个或多个类(如
DistanceSensor、ClassifierCamera、LEDController),各自提供setup/loop方法由主函数调用;在单一位置统一处理命令并分发到对应设备类;主loop中统一时序(如每秒处理一次的设备,用一个计数器每 10 次循环再处理另一个设备)。
5.6 从原型走向生产
原型是最终生产系统的基础,两者差异包括:
- 加固组件——使用能承受工厂噪声、高温、振动与压力的工业级硬件;
- 内部通信——部分组件直连通信、避免绕道云端,只在需要存储时才把数据发往云端(可通过直连或网关设备在边缘运行部分 IoT 服务);
- 可配置选项——不同工厂场景不同,如接近传感器可能需要在不同距离检测不同果实,触发距离不应硬编码,而应通过云(如device twin设备孪生)动态配置;
- 自动化剔除——用自动化设备替换 LED 告警,直接移除未熟果实。
✅ 思考题:生产设备与开发套件还有哪些其他差异?
六、配套资源与学习路径
- 课程作业:第一课作业见 assignment.md(训练多果蔬分类器);第四课作业见 4-trigger-fruit-detector/assignment.md(构建完整质量检测器);
- 可视化笔记:本模块四课对应 sketchnotes/lesson-15.jpg、lesson-16.jpg、lesson-17.jpg、lesson-18.jpg;
- 云资源清理:若不会继续完成本项目的其余课程,务必按 clean-up.md 清理云资源;
- 课后扩展:深入理解容器(OS 级虚拟化)、边缘计算与 5G 的关系、设备孪生机制、OPC-UA(工业自动化中的机器间通信协议)等主题;
- 本模块全部课程:由 1-train-fruit-detector、2-check-fruit-from-device、3-run-fruit-detector-edge、4-trigger-fruit-detector 四课组成,所有示例代码、配置模板与训练图片均可在对应目录下找到,可结合本文逐课动手复现。
总结
制造与加工模块演示了一条完整且可直接落地的 IoT 食品质量检测技术栈:训练(Custom Vision 图像分类 + 迁移学习)→ 调用(IoT 摄像头取图 + REST API 分类)→ 下沉(紧凑模型导出为容器,经 Azure IoT Edge 部署到本地)→ 编排(接近传感器触发 + serverless 决策 + LED/执行器动作)。整个链路既涵盖了 ML 模型、边缘计算、容器化等通用技术原理,也提供了 Python 与 Arduino 双平台的源码实现和完整的deployment.json部署清单。对希望进入智能制造、视觉质检领域的开发者来说,这是从入门到实战的最佳跳板。
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考