搞机器视觉这些年,有个现象一直挺有意思:很多人算法、硬件都能聊得头头是道,可一落到“把相机、光源、PLC、上位机串成一条能跑的产线”这事上,第一反应就是LabVIEW。我最早接手的视觉项目就是用LabVIEW配合NI Vision搭的一条小尺寸零件检测线,后来陆续在光源选型、GigE相机配置、Modbus握手、帧率匹配这些环节里踩了不少坑,有些教训到现在写代码还会刻意避开。
这篇就把LabVIEW机器视觉从环境准备到项目落地的常见路径拆开讲一遍。适合三种人看:刚入行想摸清视觉开发到底做什么的新手、写上位机想往视觉方向扩的工控程序员、以及被项目逼着用LabVIEW接手视觉系统的朋友。文章不会只堆概念,会尽量把每个环节“为什么这么做”和“现场容易死在哪儿”说清楚,方便你直接照着搭一套能跑的原型。
1. 先搞明白:LabVIEW机器视觉项目里,你到底在做什么
1.1 视觉工程师日常处理的四类事
先说个容易被误解的点。所谓“LabVIEW机器视觉开发工程师”,不是天天在调图像算法,更多时候是在处理工程问题。我归纳下来,日常主要就四类:
第一类是图像方案验证。拿到一个待检测的零件,先要确定用什么光源、什么相机、什么镜头,能不能稳定拍到特征。这步直接决定后面算法的难易。第二类是上位机逻辑。视觉系统不是独立存在的,它要把检测结果发给PLC、机械手或者数据库,同时接收触发信号。这部分在LabVIEW里占的代码量往往比图像处理还大。第三类是现场标定和维护。换了一个相机、挪了一下安装位置,坐标标定就要重做,曝光参数也要跟着调。第四类才是算法实现,比如定位、测量、缺陷识别,这些在NI的视觉函数库里多数有现成模块,反而是最不容易“卡死”的部分。
理解了这一点,就不会一上来就钻图像处理的牛角尖。很多项目做砸,不是算法不行,是前面三步没做好。
1.2 NI视觉三件套:LabVIEW、VDM和VBAI怎么分工
NI的视觉生态里,普通人最容易混淆的是三样东西:LabVIEW本身、Vision Development Module(VDM)和Vision Builder for AI(VBAI)。
LabVIEW是图形化编程环境,是我们的“主战场”,负责流程控制、数据交互、界面显示。VDM是视觉函数库,装好之后会在LabVIEW函数面板里多出一整套图像处理VI,包括采集、滤波、找边、粒子分析、模板匹配等,它才是真正干图像处理的模块。VBAI则是一个独立的快速原型工具,不需要写代码,用拖拽的方式配置检测流程,适合做方案验证和小批量产线。
我再补充一点经验:VBAI虽然叫“快速原型”,但它生成的检测脚本可以直接导出成LabVIEW代码调用。很多项目我会先用VBAI验证流程,等方案稳定了再导到LabVIEW里做二次开发,速度比直接在LabVIEW里折腾快很多。如果检测逻辑不复杂,甚至可以在产线上直接跑VBAI的运行时界面,工程师用触摸屏就能改参数,日常维护成本很低。
1.3 选VBAI还是选VDM,我给个实际建议
不少新手会纠结“要不要学VBAI”,我的判断标准很简单:如果项目方案比较固定、流程不绕弯,用VBAI搭建后让现场人员自己微调,是最稳的;如果要做复杂的多工位协作、跟自定义硬件的交互比较多,就得用VDM把视觉模块嵌到自己的主程序里。
VDM提供了一套比较完整的图像处理函数,但它的复杂度确实比VBAI高。比如Image文件或图像的缓存管理、内存释放、不同图像类型转换,这些在VBAI里系统全帮你处理了,而在VDM里要自己注意。
所以,如果你想少走弯路,可以两条腿走路:VBAI做方案预研,VDM做正式程序。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从安装到能跑图:先铺一条顺畅的开发链路
2.1 软件版本选择的几个原则
很多人一上来就问“LabVIEW最新版号是多少”之类的问题。我心里默认标准是:NI的软件按版本严格对齐,能用同一年的版本尽量同一年的。比如计算机上装了LabVIEW 2017,VDM版本年份最好也是2017,驱动也要配2017对应的版本,不然就会出现函数面板里找不到函数、报错提示“VI版本过高”之类的奇怪问题。
LabVIEW 2018在业内用得依然很多,主要因为性能和兼容性平衡不错。如果你要用的相机SDK、PLC通讯库只有老版本支持,就不要盲目装新版,项目稳定优先,工具求新求变只会给自己添麻烦。
还有一个很多人容易忽略的地方:安装路径不要有中文和特殊字符,装完以后能不动就不动。NI软件生态跟Windows底层注册表耦合很深,我见过有的同事手欠去挪安装位置,结果整个工程编译报错,最后只能重装系统,这属于纯血泪教训。
2.2 安装遇到的坑和排查思路
安装这块有两个高频问题。
一个是安装包下载或者安装到一半提示错误,最后一步回滚。多数是网络代理、杀毒软件拦截、系统环境变量被改过导致。解决思路有一个可以先试:右键用管理员身份运行NI Package Manager,安装前暂时退出第三方杀毒和防火墙软件,一般能绕过一半问题。还有一部分情况是之前卸载NI套件没卸干净,上一条代码在残留注册表,这时候需要用NI官方提供的清理工具把残件清一遍,再重试。
另一个是装完后LabVIEW启动报“运行时错误”或者找不到许可证。常见的原因是NI License Manager里面没有激活对应的模块,或者安装时没有选择完整功能包。建议在安装组件选择界面,把Vision Development Module、IMAQdx驱动、VBAI全部勾上,免得后面要用的时候又得单独补。
2.3 操作系统兼容性
有的朋友问“银河麒麟系统或者Linux能不能跑LabVIEW”。NI官方历史上对于跨平台支持,主要是Windows和部分Linux版本,但很多设备厂商驱动并不一定支持Linux,相机驱动、采集卡驱动都会成为拦路虎。因此,如果你是在国产化环境做工业视觉,最靠谱的思路不是在Linux里硬跑LabVIEW,而是把视觉核心放到Windows工控机里,再通过标准通讯协议把结果交给国产化系统上位机做界面展示和逻辑调度。前期花费的改造时间少,也稳妥。
2.4 图像浏览器和调试工具别忽略
有一类实用工具容易被忽略,而这恰恰能帮你省一半调试时间,就是NI自带的IMAQ Image Browser(图像浏览器)和Vision Assistant。
我的用法是:在代码的关键步骤里,把当前帧图像临时保存成PNG或者用Image Browser打开,离线查看中间结果。比如在阈值分割之前、灰度转换之后各存一张图,就能快速判断是“采集没采好”还是“阈值参数不对”。Vision Assistant里也自带图像记录功能,可以把每次参数修改前后的效果并列对比,当你需要调一套坏品缺陷阈值时,这个功能特别重要。
有几次现场反馈“检测不稳定”,我看保存的中间图像就发现是镜头上有水雾,根本不是算法问题。如果只盯着代码,大概会多折腾一天。
3. 搭一套能落地的视觉检测方案:光源、相机和图像处理链路
3.1 选型顺序:光源优先,算法靠后
这是我在项目中排序最坚定的一条经验。同样的算法和相机,换一种光源效果可能是天壤之别。很多团队项目做砸,不是算法选型差,而是图省事当天花板下装了一颗普通LED环光就开始调程序,结果特征反差不出来,后面怎么调阈值都白搭。
光源的类型选择,我常用的判断逻辑整理成一张表:
| 光源类型 | 常见效果 | 典型适用场景 |
|---|---|---|
| 环形光源 | 从镜头四周平行打光,突出表面细节 | PCB字符、金属表面划痕 |
| 条形光源 | 大范围斜照,强化边缘与凹凸 | 大面积面板、外壳轮廓 |
| 背光源 | 从被测物背后均匀透射,形成高反差轮廓 | 尺寸测量、引脚共面度、缺口检测 |
| 同轴光源 | 光线经半反半透镜垂直照射,消除反光 | 高反光表面、晶圆mark点定位 |
| 球积分光源 | 多角度均匀漫反射,消除阴影和反光干扰 | 曲面、反光件的整体外观检测 |
记住一个基础原则:检测特征靠的是目标和背景之间的灰度差。如果灰度差够大,后面随便一个二值化都能稳定处理;如果灰度差不够,就算上了深度学习也很难救回来。这就像拍文件照片,晚上开台灯直射纸面,无论相机多好都白搭。
调试时一般先看灰度直方图,如果目标区域和背景区域的峰值能分开,就是比较理想的打光状态。如果没有分开,优先调光源角度、高度和亮度,而不是急着调算法参数。
3.2 相机连接与图像采集的LabVIEW实现
工业相机在LabVIEW里的接入方式,主流是GigE Vision或者USB3 Vision。GigE由于传输距离长、稳定性好,在产线里用得最多。用LabVIEW采集GigE相机图像的经典流程大概这样:
先要安装设备商提供的驱动或者NI IMAQdx驱动。如果相机是海康、大恒这类国产品牌,官方一般会提供自己的LabVIEW例子和SDK,建议优先用官方驱动,因为IMAQdx对非NI品牌相机的支持有时不够完整。在开始编程前,先把相机、网卡IP和设备IP设在同一个网段,然后用NI Max或者相机的配置工具确认能正常打开图像,这一步不通过的话后面代码写再多也没用。
采集代码的核心步骤可以拆成:
- IMAQdx Open,打开指定相机,拿到会话句柄。
- IMAQdx Configure Grab或Start Acquisition,启动连续采集。
- IMAQdx Grab,从缓存区取一副最新图像到LabVIEW图像缓冲。
- 对图像做处理或显示。
- 停止采集并关闭相机。
这里最需要提醒的是:图像处理之间要使用同一个Image Buffer。第一次处理完直接覆盖当前图像,会丢掉原始帧,但很多检测需要原始图做备份。所以建议创建两个Image:一个存“原始采集图”,一个存“处理用图”。后续不管怎么滤波、分割,都不要动原始图。需要复看时原始图随时可以拿出来。
3.3 一个最常规的定位任务:螺丝孔圆心定位
举一个代表性的项目,在手机中框上定位螺丝孔中心,然后引导机械手把螺丝拧进去。这类“定位+引导”功能是机器视觉里最典型也最容易上手的场景。
第一步,采集一帧干净图像,用灰度转换函数把彩色图转成灰度。若背景反光较强,可以考虑光源类型或加偏振片。
第二步,用阈值分割把螺丝孔从背景里分离出来。由于螺丝孔区域通常比周围暗,阈值范围会设在较低灰度段。阈值设定时不要只盯单帧,要连续取十几帧图像看波动范围,然后在最差情况下还有余量,才算是一个稳定参数。
第三步,用粒子分析或者形状匹配找到目标区域的中心坐标。这个位置是像素级坐标,单位是“像素”。如果要给机械手用,还需要换算成机械坐标。
换算方式分为两种:如果产品位置和相机位置完全固定,可以通过单次标定计算出像素当量,也就是每毫米多少像素,然后把像素偏差换算成毫米偏移。如果机械手可能需要移动或者相机视野会变,就要做九点标定,机械手依次走到九个标定位置,相机记录像素坐标,构建像素坐标到机械坐标的映射关系。
现场最容易翻车的是没有考虑产品来料角度有轻微旋转。如果每个产品只做平移匹配,不修正角度,机械手抓住的位置就会有偏差。所以做定位项目时,除了中心坐标,还要同时输出角度值,实际偏置就是中心坐标的偏移加上孔位相对于基准点的旋转补偿。
3.4 视觉结果给PLC:串口和Modbus的常见玩法
视觉系统把结果算出来之后,下一步就是跟PLC握手。这里点名一个非常常见的“新人翻车点”:视觉软件已经把结果写到了界面上,但PLC那边一直收不到,于是两边开始互相扯皮。
根本原因大多数是通讯格式或时序没对齐。LabVIEW里做PLC通讯最常见的两种方式:用VISA做串口,执行Modbus RTU协议;或用TCP/IP自定义报文,对接支持Modbus TCP的PLC。
Modbus RTU在这种场景下很常见。数据帧结构不复杂:从站地址、功能码、寄存器地址、数据区、CRC校验。比如读取PLC里的某个启动信号,写入的报文格式大致是“设备地址+功能码03+起始寄存器地址+读取寄存器数量+CRC校验”。LabVIEW里可以用VISA写入把报文发出去,再用VISA读取返回的字节,最后解析出寄存器的值。
调试小技巧是:先用串口助手手动发一帧报文确认PLC能返回正确数据,再回过来查LabVIEW里的字节序和CRC计算。CRC算错是高发问题。比如CRC低字节在前还是高字节在前,不同设备要求不一样,我曾在这上面卡了半天,后来对着PLC厂商手册仔细核对才解决。
另一个教训是“握手时序”。视觉系统拍完照、算完结果,需要把“结果有效”的信号先置位,PLC读取完后再给一个“已接收”信号,视觉端再复位。如果不做这种两段式握手,只靠延迟等待,产线速度一波动就容易丢数据。
3.5 移位寄存器在连续检测中的用途
很多工控转过来的朋友对LabVIEW的while循环不熟,一写连续检测就把相机采集和处理全揉在一个循环里跑。这里我有一个习惯:如果用移位寄存器保存上一帧的状态或中间数据,是LabVIEW和普通文本语言很不一样的地方,用途也很多。
举一个场景:检测中需要判断“一个工件从进入到离开视野”的完整过程,这时候就需要“刚才一帧里有没有触发区域内有运动目标”这个历史状态。如果用普通局部变量,循环复位或并行调用时容易出现数据竞争;用移位寄存器,则可以在每次循环结束时把当前状态带到下一次循环开始,整体代码会干净很多,而且没有全局变量那种隐性耦合。
在比较稳定的采集循环里,相机句柄、图像引用、上一帧的处理结果都可以通过移位寄存器传递。这套模式用习惯之后,你会发现很多在文本语言里要靠类成员变量或者静态变量解决的问题,在LabVIEW里用移位寄存器就够用了。
4. 工程化性能调优:帧率、缓存和标定
4.1 高速产线为什么老“丢帧”
现场只要速度跑起来,第一个被质疑的对象就是视觉系统,“检测太慢”“相机丢帧”这类声音很快会传开。但很多“丢帧”并不是相机或代码性能不够,而是采集线程和处理线程没有做好速度匹配。
LabVIEW默认在一个while循环里同步调采集和处理,循环一圈的时间等于“等待相机帧+图像处理时间”。如果相机是30帧每秒,而一次处理要50毫秒,那最终输出就只有20帧每秒,再往上加就会被拖垮。
更麻烦的是,如果采集驱动用Grab方式,每次取的是最新帧,当处理慢了,中间这些新帧就被丢掉了,并不是相机没采到,而是处理端来不及接。
解决思路主要有两条:一是优化算法,比如降低分辨率、缩小检测区域,减少不必要的彩色图转换;二是改造成生产者-消费者架构。生产者循环只负责抓图并把图像引用放进队列,消费者循环从队列取图做处理。这样图形采集不会因为处理慢而停摆。
在LabVIEW里实现这种架构并不难,用队列函数就能做。队列长度可以设成5到10,防止积压太多旧图导致内存暴涨。实际项目中,我的经验是把采集帧率控制在需求值的1.5倍左右,然后让消费者尽可能处理完每一帧,如果实在处理不过来,宁可丢旧帧也不能让队列无休止增长。
4.2 图像内存和缓存管理
LabVIEW的数据流语言特点之一,是图像这块通常以引用方式传递。新手最容易犯的问题就是在一个循环里反复用IMAQ Create创建图像,但忘了对应release或者close,跑上几个小时内存慢慢涨,最后系统卡死。这种内存泄漏排查起来很费劲。
我这里有一个标配套路:在循环外面创建需要用到的全部Image引用,在循环里只对这些Image做覆盖写入,循环结束后统一用IMAQ Dispose释放。这样既不会频繁分配内存,也不会泄漏。
另外,Linux系统的内存管理比较激进,Windows的工控机如果长期跑视觉程序,建议定期重启检查。对于7x24小时运行的产线,我会在程序里记录运行时长,超过24小时后自动提示重启,当然这只是临时规避,想彻底解决还是要看代码里有没有内存持续增长的隐患。
4.3 曲线拟合在尺寸测量里的补位作用
热词里“labview曲线拟合”这个词条,在视觉项目里会以另一种方式出现。比如测量一个圆弧的半径,或者检测某个边缘的直线度,单纯靠找边点会受单个像素噪声影响比较大。这时候对边缘点序列做一次直线拟合或者圆拟合,能明显提高稳定性。
NI VDM里自带边缘检测函数,可以设置卡尺(Caliper)区域,在区域内沿着搜索方向找边缘点。找到若干个点之后,用IMAQ Fit Line或者IMAQ Fit Circle做拟合,得到亚像素精度的直线或者圆心拟合结果。这比直接在二值化图像上量轮廓要稳定得多,尤其是在边缘存在光照不均、微小毛刺的情况下。
这类方法写起来不难,难在“卡尺区域”的设定。如果卡尺框太小,虽然有噪声点也被当成有效数据参与拟合;如果太大,会把旁边的干扰边缘一起框进来。建议把卡尺区域紧贴目标边缘,并且设置边缘极性(亮到暗还是暗到亮)。先在离线图上多测几张,再定参数区间。
4.4 数据采集和分布式监控怎么跟视觉系统联动
如果只是做检测,上一个完整项目往往还会要求把视觉数据和温度采集、产量统计汇总到一个监控界面里。现实中比较多见的形式是用LabVIEW运行分布式数据采集程序,把视觉结果、传感器数据都汇到一台中心服务器。
视觉系统在产线上通常有自己的工控机,分布式结构下,每台工控机的LabVIEW程序通过网络流(Network Streams)或者TCP把检测结果推送到中央监控。要注意点位数量别太多,否则网络也受不了。另一个优化方向是,视觉端只发送“通过/不通过、坐标、图片路径”等精简信息,大图通过共享文件夹保存,监控端需要复核时再去读取。
如果监控端要求的数据刷新很快,就用网络流,它比TCP更稳定且能自动处理断线重连;如果只是低频记录,用TCP或者UDP就够了。不要一上来就做很重的架构,先跑通小循环再横向扩展,是最稳的节奏。
5. 常见坑位与排查技巧实录
5.1 安装和版本相关报错速查
| 现象 | 常见原因 | 处理思路 |
|---|---|---|
| NI Package Manager安装中断/回滚 | 网络代理、杀毒软件拦截、残留的旧版本组件 | 管理员身份运行,临时退出杀软,用NI官方清理工具清除残留后重装 |
| LabVIEW启动报缺少运行时引擎 | 运行时引擎版本与开发环境不一致 | 到NI官网下载对应年份的Runtime Engine安装,比如8.5.1是古董程序才需要用 |
| 函数面板里找不到视觉相关VI | Vision Development Module没安装,或版本年份与LabVIEW不一致 | 检查NI Package Manager里是否勾选VDM,卸载后重装同一年的VDM |
| VBAI脚本运行时报驱动不可用 | 相机驱动或IMAQdx版本问题 | 更新相机厂商SDK,或确认相机类型是否被NI驱动原生支持 |
| LabVIEW打开工程后提示“强制编译” | 部件版本不一致,底层需要重新生成代码 | 等待编译完成即可;若经常触发,注意确认所有模块版本统一 |
“强制编译”这个词被很多人当成怪事。它其实是LabVIEW发现VI的底层二进制代码跟当前版本的库不匹配,需要重新生成。第一次打开老项目时强制编译是正常的,但如果每次打开都强制编译,怀疑是杀毒软件锁了生成目录,或者安装路径有权限问题阻塞了缓存文件写入。
LabVIEW安装目录和项目路径不要带中文,也是一个传统老坑。Visual Studio和NI的组件在中文路径下编译时偶尔会出奇怪问题。工程路径最好用纯英文,哪怕工控机用户名是中文,也可能导致缓存目录异常,可以让NI Package Manager把缓存目录改到非系统盘。
5.2 图像显示“不刷新”和内存“涨不停”
如果在前面板上放了一个图像显示控件,但运行时画面卡住不动。这时候先检查是不是显示控件放在普通While循环里,同时采集也放在同一个循环,前面板事件处理被阻塞了。正确的做法是,图像显示和采集尽量用并行循环,或者把显示刷新放到事件结构中,只在界面需要时才更新,相当于减少性能损耗。
关于内存涨不停,除了前面说的IMAQ Create和Dispose不配对,还有一种隐藏原因是使用了Vision Assistant自动生成代码时,它可能会在内部创建临时图像,而这些临时图像没有显示释放。如果你把VBAI生成的代码嵌到一个长期运行的循环里,建议逐行看代码,凡是出现Create结尾没有Dispose的地方,都要手动补上。这是检查和修复内存泄漏的基本功。
5.3 相机掉线和网络带来的诡异问题
现场有时候图像显示正常,但跑一段时间后相机连接断掉,程序卡死或者直接退出。这种问题在GigE相机上频发。排查思路第一步不是代码,而是先看网卡是否开启了巨型帧(Jumbo Frame)。相机输出分辨率高时,巨型帧必须开启到9K,默认1500字节的MTU会加大传输负担。很多相机掉线问题,把网卡巨型帧打开并关闭节能模式就消失了。
然后是IP冲突,这个在工厂环境里比较常见。设备一多就容易有人的IP被占用。给视觉系统分配独立网段,并且把IP设成静态,不要用DHCP。相机和上位机之间用单独的物理网卡,不跟办公网混用,是一劳永逸的做法。
相机掉线后的代码也要做自我保护。采集函数返回错误时,程序不能直接退出死循环,应该做重连逻辑。我会给采集循环加一个错误计数器,连续失败三次就自动执行相机关闭再打开的恢复流程,并弹窗报警,让现场人员知道发生了什么,而不是界面突然消失。
5.4 算法参数“现场稳定”的诀窍
做视觉久了你会明白,真正的验收标准不是你自己电脑上跑得多好,而是产线操作工能不能稳定用几个月。有几次我从实验室里换了一组阈值到现场测试,结果产品表面的油污变化就会误判,只能反复改参数。后来想明白一个关键问题:参数要在一个波动范围内选择,而不是追求某一个孤立的“最优值”。
比如光源亮度,调到100刚好的单帧可能没有余量。我会把亮度从80到120逐档拍图记录,观察目标特征在哪个区间内还能稳定识别,然后选择区间的中间位置。阈值参数同理,把高亮产品、正常产品、偏暗产品各取几张作样本,统一测试阈值范围,找到能覆盖所有样品的公共区间。
还有一点很实在的经验交接给现场:把核心算法参数开放到前面板,并在旁边标明建议范围。以前我习惯把阈值全写在代码里,现场想调只能远程喊我改,后来改成前面板输入并做了范围限制,现场工程师自己就能微调。生产效率提升得很明显。
5.5 LabVIEW视觉与AI模型的边界
搜索热词里经常出现onnx runtime以及LabVIEW中调用深度学习模型的内容。对此我的观点是:传统NI视觉函数擅长解决“特征明确、规则固定”的问题,比如定位、测量、常规的外观有无判断。但遇到纹理复杂、缺陷形态不固定的场景,比如布匹表面瑕疵、电池表面划痕,传统方案可能会非常吃力。现在不少项目开始借助ONNX Runtime或TensorRT这类推理库,把训练好的模型打包进视觉系统。
但NI的VDM自身不带深度学习训练能力,如果你要嵌入模型,得通过调用外部动态库的方式来加载ONNX模型或TensorRT引擎。这对普通工程师来说上手成本不算低。我更推荐的落地路径,是先用传统方法跑通整体流程,判断瓶颈是不是真的卡在“缺陷形态多变”上;如果确实是,再局部引入AI识别模块,把它当成一个“高级滤镜”,输入图像输出区域框。把传统定位和AI分类结合起来,在产线上往往比单用任何一种方案更稳。
刚才说的很多坑,我在前几个项目里都踩过一遍。尤其是内存泄漏和相机掉线,这两类问题有一个共同特征:在实验室很难复现,一到现场连续跑几小时就出现。所以现在我做视觉程序,会刻意在循环外围统一管理图像资源和相机连接,并且主动加入看门狗和日志记录。这样即使出了异常,也能通过日志定位到具体是采集、算法还是通讯链路掉链子。
LabVIEW做机器视觉,优势在于开发速度快、和NI硬件配合顺畅、视觉函数库足够丰富,适合快速原型和中小型检测项目。它也并非万能,遇到强非线性缺陷或复杂分类场景,还是要敢于引入外部AI库或者专用算法模块。但从我实际参与的项目来看,大量的产线视觉需求其实就是定位、测量、有无判断,这些用LabVIEW和VDM处理起来手法还是很成熟的,前提是你把环境、图像资源和通讯时序三件事处理好。
如果正在准备项目,建议先别急着铺开写全部代码,花一天时间把相机点亮、光源调好、把一张稳定图像拿到手再动手。一个能稳定输出的图像源头,能省掉后面一半的调参时间。这条经验放在这里,等你在现场被杂光折磨的时候,可能想起来会更有体会。
