ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

树莓派5部署YOLOv5视觉检测实战:从Ubuntu到车间的六步落地指南

树莓派5部署YOLOv5视觉检测实战:从Ubuntu到车间的六步落地指南 把树莓派5塞进车间当视觉检测主机这个念头在我脑子里转了大半年。真正动手之后才发现它不光娇气还很折腾——我好不容易在PC上跑通了自己训练的YOLOv5模型转头想部署到树莓派5上却被安装Ubuntu、接摄像头、改推理代码这些看似基础的事连续卡了十几天。整个过程重复踩坑最后归纳出六件事每一件都值得单独开一篇。如果你也打算在产线上用树莓派5做视觉检测、质量判断或者边缘数据采集这篇就算是给你提前踩一遍雷。我的项目很简单用一个CSI摄像头对准装配工位用自己训练的YOLOv5模型识别有没有漏装零件检测结果通过GPIO联动报警灯。听起来不复杂但台上一分钟台下是真的坑坑洼洼。1. 第一件事树莓派5安装Ubuntu开局差点劝退1.1 为什么我从树莓派OS换成Ubuntu很多人买回树莓派第一反应就是刷官方Raspberry Pi OS。但如果目标明确是部署YOLOv5模型我更推荐直接上Ubuntu。原因有三点一是Ubuntu Server无桌面版镜像体积小跑Python推理更清爽二是Ubuntu对工业环境的软件生态兼容更好像ROS、Docker、Mosquitto这些常用服务都有现成deb包三是我个人最在意的树莓派OS的Python环境偏旧YOLOv5拉出来的依赖经常要自己编译而Ubuntu 24.04 LTS自带的Python 3.12配合pip venv能少踩很多兼容性坑。当然树莓派官方OS也不是不能用只是你在网上搜到的很多树莓派5部署YOLOv5的教程都是基于Ubuntu 22.04或者24.04写的抄作业更方便。如果你之前用惯了树莓派OS也不必推翻重来但请至少用64位版本。现在树莓派5的CPU是4核Cortex-A76跑64位系统才能把性能吃满。另一个容易被忽略的问题是Ubuntu Server默认没有桌面环境对只想做检测服务的人来说是优点但对需要经常调试的人来说可能不方便。我的做法是先装Server版后面需要图形界面时再手动装一个轻量桌面这种“按需加料”的方式比一开始就装Desktop更稳。1.2 烧录、启动和电源的真实体验我用的烧录工具是Raspberry Pi Imager镜像选“Other general-purpose OS”里的Ubuntu Server 24.04 LTS。烧录前记得先点开右下角的齿轮图标预配置好WiFi、SSH和用户名密码不然第一次开机没有显示器只能干瞪眼。烧录时间取决于卡的速度一般一两分钟完成。这里有个经验如果你同时插了SD卡和NVMe SSD首次启动会默认从SD卡引导需要手动修改引导顺序Ubuntu 24.04的firmware配置比老版本友好但还是建议烧录前就把配置文件看清楚省得启动后找不到系统盘。启动后最容易出问题的不是系统而是电源。树莓派5的USB-C口支持PD供电官方标称要5V/5A。我第一次用普通手机充电器系统能起来但一接上摄像头和树莓派官方风扇屏幕就出现电压报警图标推理程序动不动就崩。后来换了一个带PD协议输出的电源电压报警直接消失。这里提醒一句不是电流够就完事很多充电器对树莓派5的PD握手不兼容最好用官方电源或者拆机验证过的5V5A电源。如果后面还要挂更多外设建议直接买工业级导轨电源转5V输出从根源上解决电压不稳的问题。存储方面我强烈建议别用SD卡裸跑。树莓派5支持PCIe接口配一张NVMe转接板和转接线就能把系统装在M.2固态上。为什么要这么做后面“长期运行”那节我会细说但一句话先撂在这车间环境里SD卡的损坏率远比你想象的高。加上NVMe之后启动速度和系统的稳健性是质的提升。另外树莓派5的原装散热风扇不接的话夏天跑YOLOv5处理器很容易冲到80摄氏度以上然后降频到1GHz以下推理速度肉眼可见地变慢。所以开机第一件事把散热风扇接上或者至少装一个够大的铝散热片。电源、存储、散热这三件事决定后面所有部署能否顺利进行。2. 第二件事摄像头与图像采集车间光源比YOLOv5更磨人2.1 CSI摄像头选型接口和排线都有坑树莓派5上的CSI接口跟以前的旧型号不一样了是22针的宽度变得更小。手里如果还留着树莓派4时代用的老款IMX219摄像头模块普通排线插不进去必须要买一根22针转15针的转换排线。我一开始没注意这个细节板子到了之后排线怎么都插不紧以为是坏了后来才发现是接口规格换了。选摄像头方面如果拍的是静止或者低速移动的工件普通的Camera Module 3就够了500万像素自动对焦版本在调试时能省不少麻烦。如果流水线速度快需要拍高速运动的物体那就得选全局快门摄像头否则拍出来全是运动模糊。树莓派官方有一款6mm广角全局快门摄像头在车间里很实用缺点是价格贵。采像原理上全局快门一次曝光所有像素和卷帘快门逐行曝光相比不会出现“果冻效应”这对测漏装零件这种任务非常关键。摄像头类型接口适合场景注意点Camera Module 322针CSI静态或慢速工件自动对焦版在调试时更方便官方全局快门摄像头22针CSI高速流水线运动工件价格高但抗运动模糊USB摄像头USB-A快速验证测试延迟高CPU占用高不推荐产线2.2 libcamera与GStreamer绕开OpenCV读摄像头的坑树莓派5跟旧树莓派另一个大的区别是摄像头底层已经全面切换到libcamera框架传统raspistill和raspivid命令已经不存在了。Python里如果用OpenCV的cv2.VideoCapture(0)去读官方CSI摄像头大概率会打开失败或者读到黑屏。正确做法是让OpenCV走GStreamer管道。我用的验证命令是gst-launch-1.0 libcamerasrc ! video/x-raw,width1280,height720,framerate30/1 ! videoconvert ! autovideosink如果只是快速验证图像可直接用libcamera-hello或libcamera-still。但为了后续接入YOLOv5我建议直接用GStreamer的管道把CSI摄像头伪装成一个标准v4l2设备。实际使用中我在Python里这么写cap cv2.VideoCapture( libcamerasrc ! video/x-raw,width640,height480,framerate15/1 ! videoconvert ! video/x-raw,formatBGR ! appsink drop1 )注意appsink后面的drop1这个参数很关键。当推理速度跟不上采集速度时OpenCV会自然丢弃旧帧保证读到的永远是最新一帧避免队列越积越多导致延迟越来越大。如果你只是做单张图片检测也可以直接走libcamera-still --output但要额外处理子进程调用不如GStreamer管道灵活。2.3 车间光照和曝光参数调整实战车间环境最难受的是光源不固定白天有窗户光、晚上有高频灯工件表面还会有反光。YOLOv5模型训练时拍的照片可能是均匀光照一到现场就各种过曝欠曝检测率直线下降。我的处理办法是先用libcamera-still连续拍几十张把曝光时间和增益范围确定下来。如果现场光线基本固定可以固定曝光参数不让自动曝光来回跳libcamera-hello --set exposure_time 20000 --set gain 1.5在Python代码里也可以借用libcamera的controls设置曝光。这里要特别提醒自动曝光在视觉算法里常常是敌人因为检测算法期望输入图像的统计分布稳定。固定曝光、固定白平衡甚至固定对焦距离能显著减少误检。我后来还在镜头前加了一块偏振片专门压反光效果立竿见影——车间金属工件表面的高光区不再把检测框带偏。3. 第三件事自训练的YOLOv5模型部署最大的坎在模型转换3.1 先在PC上把模型导出成ONNX训练YOLOv5的过程就不展开说了网上教程一抓一大把。重点是从best.pt到能跑在树莓派5上的推理格式。我这里选择的是ONNX原因很简单ONNX Runtime在ARM64上有官方wheel包而且针对CPU做了线程级优化PyTorch直接在树莓派上跑不但包体积大推理速度也慢。导出命令是在PC上完成的YOLOv5官方仓库自带export.pypython export.py --weights best.pt --include onnx --simplify --opset 12如果你的模型类别数不是默认的80也不用担心导出时会自动带上训练时的nc参数。导出完成后会得到一个best.onnx可以用Netron打开检查计算图确认最后一个输出层的维度是不是[1, 25200, 5nc]。25200来自640分辨率下三个尺度特征图的总和80×80、40×40、20×20每个网格还有三个anchor所以8400×325200。如果你导出时指定了更小的imgsz比如320那么三个特征图是40×40、20×20、10×10输出就会变成6300个候选框推理压力小很多。3.2 树莓派5上的Python推理环境搭建在树莓派5上创建一个干净的虚拟环境这是吃了太多次系统Python环境被搞烂的教训。直接在系统全局pip install很容易跟Ubuntu自带的包冲突而且后面换模型、换依赖版本时会很痛苦。我习惯把项目隔离在venv里python3 -m venv ~/venv/yolov5 source ~/venv/yolov5/bin/activate pip install --upgrade pip pip install onnxruntime opencv-python-headless numpyopencv-python-headless比opencv-python更适合服务器场景少带GUI依赖。如果你的Ubuntu还没装系统基础包可能还要装libglib2.0-0。onnxruntime建议装最新版至少是1.16以上旧版本在Python 3.12上可能没有对应wheel。装好之后可以先用一行命令验证ONNX Runtime能不能正常加载模型python -c import onnxruntime as ort; sort.InferenceSession(best.onnx,providers[CPUExecutionProvider]); print(s.get_inputs()[0].shape)如果输出的是[N,3,640,640]之类的维度环境就通了。如果报错最常见的原因是onnxruntime装成了x86版本或者在树莓派5的ARM64系统上pip拉到了一个老的wheel。这时候强制卸掉重装最新版基本能解决。3.3 ONNX推理与后处理代码照着抄就行官方YOLOv5仓库里的detect.py也能在树莓派上跑但那些代码里包含很多跟推理无关的配置速度也不够极致。我这里把最核心的推理逻辑提炼出来import cv2 import numpy as np import onnxruntime as ort class Detector: def __init__(self, onnx_path, conf_thres0.25, iou_thres0.45): self.session ort.InferenceSession(onnx_path, providers[CPUExecutionProvider]) self.conf_thres conf_thres self.iou_thres iou_thres self.input_name self.session.get_inputs()[0].name self.input_shape self.session.get_inputs()[0].shape self.out_names [o.name for o in self.session.get_outputs()] def letterbox(self, img, new_size(640, 640)): h, w img.shape[:2] r min(new_size[0] / h, new_size[1] / w) nw, nh int(round(w * r)), int(round(h * r)) img_resized cv2.resize(img, (nw, nh), interpolationcv2.INTER_LINEAR) canvas np.full((new_size[0], new_size[1], 3), 114, dtypenp.uint8) top (new_size[0] - nh) // 2 left (new_size[1] - nw) // 2 canvas[top:topnh, left:leftnw] img_resized return canvas, r, left, top def detect(self, img): canvas, r, left, top self.letterbox(img, (640, 640)) blob canvas[:, :, ::-1].transpose(2, 0, 1)[None].astype(np.float32) / 255.0 out self.session.run(self.out_names, {self.input_name: blob})[0][0] xc out[:, 4] self.conf_thres boxes out[xc] results [] if len(boxes) 0: return [] for *xyxy, conf, cls in boxes: if conf self.conf_thres: continue x1, y1, x2, y2 (xyxy - np.array([left, top, left, top])) / r results.append([x1, y1, x2, y2, conf, cls]) if not results: return [] results np.array(results) indices cv2.dnn.NMSBoxes(results[:, :4].tolist(), results[:, 4].tolist(), score_thresholdself.conf_thres, nms_thresholdself.iou_thres) if len(indices) 0: return [] return results[np.array(indices).flatten()]实际使用的时候还需要注意输入图像最好是BGR顺序letterbox后的图像要转成RGB、归一化到0到1、变成NCHW格式再放进session.run。这一步是新手最容易漏的地方漏了之后推理结果全部乱套。我自己第一次跑的时候忘了除以255出来的检测框置信度全部异常排查了大半天。后处理里的NMS我更推荐用cv2.dnn.NMSBoxes因为OpenCV里的实现是C写的比纯Python循环快很多。如果类别数量多建议把NMS逻辑改成numpy并行版本。不过对咱们这种小项目来说cv2版已经足够。4. 第四件事算力不够怎么把YOLOv5的速度抠出来4.1 模型尺寸与分辨率先砍一刀树莓派5没有独立NPU所有计算都靠4颗A76核心。因此最直接的优化就是先把输入分辨率从640降到416或者320。检测目标如果只是“有没有漏装零件”320分辨率足够了降分辨率带来的是计算量平方级下降FPS提升非常明显。我在测试中把640降到320后推理时间大约能缩短一半还多。当然分辨率不是越低越好降太狠小零件会直接糊掉需要拿你的实际数据集做对比。模型本身也别贪大。YOLOv5s是性价比最优选YOLOv5m和YOLOv5l在树莓派上跑起来非常痛苦。我自己试过YOLOv5s和YOLOv5n工件特征比较小的情况下yolov5n会漏检s基本够用。另外可以尝试把模型量化成FP16ONNX Runtime在CPU上对FP16不一定比FP32快但部分情况下能减少内存占用这个需要实测不要盲目相信教程。剪枝蒸馏那种高阶玩法对小项目来说投入产出比不高除非你整个团队都有做算法优化的经验。4.2 推理管线和线程优化很多人在树莓派上写代码还是PC时代的思维单线程循环里一边读摄像头一边做推理。在树莓派上这么干读帧和推理互相抢CPU帧率很难看。正确做法是拆成两个进程或至少两个线程主线程负责取帧把最新一帧丢进队列推理线程永远只处理队列里最新的帧如果推理跟不上宁可丢帧也不阻塞采集。把采集的GStreamer管道写成cap cv2.VideoCapture(libcamerasrc ! video/x-raw,width640,height480,framerate15/1 ! videoconvert ! video/x-raw,formatBGR ! appsink drop1)然后用queue.Queue(maxsize1)来保证最新帧。之所以maxsize设为1是为了避免积压几十帧后推理滞后实时性反而更差。如果系统还有多余CPU建议用multiprocessing替代多线程。Python的GIL对onnxruntime影响比较小但OpenCV的读帧和预处理受GIL影响明显多进程可以同时跑采集、预处理、推理三件事。4.3 树莓派5的定位不是每个检测都要24帧我也踩过“一定要跑到30FPS”的执念。但回到车间场景检测漏装零件通常只需要几秒一拍检测完再配合复检或停机根本不需要连续视频流。所以最终我把推理输入分辨率定为416单帧推理时间稳定在1秒以内整个系统足够用。启停时间和告警联动都基于这个节奏来配反而比追求高帧率更稳。如果你确实需要高帧率树莓派5的CPU就力不从心了。我建议把树莓派5用在低功耗、低成本、算力需求不高的边侧场景需要高帧率连续检测时直接上带NPU或者GPU的边缘设备更省心。树莓派5的价值在于功耗低、体积小、方便改造旧设备而不是跟专业工控机拼算力。搞明白定位之后你才不会陷入无休止的调参焦虑。5. 第五件事车间长期运行供电、散热和死机恢复缺一不可5.1 电源和散热别让设备死在夏天车间环境最现实的问题是电压不稳。普通家用电源在车间里会受到大型设备启停影响瞬间跌落会让树莓派重启。所以建议不要直接插墙插而是用一个工业级开关电源转5V或者至少一个带过压保护的适配器。我买过一个号称5V5A的杂牌电源带载能力不足树莓派5高负载运行半小时后就开始缓存报警后来换成有3C认证的电源才稳定。温度方面树莓派5的高性能核心发热量不小。如果机器放在不通风的控制柜里夏天环境温度35度时树莓派核心能冲到85度。温度一高系统会自动降频推理速度变得极其不稳定。我的方案是主动散热风扇加散热片机柜侧板开孔装一个温控风扇树莓派侧设置一个systemd定时任务超过70度就把风扇开到全速。定期清理风扇灰尘也很关键车间粉尘多两个月不清风扇就变成积灰陀螺散热效率大打折扣。5.2 开机自启、看门狗和掉电后的惨痛教训检测程序如果还要人工去开机点一下那就不叫进车间。我写了一个systemd服务开机自动启动Python脚本并加了Restartalways让进程在崩溃或异常退出后自动拉起来。服务文件大致如下[Unit] DescriptionYOLOv5 Detection Service Afternetwork.target [Service] Userpi WorkingDirectory/home/pi/detect ExecStart/home/pi/venv/yolov5/bin/python /home/pi/detect/run.py Restartalways RestartSec3 [Install] WantedBymulti-user.target这个服务的价值在于崩溃自动恢复但如果整个系统死机、硬件看门狗触发不了程序还是可能停摆。所以我再加了系统层watchdog在/boot/firmware/config.txt里启用bcm2712 watchdog然后配置systemd的RuntimeWatchdogSec和ShutdownWatchdogSec保证树莓派5死机后能自动断电重启。这里注意不同内核配置项名称树莓派5上最常见的是bcm2712_wdt。掉电这个问题我再三强调别用SD卡裸跑。我有一次车间意外断电再上电后SD卡文件系统损坏连ext4都挂载不了。后来换成NVMe SSD加上开机自动fsck断电后再启动基本没有丢过系统。5.3 存储保护SD卡不是车间的“存尸柜”只要条件允许系统盘一定放在NVMe SSD上。树莓派5的PCIe 2.0带宽虽然不算高但跑一个视觉服务绰绰有余。SSD没有SD卡那种猝死式损坏连续读写寿命也高得多。开销大概就是一块M.2转接板加一块二手固态的钱对比产线停机的损失完全可以接受。如果实在要用SD卡还有个办法是开启overlayfs把系统分区设为只读日志和检测结果写到内存盘或者U盘。这样SD卡基本不会在读面上出问题但代价是每次配置重启后不保留适合那种“配置好后不再动”的稳定场景。我经历过一次SD卡“读卡器写坏”之后对这种做法特别推荐。另外无论哪种存储建议都要定期备份模型和关键配置文件哪怕只是打包丢到另一台机器上也比出问题后重配全部环境省事得多。6. 第六件事让树莓派5真正进产线不能只跑一个算法脚本6.1 外围设备与GPIO/串口对接视觉检测最终要跟产线交互不能只在屏幕上画框。最简单的联动方式是GPIO检测到缺陷时拉高一个GPIO引脚触发继电器给报警灯供电或者给PLC一个24V信号。这里要注意树莓派GPIO是3.3V电平不能直接接24V系统一定要经过光耦或者继电器模块隔离。我一开始直接用杜邦线接继电器模块结果现场有电磁干扰误触发了几次后来换成光耦隔离模块才好。如果设备支持Modbus RTU可以用USB转485模块通过pyserial按照Modbus协议读写寄存器。我从PLC手册里摸了一下午最后用modbus-tk把检测结果写入保持寄存器。这里要提前规划好寄存器地址和字节序别等到了现场再翻手册。车间里还有种常见需求是声光报警用继电器控制即可。需要接多个输出时建议用I2C扩展GPIO或者用串口控制小型继电器板别一根根杜邦线乱接。6.2 检测数据上报与产线看板检测结果不能只存在本地SD卡里。我用了一个非常简单的方式脚本每完成一次检测就把带框图片保存到本地目录同时把统计结果通过MQTT发布到产线看板。MQTT的好处是即使看板偶尔断线消息也能通过broker缓存重新上线后补发。上报代码逻辑大约是这样import paho.mqtt.client as mqtt client mqtt.Client() client.connect(192.168.1.50, 1883) client.publish(line1/vision/result, f{ok_count} {ng_count})如果厂里已有MES系统也可以把结果从MQTT转发到数据库。关键是把检测结果结构化是OK还是NG、缺陷类型、置信度、时间戳这些字段一定要提前定义好不然报表写一半要改结构很痛苦。我这里把图片命名规则设成了“日期_时间_结果_置信度.jpg”后面追溯异常工件时非常方便。日志也不能只存在树莓派本地最好定时同步到文件服务器至少保留三个月方便质量部门复盘。6.3 运维视角模型更新与远程管理模型上线后发现误判率高肯定要迭代。树莓派5上不能每次重新训练都跑过去插电脑我把模型放在固定目录训练完通过scp上传再用软链接切换版本。脚本里每次启动时读取模型文件这样只要更新软链接并重启服务就能完成模型升级。我还会在服务里加一个模型时间戳检查如果模型文件发生变化就自动重启推理流程省去手动操作。远程管理方面我采取的策略很简单在树莓派上配置固定IP厂内局域网随时可以SSH登录需要跨网段访问时通过已有IT规划的跳板机走正规通道。直接用远程桌面做图形界面调试也行但生产环境我尽量不开图形服务省内存也少暴露攻击面。每次远程改完代码先用日志确认没过热、没爆内存再离开。这习惯帮我避开了好几次“远程改完第二天才发现服务没起来”的尴尬。六件事走下来树莓派5已经从桌面的玩具变成了车间角落里一个不太起眼的铁盒子。我个人最大的体会是它的算力不算强但足够解决很多实际检测问题尤其是在成本敏感、空间有限的老设备改造中优势很明显。如果你想把它搬进产线别急着追求模型效果先把系统、摄像头、模型转换、稳定运行这六件事踏踏实实做好八成也能顺利落地。最后再多说一句所有的坑都不会白踩下一次再看到树莓派你会先看一眼电源和散热。
返回列表