我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

树莓派5工业视觉检测实战:从散热供电到模型部署的完整踩坑记录

树莓派5工业视觉检测实战:从散热供电到模型部署的完整踩坑记录 车间活路多最近接到个新需求——用小尺寸设备做产线视觉检测。我一开始想上工业小主机结果看了一眼预算又想了想手上那块已经吃灰的树莓派52023年底买的性能提升确实明显但一直没找到正儿八经的落地场景。这次我决定把它带进车间试试顺便把一路踩过的坑都记下来。原以为把模型文件拷上去跑个Python脚本就能完事。真到了车间才发现从开发台到生产现场中间至少隔着六件事散热、供电、系统、模型部署、设备通信、长期稳定运行。今天这篇东西就是围绕这六件事展开的适合手里正好有树莓派5、想把它用于工业或准工业场景的朋友。如果你是打算跑个demo测测性能那可以跳过一半的篇幅如果你是真的想让它在产线旁边连续跑一周以上那每一条都是我用实际试验换来的。1. 项目场景与整体思路1.1 车间里的活儿是什么车间要检测小尺寸继电器外壳的外观缺陷主要是凹点、缺料和错位。原来靠人工目检速度慢漏检率看工人状态现在想上一套简单的视觉检测装置。方案要求不高一节流水线节奏一张图片判断合格还是不合格把结果告诉旁边工位的控制器。我手头有一块树莓派58GB内存版本跑了几个月的网页服务和一些小脚本一直没派上大用场。这次视觉检测的算力需求——YOLOv5s级别的小模型——正好在它的能力边界附近。于是搭了个测试架USB工业相机朝下拍树莓派5放在防尘盒里旁边接了块继电器小板模拟现场输出信号。说句实在话这套东西如果放到工业PC上半小时就能跑通。但换成树莓派5整套流程的侧重点完全变了你处理的不是“怎么把算法跑出来”而是“怎么在有限散热、有限电源、有限稳定性的前提下把算法连续跑下去”。各种奇怪的问题会在第一天、第三天、第五天分别冒出来这也是我写这篇记录的最大动机。1.2 为什么选树莓派5而不是别的对比过几个方案。工业小主机最省心但价格足够买五六块树莓派5Jetson Nano的算力差不多的水平但生态和周边模块没树莓派丰富实在的方案里树莓派5算是“综合成本最低、周边最全、坏了就换不心疼”的选择。树莓派5的优势在回车间的场景下很具体GPIO直连继电器板不用多买转接模块支持USB启动能把系统从SD卡挪到固态盘上双摄像头接口以后想加第二路检测不用加板子四个USB 3.0口接相机、接键鼠、接U盘都不会互相打架。短板也明确CPU是四核Cortex-A76跑大模型不现实跑个微型YOLOv5s还能接受对供电敏感对温度敏感这俩如果不好好处理能让你怀疑人生。所以整体技术路线定下来树莓派5 Ubuntu 自己训练的YOLOv5模型 ONNX Runtime推理 串口/MQTT外发结果。下一步就是逐个解决那六件事。2. 第一件事和第二件事散热和供电硬件底子先打牢2.1 散热这块我建议别用原厂小风扇树莓派5的性能释放比树莓派4激进得多代价就是发热同样激进。开发台上放着跑室温25度我裸板测过一个满载循环CPU温度十几分钟就冲到82度以上这时候A76核心会自动降频推理时间从0.8秒左右被拉到1.5秒以上。这个降频完全无提示不看温度监控根本发现不了。车间环境更严酷夏天温度35度是常态防尘盒里面空气不流通如果还用原厂那个小风扇效果只能说勉强够用而且风扇转速上去之后声音不小持续高负荷下滤网堵灰是早晚的事。我最终用了铝制被动散热壳加一颗4020温控风扇。风扇接5V通过一个简单温控模块控制低于55度不转高于60度低速转超过70度全速。实测稳定运行一小时后温度在68到72度之间没有触发降频。如果不想折腾温控直接买那种带调速的铝壳风扇套装也行关键是别让那颗SoC在80度以上连续工作。注意树莓派5的散热片贴法有讲究。SoC和周边供电芯片都在PCB正面别只贴SoC一块。有条件的话买能覆盖到供电区域的大面积散热片供电温度过高同样会限制性能。2.2 供电这件事别省那一根线树莓派5官方要求5V/5A的USB-C电源实际功耗看负载待机大约3瓦出头跑YOLOv5推理时能到9到12瓦。这个功率看起来不大但车间里的电网环境往往很恶劣——旁边有变频器、伺服电机、电磁阀电压跌落和浪涌都是常态。我一开始用的是一块标称5V/3A的普通充电头在车间测试架上跑了半天随机出现多次“欠压提示”和USB相机断连。后来换了5V/5A的工业开关电源直接接USB-C诱骗线供电问题基本消失。原因很简单普通充电头在负载波动时纹波大、稳压慢而工业电源稳压能力和余量都更足。还有两个细节需要注意。第一是USB线材我试过一根细线线阻大同样的电源在树莓派端测到的电压掉了接近0.4V直接触发欠压。换了一根带屏蔽的粗线一切正常。第二是建议加一块不间断电源HAT不一定要UPS那么大容量能撑住几秒钟就行。车间里偶尔会有人误插拔电源线或者总闸跳一下这东西能给你一个优雅关机的窗口省去SD卡文件系统损坏的烦恼。3. 第三件事系统选型Ubuntu还是官方系统3.1 Ubuntu 24.04与树莓派OS的取舍树莓派官方系统Raspberry Pi OS开箱即用硬件支持最完整特别是GPU驱动和摄像头库都预装好了。但车间场景下我最终选了Ubuntu Server 24.04 LTS理由很实际团队对Ubuntu的维护习惯更熟悉跑Docker、配Python环境、装ONNX Runtime时不会有“换了一个发行版”的割裂感而且Ubuntu对树莓派5的支持已经官方化镜像直接下载装完就能用。Raspberry Pi OS也不是不能跑如果你一个人维护那它确实省事。但车间设备多半要交给接班的人用Ubuntu会让后续维护的人少一层认知负担。两条路都能走到终点选Ubuntu纯粹是“哪个顺手用哪个”。镜像从官方渠道下载“Ubuntu Server 24.04 LTS”的树莓派版本我用的是64位ARM版本。烧录用树莓派Imager或者balenaEtcher都行重点在写卡之后的初始设置默认用户、SSH开关、网络配置这些在Raspberry Pi Imager里就能预填省得第一次开机再拿显示器去配。3.2 装完Ubuntu后先检查三项装好系统只是开始直接开工你会被各种小问题卡住。我整理了三项必须做的事第一确认内核和设备树正常。树莓派5需要比较新的内核Ubuntu 24.04默认内核版本可以支持但最好跑一下uname -r确认版本号再检查/boot/firmware/config.txt是否存在。如果文件缺失说明安装时有兼容问题建议更换镜像重写。第二把用户加进必要的组。树莓派5上用串口和GPIO如果不在dialout和gpio组里Python脚本根本没权限打开设备。我吃过一次亏程序在SSH下跑得好好的改成systemd服务后突然报Permission denied排查了半天发现就是用户组问题。第三决定要不要桌面环境。如果是无人值守的车间设备我建议只装Server版不装桌面。省内存、少更新、少一个崩溃源而且排查问题用SSH就够了。如果非要桌面Ubuntu Desktop for Raspberry Pi也行但功耗和复杂度都会增加。4. 第四件事部署自己训练的YOLOv5模型4.1 环境搭建与依赖陷阱模型本身在电脑上训练我是用YOLOv5官方仓库训的自己的数据集最后得到best.pt权重文件。需要说明的是现在很多人已经转向YOLOv8甚至更新的版本但这次客户给的标注格式和部署环境都是围绕v5的所以接着用v5。模型结构是v5s输入640×640检测类别就两类OK和NG。在树莓派5上部署我试过两条路直接跑PyTorch以及导出ONNX后跑ONNX Runtime。如果你的任务非常在意速度直接放弃纯PyTorch方案。树莓派5的CPU算力跑PyTorch的YOLOv5s每次推理接近2秒实在不适合产线节拍。ONNX Runtime下同一模型降到1秒左右再配几个优化手段还能压到0.7秒上下。环境搭建的步骤并不复杂但有几个容易踩坑的地方。建议先建一个虚拟环境我用的是系统自带的venvpython3 -m venv ~/yolo/.venv source ~/yolo/.venv/bin/activate pip install --upgrade pip然后装依赖。onnxruntime在ARM64上有官方轮子直接pip安装即可。opencv-python也是同样。如果要用PyTorch做验证pip install torch torchvision也能装到ARM64版本但体积大不建议在最终运行环境里保留。我在部署机上只留了onnxruntime、opencv-python、numpy和pillow需要的推理库就这几个干净利落。4.2 推理优化从2秒压到0.7秒导出ONNX模型这一步在电脑上完成更稳妥树莓派上直接跑导出脚本会慢且容易内存不足。在训练机上执行python export.py --weights best.pt --include onnx --opset 12导出后把best.onnx文件拷到树莓派上。推理脚本的核心逻辑很简单import onnxruntime as ort import cv2 import numpy as np session ort.InferenceSession(best.onnx, providers[CPUExecutionProvider]) input_name session.get_inputs()[0].name img cv2.imread(sample.jpg) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) resized cv2.resize(img_rgb, (640, 640)) input_tensor resized.astype(np.float32) / 255.0 input_tensor np.transpose(input_tensor, (2, 0, 1))[None, ...] outputs session.run(None, {input_name: input_tensor})就这样直接跑640输入大概1.2到1.5秒。要再压缩时间我实测有效的优化有三招第一固定线程数。ONNX Runtime默认可能调度得不够好显式设置session_options.intra_op_num_threads 4利用率能上来一些。第二把输入尺寸从640降到416或320。车间检测的继电器壳体比较大降到416精度损失不大推理时间能压到0.8秒左右。第三如果目标允许把相机画面里检测区域裁剪得更紧减小预处理开销。实测数据参考不加优化的PyTorch在2秒以上ONNX Runtime默认参数约1.3秒固定4线程加416输入约0.8秒再配合固定的BGR转RGB预处理整体稳定在0.7到0.9秒。对于一秒钟抓两三张图的检测节拍这个性能完全够用。如果将来要更快可以试试NCNN的Vulkan后端树莓派5的VideoCore VII支持Vulkan但我目前没在产线场景实际应用不敢说具体提升多少。注意导出ONNX时最好固定输入尺寸避免动态shape在树莓派CPU上触发不必要的算子优化失败。能用固定640×640或416×416就别用动态维度。4.3 从电脑到树莓派的完整路径把一次模型迭代从训练机搬到树莓派上完整流程应该是标注数据 → 训练得到best.pt → 导出best.onnx → 拷贝到树莓派 → 更新推理脚本中的权重文件路径 → 重新测试几张现场图片 → 确认检测效果 → 重启systemd服务验证自启动正常。我在这个流程里吃过最大的亏是精度校准。训练用的数据是电脑上从现场录制视频抽帧后人工标注的光线条件和车间实际略有差别导致刚部署时误检率偏高。解决办法是拷了几十张现场实际运行画面在电脑上做二次测试完成精度确认后再上机。别跳过这一步不然调试会消耗你大量的时间。5. 第五件事与车间设备的通信衔接5.1 用串口走Modbus RTU对接PLC检测结果如果不发出去那这个视觉检测就只是自娱自乐。我们车间旁边的控制器用的是Modbus RTU协议所以我在树莓派上用串口接了一块RS485收发器然后通过Modbus把结果写进PLC的寄存器。树莓派5默认的串口映射需要先启用在config.txt里确认enable_uart1并把控制台输出从串口上取消否则系统启动日志会干扰通信。接线方面用的是UART的TX/RX接MAX3485的DI/RO再引出A/B线到PLC侧。A/B线要用双绞屏蔽线屏蔽层单端接地否则长距离走线时容易受到车间变频器干扰。Python侧我用pymodbusfrom pymodbus.client import ModbusSerialClient client ModbusSerialClient(methodrtu, port/dev/ttyAMA0, baudrate9600, timeout1) if client.connect(): # 写入保持寄存器0x01011表示合格0表示不合格 client.write_register(0x0101, result_int) client.close()这里最值得注意的不是代码而是系统权限和串口设备名。树莓派5启用串口后设备节点可能是/dev/ttyAMA0或/dev/serial0不同系统版本有差异用ls -l /dev/serial*确认一下。同时运行用户必须在dialout组里否则报错会非常痛苦。5.2 数据上云MQTT推送到监控屏除了PLC那边的实时信号车间办公室还想看统计数据——今天检测了多少件、良率多少、NG件是哪一种缺陷。这个需求用MQTT很顺手。我在树莓派上用paho-mqtt库每推理完一张图就发送一条消息到内网的MQTT broker然后在办公室的监控屏上订阅这些数据做可视化。import paho.mqtt.client as mqtt client mqtt.Client() client.connect(192.168.1.50, 1883, 60) client.publish(line1/vision/result, OK) client.publish(line1/vision/ng_type, dent)车间环境的无线网络非常不稳定金属结构、电机干扰都会导致WiFi信号飘忽。我在串口通信和MQTT通信上都用了有线网络树莓派5自带千兆网口直接插一根网线到车间交换机彻底绕开无线问题。这是第一天上线就吃过的亏WiFi信号满格但丢包率高达10%推理脚本间歇性卡顿。6. 第六件事长期稳定运行的工程化处理6.1 用systemd把推理脚本扛起来调试时可以在SSH里手动跑脚本但上了产线就必须做到开机自启动、崩溃自动拉起、异常退出能留下日志。systemd是最自然的选择。我建了一个服务文件路径在/etc/systemd/system/vision.service[Unit] DescriptionYOLOv5 Vision Inference Afternetwork.target [Service] Userpi WorkingDirectory/home/pi/yolo ExecStart/home/pi/yolo/.venv/bin/python detect.py Restartalways RestartSec5 EnvironmentPYTHONUNBUFFERED1 [Install] WantedBymulti-user.target执行systemctl daemon-reload systemctl enable --now vision以后重启树莓派服务自动拉着推理脚本跑起来。Restartalways会让脚本崩溃后5秒自动拉起这个配置在车间环境里价值巨大——总有一些你没预料到的异常会让脚本退出自启动能让你少跑好几趟车间。6.2 断电保护与SD卡文件系统树莓派5可以用TF卡启动但TF卡在异常断电时容易损坏文件系统。车间里的电不是你想控就能控的所以我做两件事降低风险第一把系统从TF卡迁移到U盘或SSD上。树莓派5支持USB启动把根文件系统放在SSD里耐用性和稳定性比TF卡强一个级别。第二开启系统的overlayfs只读模式让系统分区变成只读推理结果写入内存或者外部存储这样就算断电系统分区也不会因为写入中断而损坏。注意overlayfs模式下写入是临时的如果你需要修改代码或保存日志要把对应目录挂载成可写。我的方案是日志写到内存盘(tmpfs)里定时同步到局域网另一台服务器。这个做法稍微复杂但换来的稳定性很值。6.3 看门狗与日志排查树莓派5的系统里挂着bcm2835_wdt看门狗驱动可以让systemd在系统卡死时自动重启。编辑/etc/systemd/system.conf设置RuntimeWatchdogSec14然后systemctl daemon-reexec。这样哪怕树莓派死机到连SSH都进不去看门狗也能在十几秒内重启系统省去每次人工断电重启。日志方面我建议不要只依赖journalctl。给推理脚本写一个简单的日志文件记录每张图的检测结果、当次推理耗时、CPU温度。好处是排查问题时不用翻系统日志直接看业务日志就能知道是算法误判、硬件卡顿还是电源低压。我的日志每行都带时间戳和温度数据上线第三天就靠它抓到一个“每天下午三点准时空闲”的问题——车间那台空调一启动电压波动导致USB相机偶发掉线。7. 几个避坑心得和收尾小技巧7.1 车间环境里容易被忽略的干扰源除了电源干扰车间还有几个隐蔽的坑。第一是静电防尘盒如果用的是普通塑料壳摩擦起电后可能导致USB相机图像间歇性花屏。我给树莓派外壳接了根接地线问题就消失了。第二是环境光变化YOLOv5对光线敏感流水线旁边如果有人打开遮光帘检测准确率会肉眼可见地下降。我直接在测试架上装了一块遮光罩同时把相机曝光固定成手动模式不再让自动曝光跟着晃。7.2 我个人在实际操作中的体会是如果让我重新来一遍我会先花半天时间把供电、散热、系统这三件基础事情一次做到位而不是像这次一样边跑边补。基础没打好后边所有问题都会往这两个方向关联排查起来特别费劲。另外树莓派5在车间的定位要摆清楚——它是边缘小算力节点不是大模型服务器。把模型压小、把输入尺寸压到够用就好不要追求实验室里的高精度。准确率从99.2%提到99.5%带来的收益远不如在线连续跑一周不出事重要。最后再分享一个小技巧初始调试时别急着把树莓派放进防尘盒。裸板跑两天确认所有功能都稳定了再装箱上线。否则一旦出问题开箱排查的复杂度会成倍增长。这套设备现在已经在车间连续运行了两周多除了例行检查没有需要人工干预的时候。如果你也有树莓派5进车间的打算但愿这篇踩坑记录能帮你少走一段弯路。
返回列表