简介:这是一套基于康耐视VisionPro开发的机器视觉案例合集,面向视觉工程师、自动化设备调试人员以及机器视觉初学者。内容覆盖零件尺寸测量与显示、硬币统计、骰子点数统计、零件孔位数量统计、瑕疵检测、车牌识别、陶瓷釉面瑕疵标注、地面裂痕检测等十余个典型场景,适合用来熟悉VisionPro的定位、测量、识别与缺陷检测流程。压缩包共929个文件,以650张jpg测试图像、76个cs源文件、25个vpp视觉流程文件为主,并包含bmp样本、resx资源配置、dll动态库等,整体55.37MB,结构清晰便于按案例查阅。目前已有557人学习下载,案例集既提供完整工程文件,也配有可运行的图像样本和C#脚本,便于对照学习从图像采集到检测结果输出的实现思路,同时能借鉴实际项目中常见的标注与统计方法。无论是用于课程实验还是工业项目预研,都能提供直观的参考价值。
1. 项目概述与方案设计思路
1.1 三个案例背后的共同需求
接触机器视觉这几年,VisionPro一直是我项目里的主力工具。这次要拆解的案例合集,包含零件尺寸测量与显示、硬币统计、骰子点数统计三个经典场景,别小看这几个看似简单的demo,它们几乎覆盖了机器视觉入门到进阶的完整知识链路。
先说需求本质。零件尺寸测量,核心诉求是“把像素距离变成物理距离,而且测得准”;硬币统计,核心诉求是“不管硬币怎么摆,都能数得清”;骰子点数统计,核心诉求是“识别小圆点的数量,并且能应对倾斜、光照变化”。三个需求放在一起,恰好对应了VisionPro三大核心能力:标定与几何测量、斑点分析与计数、模板匹配与特征提取。
这类案例最适合谁?如果你刚接触VisionPro,想搞清楚工具链怎么串起来,或者你正在做类似项目但测量精度一直上不去、计数老出错,这篇内容会给你一套完整可复用的思路。我尽量把每个环节的“为什么这么做”也讲清楚,而不是只丢一堆工具节点截图。
1.2 为什么选VisionPro这套组合
市面上机器视觉软件不少,OpenCV、Halcon、VisionPro各有拥趸。这几个案例我最终用VisionPro实现,主要基于三点考虑。
第一,VisionPro的QuickBuild环境对原型验证极其友好。拖拽工具、连线、跑图看结果,十分钟能出一个可交互的demo。对于零件测量这种需要反复调参的场景,这个效率优势很明显。
第二,CogPMAlignTool(模板匹配)和CogBlobTool(斑点分析)在工业场景下的稳定性确实经得起考验。硬币统计看似简单,但遇到反光、氧化、部分遮挡时,纯阈值分割的方案很容易翻车,配合模板匹配做粗定位再分割,鲁棒性会好很多。
第三,VisionPro的C#二次开发能力非常完善。原型验证完之后,把整个工具流封装成一个类,UI和逻辑分离,可以直接嵌入到产线软件里。这一点后面会详细说。
1.3 硬件选型与打光方案对比
这一Part分享硬件搭配的实测经验,给到可复用的配置参考。
| 场景 | 相机建议 | 镜头建议 | 打光建议 |
|---|---|---|---|
| 零件尺寸测量 | 500万像素以上工业相机 | 远心镜头或低畸变定焦镜头 | 平行背光源,突出轮廓 |
| 硬币统计 | 300万~500万像素 | 普通定焦镜头,视场覆盖整个区域 | 低角度环形光,避免镜面反射 |
| 骰子点数统计 | 200万像素即可 | 定焦镜头,保证骰子占画面1/3以上 | 漫射穹顶光源,均匀打光 |
打光这块我必须多说一句:硬币那种高反光表面,如果用高角度环形光,画面上全是亮斑,阈值分割根本没法做。低角度打光或者加上偏振片之后,背景压暗、币面细节突出,分割效果立竿见影。零件测量则相反,要的是清晰的边缘轮廓,背光源直接把零件变成黑色剪影,边缘过渡锐利,找线工具的精度才能上去。
2. 核心工具链与关键技术点拆解
2.1 九点标定与畸变标定:测量类应用的“地基”
先想说一句:很多人做测量项目,上来就测,测出来的数据忽大忽小,然后怀疑是找线参数没调好。但实际上,至少一半的精度问题出在标定上。
VisionPro里标定分两部分。第一是九点标定,解决的是像素坐标系到世界坐标系的映射关系。简单理解,就是告诉软件“图像里一个像素到底对应物理世界多少毫米”。操作上,用一张带有9个已知间距圆点的标定板,在视野里移动到9个不同位置,或者直接用一张9点标定板拍一张图,然后让软件建立映射关系。这里有个技巧:标定点要尽量覆盖整个视野范围,不要只在中间一小块区域采点。否则视野边缘的零件测出来会明显偏大或偏小。
第二是畸变标定,解决的是镜头本身带来的图像变形。普通工业镜头在视野边缘会有不同程度的桶形或枕形畸变,对于零件测量这种对绝对精度有要求的场景,务必用CogCalibNPointToNPointTool配合畸变模型(如CogDistortionCorrectionTool)进行处理。如果用的是远心镜头,畸变相对小很多,但也不能完全不标,尤其是测量尺寸公差卡得很严的产品时。
关于标定实操,我的经验是:先做畸变校正,再做九点标定,顺序不要反。如果先做九点标定再做畸变校正,标定矩阵就白做了。
2.2 找线工具做尺寸测量:CogCaliperTool的底层逻辑
VisionPro里做尺寸测量,最常用的是CogCaliperTool(卡尺工具),它的底层原理值得展开讲讲。
卡尺工具的逻辑是:在图像上定义一个搜索区域,沿着搜索方向对图像灰度值的变化进行扫描,找到边缘点,然后通过边缘点拟合成直线或圆。关键参数有几个:搜索方向、边缘极性(亮到暗还是暗到亮)、边缘过滤阈值、卡尺数量、拟合算法。
零件外径测量,我通常的做法是:先用CogPMAlignTool做模板匹配,把零件位置找出来,然后基于匹配得到的坐标,动态地把卡尺工具的搜索区域“贴”到零件边缘附近。这样零件在视野里稍微偏一点,测量区域会跟着移动,不用每次手动调整ROI。这个思路在产线上极其重要,因为零件的位置不可能每次放得完全一致。
卡尺数量方面,我之前犯过的错是:为了追求精度,把卡尺数量设得特别多(比如100个)。实测下来,过密的卡尺反而会把边缘上的细小毛刺、灰尘点也当成边缘点,拟合出来的直线被带偏。后来经验是:边缘长度10~30个卡尺点就够了,配合离群点剔除(Outlier Removal),稳定性会有质变。
有一个容易被忽略的参数是边缘过滤阈值(Edge Filter Threshold),它控制“多大的灰度跳变才算边缘”。这个值设太低,噪声会被当成边缘;设太高,真实的弱边缘会丢失。批量调参的时候,我习惯先用一张典型图,把阈值从低到高扫描一遍,看输出尺寸的稳定性,找到平台区,再定最终值。
2.3 斑点分析与模板匹配:硬币与骰子的识别方案
硬币统计和骰子点数统计,一个用斑点分析做顶梁柱,一个用模板匹配加斑点分析组合拳。
斑点分析(CogBlobTool)本质是连通域分析:输入一张二值图,工具会自动找出所有连通的亮区域或暗区域,并输出每个区域的面积、周长、外接矩形、圆形度等几何特征。
硬币统计场景下,核心思路是:先通过阈值分割把硬币从背景里分离出来,然后用CogBlobTool找到所有硬币区域,最后用面积(或直径)做过滤条件,排除掉误检的噪点。这里的一个关键坑是:如果硬币之间存在叠放,或者相机角度不垂直,硬币投影会变成椭圆或者互相粘连,一个区域里包含两枚硬币,计数就会偏少。解决方案通常有两种:一是从打光层面改善,让硬币尽量分开;二是通过“面积除以单枚硬币面积,向上取整”做一个粗略估算,但这个方法精度有限,只适合做辅助判断。
骰子点数统计则不太一样。骰子是典型的刚性目标,点数位置相对固定,所以先用CogPMAlignTool做一次匹配,确定骰子的位置和旋转角度。拿到旋转角度之后,可以把骰子图像旋转校正,让点阵回到水平方向,然后再对点阵区域做斑点分析,数出里面有多少个点。这种“匹配校正+斑点计数”的组合,比直接整幅图做斑点分析要靠谱得多,因为它天然解决了角度变化的问题。
为什么不用纯深度学习的方案?在这个场景下,传统视觉的优势是:速度快(毫秒级)、可解释性强(每个点为什么被计数,可以通过阈值和面积参数回溯),而且不需要标注数据和训练GPU。对用户来说,这套方案逻辑透明,后期做验收也更容易。深度学习适合的是外观缺陷检测这类“规则说不清楚”的场景,跟计数测量这类“规则非常明确”的场景,技术选型上是两码事。
3. 完整实操过程与参数配置实录
3.1 零件尺寸测量与显示案例实操
这个案例我做一个外径测量,零件是个金属圆环,公差要求±0.05mm。
Step 1:图像采集与预处理用500万像素相机加背光源,拍出来的图是暗背景、亮零件。为了让边缘更锐利,先在CogImageConvertTool里转成灰度图,然后加一个CogIPOneImageTool(高斯滤波),核大小设为3x3。这里注意:不要用太大的滤波核,否则边缘会被钝化,卡尺找出来的边缘位置会系统性偏移,测量结果偏小。
Step 2:标定打开CogCalibNPointToNPointTool,用一张7x7的圆点标定板(圆点间距5mm),采集一张图,按顺序逐个输入标定点的像素坐标和对应的物理坐标。完成后看一眼标定误差(RMS Error),一般来说低于0.1像素就合格。这个案例里我实测RMS Error是0.06像素,对应物理误差大约0.006mm,在公差范围内。
Step 3:模板匹配定位设计CogPMAlignTool,训练时选择一个带特征的区域做模板,这次是取圆环上的一段外弧特征。匹配得分阈值设为0.7,训练区域不要选太大,否则匹配速度会变慢。
Step 4:卡尺工具测量依据匹配结果,用CogCaliperTool在圆环的两个对称位置各放置一组卡尺,测量两组边缘之间的距离。输出的距离是像素值,接在后级的CogDistancePointPointTool里,将像素距离除以标定比例(mm/pixel),得到物理距离。
Step 5:结果显示把测量结果通过CogFixtureTool固定在用户界面上显示,同时对接结果值到串口或者TCP/IP接口,方便产线PLC读取。显示部分用QuickBuild内置的CogRecordDisplay就行,如果要深度定制UI,就转到C#环境。
这套流程跑下来,圆环外径测量误差稳定在±0.03mm以内,完全满足公差要求。
3.2 硬币统计案例实操
这个案例更贴近生活场景,我直接拿一捧硬币,撒在浅色亚克力板上,顶部用低角度环形光拍摄,目标是数出硬币总数。
Step 1:阈值分割使用CogThresholdImageTool,模式选择自动阈值(Otsu),把硬币从背景分离出来。硬币是金属亮色、背景是浅色,两者灰度差异不够明显的情况下,建议先做一次图像增强,用CogIPOneImageTool的非线性对比度拉伸,把灰度差拉开。
Step 2:形态学处理分割出来的二值图可能会存在边缘毛刺,或者币面高光造成的空洞。用一个CogMorphologyTool做一次开运算(先腐蚀后膨胀),核大小设为5x5,可以去掉小的孤立噪点,同时让硬币边缘更平滑。
Step 3:斑点分析进入CogBlobTool,添加面积过滤条件。先跑一次不做过滤,让工具自动输出所有斑点的面积分布,从直方图里找到硬币对应的面积区间。然后设置最小面积和最大面积,把明显偏小或偏大的目标剔掉。
Step 4:验证与收尾这个案例里,我用18枚不同面值的硬币做测试,其中包含两枚叠放的硬币。不叠放时计数准确率100%;叠放时,工具会把两枚叠放的硬币识别成一个面积近似两倍的区域,计数会少1。针对这个情况,我在后处理脚本里加了一个补偿逻辑:当检测到某个斑点面积大于单枚硬币面积的1.6倍时,按2枚计数。这样处理之后,叠放的场景也能给出合理的结果。
3.3 骰子点数统计案例实操
骰子点数识别,本质上是一个“先校正方向、再计数”的问题。
Step 1:模板训练用CogPMAlignTool训练一个骰子模板,训练图选一张点数较少(比如1点或2点)、姿态正的标准图。特征选择上,不要只选点阵区域,要把骰子的圆角边框也包含进模板里,因为边框特征更稳定,匹配定位会更准。
Step 2:角度校正 + 点阵区域定位匹配成功后,工具会输出骰子的中心位置和旋转角度。在CogPMAlignTool后面接一个CogFixtureTool,把骰子块旋转回水平位置。如图像本身没有畸变的情况下,旋转校正完成后,点阵的位置是相对固定的,此时直接用一个固定ROI圈出点阵区域即可。
Step 3:斑点计数在点阵ROI内,用CogBlobTool做斑点检测,面积过滤范围要小心:点太小说明是噪点,点太大说明多个点粘连。骰子点数通常是1~6个直径一致的圆点,面积过滤范围的上下限设为单点面积的0.5~1.5倍,是比较稳妥的做法。
Step 4:结果对应把斑点数量映射到骰子点数,并显示在图像上。如果骰子稍微倾斜,匹配工具输出的旋转角非零,校正之后再跑斑点分析即可。
我这套方案测试下来,对白底黑点、黑底白点两种骰子都有效,前提是打光均匀,避免骰子表面出现大面积高光反射。
3.4 C#二次开发与脚本集成
如果只是做demo,QuickBuild已经够用。但真正落到产线,我一般都会搬到C#环境里做二次开发。
CogToolBlock是个核心组件。你可以把所有工具都放进一个CogToolBlock里,用代码动态创建工具、连线、读取结果。这样做的好处是:整个图像处理流程变成逻辑清晰的一个类,UI归UI、算法归算法,后期维护方便很多。
这是我用C#创建CogToolBlock并跑一个简单流程的核心代码片段:
using Cognex.VisionPro; using Cognex.VisionPro.PMAlign; using Cognex.VisionPro.Caliper; // 创建ToolBlock CogToolBlock toolBlock = new CogToolBlock(); // 添加PMAlign工具 CogPMAlignTool pmAlignTool = new CogPMAlignTool(); toolBlock.Tools.Add(pmAlignTool); // 添加Caliper工具 CogCaliperTool caliperTool = new CogCaliperTool(); toolBlock.Tools.Add(caliperTool); // 获取输入图像 CogImage8Grey image = new CogImage8Grey(); // image = ... 从相机或文件加载 ... // 连接工具 toolBlock.Inputs.Add(image); pmAlignTool.InputImage = image; caliperTool.InputImage = pmAlignTool.OutputImage; // 运行 toolBlock.Run(); // 获取测量结果 CogDistancePointPointTool distanceTool = toolBlock.Tools["DistancePointPoint"] as CogDistancePointPointTool; double resultInPixel = distanceTool.Distance; double resultInMm = resultInPixel / calibScale; // calibScale 为标定比例脚本方面,VisionPro的CogScriptTool支持C#和VB.NET,可以在工具链中间插入自定义逻辑。比如硬币计数里的面积补偿逻辑,就是在CogScriptTool里写几行判断代码实现的。脚本工具可以读取前面的工具输出,修改后再传给后面的工具,灵活性很强。
4. 常见问题与排查技巧实录
4.1 标定数据明明收敛但测量偏差大的排查
这个是很多人的盲区。标定RMS误差很小,但实际测量偏差依然0.2mm以上,可能原因有三个。
第一,标定板平面和被测零件平面不在同一个高度。镜头如果带透视效应,不同高度上的像素比例是不一样的。这种情况下,可以在标定前用机械结构保证两个平面尽量贴齐。
第二,九点标定只做了平面映射,但零件有厚度。对于有高度的圆柱形零件,侧视测量时上下边缘对应的物理尺寸不同,需要用双相机或激光辅助来修正。
第三,图像采集中存在运动模糊。如果用的是卷帘快门相机,零件运动方向与扫描方向不一致,图像会出现拖影,导致边缘位置偏移,测量值偏大或偏小。排查方法是拍一张静止零件和一张运动状态的零件,对比边缘宽度是否明显变大。
我实际遇到过第一种情况,最后是靠加装一个压紧机构,把零件压到位后再拍照解决的,标定和测量在同一平面后,偏差立刻从0.2mm降到0.03mm。
4.2 硬币粘连导致计数偏少的处理思路
硬币叠放是硬币计数方案里最烦的问题。前面提到我用面积补偿逻辑来处理,但这只是一个补救措施。更根本的解决方案是从落料机构入手:
- 使用震动送料器让硬币在进入视野前尽量摊平;
- 增加挡板结构,限制硬币堆叠厚度;
- 如果是静态拍摄,可以加一个“抖散”机构,拍照前轻震一下。
如果必须在软件层面解决,建议用分水岭算法做粘连目标分割。VisionPro里没有现成的分水岭工具,可以通过CogScriptTool调用OpenCV的库来实现分割。但要注意,分水岭对接触面积大、形状不规则的硬币效果不稳定,参数调整需要很细心。
4.3 骰子点数误判的典型场景
骰子识别最容易出问题的场景有三个,给大家参考。
一是骰子倾斜角度过大(超过45度),模板匹配的输出分数会降低,甚至匹配失败。平时做方案的时候,要约束骰子的姿态范围,或者训练多个角度的模板。二是骰子表面高光反射,点阵区域被高光覆盖,斑点分析会漏检。解决方法是换用漫射光源,或者将相机和光源的夹角调成十字偏振。三是背景杂乱,骰子和背景的纹理混在一起。这时建议用颜色阈值先把骰子从背景中分离出来,再跑模板匹配,不要直接整图匹配。
4.4 视觉工具参数调整的通用心态
调参这件事想多说一句。很多初学者遇到测量不准,第一反应是疯狂撸卡尺参数,或者不停改阈值。但参数调整是有顺序的:先确认图像质量(打光是否均匀、焦距是否清晰、有没有反光),再确认标定精度(RMS误差是否合理),然后才去调工具参数。图像质量不过关,后面的参数调得再精细都是白搭。
如果图像质量已经OK了,但测量值还是有波动,建议把连续多帧的测量结果打出来看趋势。是随机波动,还是规律性的偏差?随机波动可能是环境光抖动,规律性偏差可能是某个部件松动或者温度漂移。这属于现场工程问题了,但往往比算法问题更容易被忽略。
我自己做这些案例之后最深的体会是:VisionPro这类工具的优势在于“积木式”快速搭建,但要真正把稳定性做到产线级别,还是得回到光学、机构、标定这些基本功上。工具本身不复杂,复杂的是搞清楚每一步背后的物理限制。如果你也在做类似的测量或识别项目,希望这篇内容能帮你少走一些弯路,尤其是标定和打光那两关,值得多花点时间。
本文还有配套的精品资源,点击获取