我做了 5 年机器视觉,才看懂设备软件是怎么长出来的
工业视觉上位机从 0 到 1开篇一张全景图 一条 12 篇的落地路线从会用算法走到能交付一台视觉设备【产线真相】算法识别率 99%设备三天一台没出货先说个真事。去年一个朋友找我救火。他们公司买了一台自动视觉检测设备算法是一家高校团队做的 Demo——在实验室里识别率 99%老板看完当场拍板。装到产线上三天一台产品没正常放行。我去现场待了半天发现问题根本不在算法相机偶尔丢一帧nullptr直接把程序打崩得重启检测结果要发给 PLC通信线程和界面抢资源操作员点一下按钮界面就假死十秒判了 NG客户要查是哪一批、哪张图结果系统什么都没存想调一个阈值得改代码、重新编译、重新发布产线停机等半天。算法没问题。是**设备软件这一层根本没做**。那一刻我特别理解一件事会写检测算法的人很多能把算法变成一台能在车间跑一个月不出事的设备软件的人很少。而这正是这个系列要解决的事。你缺的从来不是算法是把算法装进设备里的那层壳先给结论——一台工业视觉设备软件由 8 个模块组成算法只是其中一个工业视觉设备软件上位机 ┌─────────────────────────────────────────────────────────────┐ │ │ │ ⑥ 交互 UI ⑦ 追溯 ⑧ 部署/稳定性 │ │ ROI/结果/参数 存图/记录/查询 打包/日志/自恢复 │ │ ▲ ▲ ▲ │ │ │ │ │ │ │ ① 采集 ──► ② 处理 ──► ③ 算法 ──► ④ 判定 ──► ⑤ 通信 │ │ 相机取流 去噪/增强 检测(可插拔) Pass/Fail PLC/控制卡 │ │ │ └─────────────────────────────────────────────────────────────┘大多数机器视觉简历上写的是中间的③ 算法。而真正决定项目能不能上线的是它在①采集、②处理、④判定、⑤通信、⑥UI、⑦追溯、⑧部署里的表现。一张表看清差距我拿了一份真实的机器视觉工程师招聘 JD把它拆成两边JD 里说的只会算法的人会做设备软件的人“负责视觉方案设计”会选模型、调参会算节拍、选相机镜头光源“对接 PLC / 运动控制”没碰过通信Modbus-TCP / 串口 / IO 触发“保证设备稳定运行”实验室能跑就行断线重连、异常恢复、跑一个月不崩“数据可追溯”只输出结果存图、存记录、能倒查“现场调试与交付”没到过车间会打包、会排现场故障你如果只会左边那一列面试官一句你独立交付过完整设备吗就聊不下去了。这个系列就是帮你把右半边补上。VisionStation我们这个系列要亲手做出来的东西系列里我们从头搭一台工业视觉上位机我给它起名VisionStation。它不是玩具也不是把某个开源框架拆开讲一遍。它是一条完整的、工业上真会遇到的链路相机取流 ─► 图像预处理 ─► 可插拔检测算法 ─► Pass/Fail 判定 │ ┌─────────────────────┼─────────────────────┐ ▼ ▼ ▼ 发给 PLC 结果可视化 存图与追溯 联上设备 操作员看得懂 出问题能查搭完之后你会有一个能编译、能取流、能联设备、能出结论、能追溯、能打包的最小可用设备软件。它不炫但它是真的。12 篇的路线图单篇也能独立读但连起来是一条完整的成长线篇你会拿到什么1就是本篇看懂设备软件长什么样2一份能扩展的 Qt CMake 分层工程骨架3稳定拿到工业相机的每一帧4一条产线上真用得上的图像预处理链5把检测算法做成可插拔插件6让上位机联上 PLC / 运动控制卡6把算法结果翻译成产线要的 Pass/Fail7数据与图像可追溯8一个操作员敢用的界面ROI 结果可视化9采集/处理/UI 三线程解耦跑几小时不卡10打包、部署到车间电脑11部署与稳定性在自己电脑能跑到车间不崩12全系列复盘 工业视觉开发者的进阶路线具体顺序以最终发布为准每篇都能独立看懂不用回头补前面的。【能跑起来的最小实现】一分钟看清全链路认知的东西说再多不如看一眼骨架。下面是 VisionStation 主干逻辑的最小骨架——它还不能真跑但能把一台设备软件到底在干什么一次说清// 一台视觉设备软件的骨架一屏看清全链路intmain(intargc,char**argv){QApplicationapp(argc,argv);FrameSource source;// ① 采集相机 / 离线图Preprocessor prep;// ② 处理ROI、去噪、增强IDetectPlugin*algo...;// ③ 算法可插拔的检测插件Judger judge;// ④ 判定OK / NG 分级PlcClient plc;// ⑤ 通信把结果告诉 PLCMainWindow ui;// ⑥ 交互给操作员看Tracer tracer;// ⑦ 追溯存图、存记录QObject::connect(source,FrameSource::frameReady,[](constFramef){Frame cleanprep.run(f);// 处理Result resultalgo-detect(clean);// 检测Verdict vjudge.decide(result);// 判定plc.send(v);// 通信通知设备tracer.log(f,result,v);// 追溯留证据ui.show(f,result);// 交互给人看});source.start();// 开始取流returnapp.exec();}就这么二十几行但它就是一台视觉设备软件的心脏。接下来的 12 篇我们做的所有事都是把上面这几个占位符一个一个换成真正能在产线上跑的实现FrameSource→ 第 3 篇工业相机采集与帧管理Preprocessor→ 第 4 篇产线级图像处理链IDetectPlugin→ 第 5 篇把算法做成即插即用的插件Judger→ 第 7 篇把算法输出翻译成产线语言PlcClient→ 第 6 篇和 PLC / 控制卡稳定通信Tracer→ 第 8 篇数据与图像追溯MainWindow→ 第 9 篇操作员敢用的界面而让这一切不卡、不崩、能交付的 → 第 2、10、11 篇。建议你先把这个骨架结构记在脑子里——以后每读一篇都回来看看它在骨架里的哪个位置。【能跑起来的最小实现】一个 5 分钟能跑的第一版如果你手痒先给一个今晚就能跑起来的最小版本“读一张图 → 显示它”这就是 VisionStation 的第一块砖。// main.cpp —— VisionStation 的最小起点Qt Widgets#includeQApplication#includeQLabel#includeQPixmapintmain(intargc,char**argv){QApplicationapp(argc,argv);QLabel view;QPixmappix(test.jpg);// 先用一张本地图代替相机if(pix.isNull()){qWarning(图片没读到检查路径);return1;}view.setPixmap(pix);view.setWindowTitle(VisionStation v0);view.resize(pix.size());view.show();returnapp.exec();}对应 CMake第 2 篇会展开这里先跑通# CMakeLists.txt cmake_minimum_required(VERSION 3.16) project(VisionStation LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_AUTOMOC ON) find_package(Qt6 COMPONENTS Widgets REQUIRED) add_executable(visionstation main.cpp) target_link_libraries(visionstation PRIVATE Qt6::Widgets)cmake-Bbuild cmake--buildbuild--configRelease跑起来你会看到一张图。它离设备软件还很远但它已经站在了起跑线上——下一步就是把读一张固定的图换成从相机稳定地拿每帧图把一个 main 文件换成一套分层的工程。这正是第 2、3 篇的事。【避坑指南】坑1以为会调 OpenCV就等于会做设备软件现象算法 Demo 很漂亮一上产线全崩。原因设备软件的难点 80% 在算法之外采集、通信、稳定性、追溯、部署。正解把这个系列当工程课来读别只盯算法。坑2一上来就去啃成熟框架的源码。现象打开一个大项目的几十个模块一脸懵劝退。原因你还没有自己从 0 搭一遍的直接经验看什么都是散的。正解跟着这个系列先搭一个最小闭环再回头看框架你会突然看懂它为什么那样设计。坑3把能跑当成能交付。现象自己电脑上完美车间电脑双击没反应。原因部署、依赖、配置、稳定性是独立的一摊事。正解从第 2 篇起就有这是要交付到车间的意识外置配置、日志、打包。下一篇先把工程的地基打好下一篇我们干一件很实在的事用 Qt CMake 搭出 VisionStation 的工程骨架——分层、单向依赖、能扩展。为什么底层不能引用上层、为什么.ui和算法要分家、为什么一个小项目也要认真分层。在那之前我想先听你一句你现在的项目是算法能跑就结束了还是设备能在车间跑一个月才算完你在这两个之间卡在哪一步评论区聊聊这决定了后面 12 篇我该重点讲哪里。