☰
康耐视VisionPro案例精讲:尺寸测量、硬币统计与骰子点数识别
2026/10/11 10:06:14 网站建设 项目流程

简介:这套VisionPro案例资源包聚焦康耐视机器视觉软件在工业检测与识别中的典型应用,面向自动化视觉工程师、智能制造学习者及竞赛备赛人群。资源覆盖零件尺寸测量与显示、硬币统计、骰子点数统计、零件孔位数量统计、零件瑕疵检测、啤酒盖瑕疵检测、书签类型检测、手机电池正反面识别、车牌识别、陶瓷釉面瑕疵检测标注、地面裂痕检测标注、杂志页排序、药物胶囊瑕疵检测等十余个场景,每个案例均包含可直接运行的工程文件与效果示例。压缩包内共930个文件,以650张jpg图像素材为主,配合76个cs源码文件、55个png图标、40个resx资源、40个bmp位图以及25个vpp工程文件,整体体积65.75MB,目录结构清晰,便于按案例逐项学习。目前已有128人学习下载,适合希望系统掌握VisionPro视觉检测方案搭建和参数调优的开发者使用。通过研读这些案例,读者可以理解相机标定、尺寸测量、特征匹配、缺陷检测等核心模块的实际用法,并直接复用到自己的项目中。

1. VisionPro 案例包能干什么:从首件引导定位到数值显示的完整链路

康耐视 VisionPro 软件在 PC 端机器视觉里算是老牌工具,但新上手的人最常见的困境是“工具一大堆,不知道从哪拖起”。这套 visionpro 案例包把三个最典型的落地场景——零件尺寸测量与显示、硬币统计、骰子点数统计——做成了完整可跑的工程链路。你不需要从零搭流程,打开工程文件就能看到从图像采集、visionpro 引导定位做首件、测量分割到结果输出的每一步接线方式。适合正在做首件确认、尺寸检测或物料计数的现场工程师,照着案例参数改就能复现。

2. 零件尺寸测量与显示:PMAlign 定位加卡尺测量的参数套路

2.1 为什么定位选 PMAlign:先把坐标系焊死在零件上

零件尺寸测量最忌讳直接拿固定 ROI 去卡图像。产线上的零件每次摆放都有偏移和轻微旋转,一个固定不动的矩形框根本框不住测量位置。案例的第一步用 CogPMAlignTool,它在图像里找与模板最相似的位置,输出一个空间变换矩阵,把零件自身坐标和图像坐标绑定。PMAlign 属于康耐视 PatMax 家族,靠几何特征匹配,对光照变化和轻微形变的容忍度远高于传统灰度相关匹配,这也是它被用来做 visionpro 引导定位做首件的原因——首件确认时零件姿态千奇百怪,灰度模板早就糊了,PatMax 还能给出稳定评分。

在 QuickBuild 里这套接线几乎是固定套路:采集图像先进 CogImageConvertTool 转灰度,灰度图进 PMAlign 训练并运行,输出的空间变换送给 CogFixtureTool。案例工程里这段链路已经连好了,你要调的是三个参数:模板 ROI、搜索区域倍数、相似度阈值。模板 ROI 要选零件上特征最明显的区域,文字、棱边、倒角都可以,但别选一整块大面积纯色区,那样 PMAlign 找不到抓手;搜索区域我一般设成模板的 1.5 倍,太小了零件偏一点就找不到,太大了背景里相似的纹理容易跳过来抢答案。

调用 CogFixtureTool 是这章最关键的一步。fixture 接收 PMAlign 的变换矩阵,输出一张“被摆正”的图像,后续所有测量工具都在这张摆正图像上工作。这样一来,零件偏 10 个像素和偏 100 个像素,测量 ROI 的位置始终不变,卡尺永远量同一个地方。如果不加 fixture,你后面每个工具的 Region 都要跟着零件位置动态改,案例里没这么做,也建议你不要这么做,那是在给自己找麻烦。

2.2 CogCaliperTool 卡尺参数:找边缘的四个关键设置

定位稳定之后才轮到测量。案例里用的 CogCaliperTool 本质是一把数字卡尺:在给定扫描区域内沿垂直方向找灰度剧烈变化的位置,把边缘点坐标输出。它最关键的参数有四个:Region、边缘数量、边缘极性、对比度阈值。Region 用矩形条带,长度要比理论边缘长出 30% 左右,覆盖公差带来的位置波动;边缘数量设 2,代表取扫描路上最先碰到的两条边;边缘极性这个案例设 Both,因为零件左右两条边一条是从暗到亮、一条是从亮到暗,只设单一极性会漏掉其中一条。

下面这段 C# 是案例测量逻辑的精简版,实际工程里通常写在 QuickBuild 的脚本工具中:

// 零件宽度测量:定位 + 摆正 + 卡尺 CogFixtureTool fixture = new CogFixtureTool(); fixture.InputImage = convert.OutputImage; fixture.FixtureTransform = pm.GetLastRunResult().GetTransform(); fixture.Run(); CogCaliperTool caliper = new CogCaliperTool(); caliper.InputImage = fixture.OutputImage; CogRectangle roi = new CogRectangle(); roi.SetCenterLengthsRotation(0, 0, 120, 30, 0); caliper.Region = roi; caliper.Run(); CogCaliperResult r = caliper.GetLastRunResult(); double pixelWidth = Math.Abs(r.Edges[0].PositionX - r.Edges[1].PositionX); double mmWidth = pixelWidth * 0.0856;

逻辑说明:fixture 先把图像扭到零件坐标系里,ROI 的 (0, 0) 就是零件原点,不会跟着零件上下乱跑。caliper 在摆正图像上找两条边,结果里 Edges[0] 和 Edges[1] 是扫描路径上最先命中的两条边缘,横坐标相减得到像素宽度,再乘标定系数 0.0856 就是毫米数。

参数说明:EdgeWidth 决定边缘滤波宽度,默认 5,值越小对亚像素边缘越敏感,但图像噪声大的时候容易误检;对比度阈值默认 20,当零件和背景灰度差小于 20 时必须往下调,否则卡尺会提示找不到边缘。跑完记得看每个 Edge 的 Contrast 值,如果某条边每次都是堪堪过阈值,说明这条边的成像质量在恶化,应该去查光源而不是调参数。

这里有个常被误解的点:卡尺的结果永远是像素单位,毫米数必须经过标定系数换算。标定系数来自视野标定,不是刻在代码里的真理。案例里的 0.0856 是调试相机在某个安装高度下实测出来的,你换了工位、换了相机高度,这个数必须重新测。

2.3 像素换算与数值显示:从像素距离到毫米读数

标定系数怎么来的?一个足够日常的做法是:放一个已知尺寸的零件或量块在视野里,用卡尺量它在图像里的像素宽度,已知物理宽度除以像素宽度就是系数。比如量块标称 20mm,卡尺测得 234 像素,系数就是 20/234≈0.0855。这个办法比用视野宽度除分辨率更接近真实,因为镜头畸变的平均效应被量块位置吸收了一部分。案例代码里 0.0856 就是这么来的,不是查手册查出来的。

显示部分用 CogRecordDisplay,把测量值作为文字图形叠加在图像上:

// 在结果图上叠加测量文本 CogGraphicLabel label = new CogGraphicLabel(); label.Color = CogColorConstants.Green; label.Font = new Font("Microsoft YaHei", 18); label.SetText($"{mmWidth:F2} mm"); label.SetCenter(80, 20); display.StaticGraphics.Add(label, null);

这里SetText里的F2格式化控制两位小数,SetCenter控制文字在图像左上角附近显示。静态图形不随零件移动,对产线看板反而是优点——操作员盯一个固定位置就能看到读数。如果你要文字贴着零件走,可以把 label 挂到 fixture 坐标系再映射回图像,案例里保留了这条路径但默认不开。

注意:标定系数必须和图像分辨率配套。相机分辨率改了、采集模式从全分辨率切成 ROI 模式了,系数都要重新算。这是新手最容易忽略的一环,也是后续测量飘移的第一大来源。

3. 硬币统计:阈值分割与 Blob 面积筛选的完整流程

3.1 预处理与阈值选择:硬币和背景分离的灰度逻辑

硬币统计的本质是图像分割:把硬币像素和背景像素分成两个集合,再数连通域。难点在硬币会反光。金属表面在常规光源下会打出高光,直接抓原始图分割,高光区域会被误判成空洞,硬币中间缺一块,面积计算全乱。所以案例的预处理链路比零件测量长一段:先 CogImageConvertTool 转灰度,再串一个开运算,把细小的反光高光点抹平,同时保持硬币整体轮廓不变。形态学开运算对这种“表面有零星高光、整体形状完整”的目标特别有效。

阈值怎么选?最快的方法是先用 CogHistogramTool 跑一版直方图,看硬币和背景有没有明显的灰度双峰。案例里硬币灰度基本分布在 180 以上,深色背景在 80 以下,中间有个干净的谷底,阈值放在谷底附近、大约 130 就能把背景完全压掉。如果你们的物料换成磨砂面或者光照不稳定,不要写死 130,用直方图双峰法对每帧图像动态取谷底,比固定阈值抗漂移能力强很多。这一条在第五章还会细说,因为它是现场翻车最高发的点。

3.2 CogBlobTool 统计流程:面积筛选与数量累加

分割做完之后,用 CogBlobTool 把前景连通域一个个挑出来。Blob 工具不关心你是什么形状,它做的是像素标记和特征统计,面积、周长、质心、圆度都算好了,你只需要决定保留哪些、丢弃哪些。跑完一次 QuickBuild,按下 F5 执行后,Blob 工具的结果面板会把每个目标的面积、周长、质心列成一张表。在快速验证阶段可以不开脚本,直接按面积排序列出前几个目标,人工核对阈值有没有把硬币切碎、有没有把背景灰尘圈进来,这一步能暴露八成以上的分割问题。

下面这段是案例统计核心逻辑:

// 硬币统计:阈值分割 + 面积筛选 CogBlobTool blob = new CogBlobTool(); blob.InputImage = convert.OutputImage; blob.SegmentationParams.Method = CogBlobSegmentationMethodConstants.Threshold; blob.SegmentationParams.Threshold = 130; blob.SegmentationParams.Connectivity = CogBlobConnectivityConstants.Connect8; blob.Run(); CogBlobResultCollection blobs = blob.GetLastRunResult().GetBlobs(); int coinCount = 0; foreach (CogBlobResult b in blobs) { int area = b.GetArea(); if (area >= 8000 && area <= 20000) { coinCount++; } }

逻辑说明:Threshold=130意味着灰度低于 130 的像素被判为背景,高于等于 130 的算前景,正好对上直方图谷底。Connect8指八连通,对角线相邻的像素也算同一个目标,硬币边缘斜向连接时不容易断开。GetArea()返回像素面积,面积落在 8000 到 20000 之间的 Blob 才算一枚硬币,其他全丢。

参数说明:面积范围不是玄学,是案例里一枚硬币在调试分辨率下的实测区间。换相机分辨率、换硬币面值后必须重新标定。土办法:单独放一枚硬币入镜,跑完看GetArea()的实测值,上下各放宽 30%。如果你要统计的硬币大小不一样,这个范围就要改成区间判断,而不是单值。

面积之外还有一条圆度过滤值得留作备用。圆度 = 4π × 面积 / 周长²,硬币接近圆形,数值通常在 0.85 以上;螺丝、垫片、条形异物会低于 0.5。案例里默认不启用圆度过滤,因为单纯统计数量时面积已经够用,但当你发现画面里混入异形物时,把这个条件打开即可,不用改结构。

3.3 边界与粘连处理:两个容易漏计的场景

硬币统计有两个坑,案例调试时都踩过,这里直接给出处理结论。

第一个是硬币压在图像边缘。硬币被图像边界切开,算出来的面积只有完整硬币的一半多,直接掉出面积区间,统计结果平白少一枚。正解不是把面积下限往下压,而是把“统计有效区”定义成一块内缩矩形,要求硬币中心落在有效区内才计入。边缘处的硬币要么机构推回,要么交给另一台相机,靠算法强行补救会引入误计。

第二个是硬币粘连。两枚硬币贴在一起会形成一个 8 字形连通域,面积大约等于两枚之和,被面积上限过滤掉,等于一次丢两枚。案例对轻度粘连用开运算先做分离,效果有限;真正叠放时要直接报警,让机构把硬币振散再拍照。视觉能解决不重叠场景的计数,但解决不了物理堆叠,这个边界心里要清楚。

4. 骰子点数统计:模板匹配加特征分类的识别方案

4.1 骰子面定位:模板训练与多匹配设置

骰子点数统计和硬币完全不同。硬币是“找所有像硬币的东西并计数”,骰子是“先找到骰子面,再数面上的点”。骰子每次入镜的姿态不一定一样,可能旋转过几十度,甚至轻微倾斜。VisionPro 案例里用 CogPMAlignTool 定位骰子面,因为它对旋转不变,模板训练完成后,输出一个变换矩阵,后续点数检测的 ROI 跟着这个矩阵转,骰子转多少度,ROI 就跟着转多少度,不会出现“点框没对上”的尴尬。

模板训练有个容易犯的错:有人觉得点数会干扰定位,所以训练时故意避开点,只选骰子的空白边缘。结果 PMAlign 评分忽高忽低。原因很简单,空白区域缺乏几何特征,PatMax 也找不到抓手。案例里直接选包含点坑在内的完整骰子面中心区域做模板,点数图案本身就是最好的特征,定位反而更稳。训练时 ROI 也不要框太大,骰子面外沿的桌面纹理混进来会稀释特征权重,框到面内留一圈余量就好。

单骰子场景把匹配数上限设 1 就够了。多骰子场景把 MaxNumberOfMatches 调大,工具会在图像里找多个相似位置,按评分排序输出。这里的坑是要确认评分阈值,默认 0.7 左右通常可用,如果骰子面有部分遮挡,评分会掉到 0.5 以下,这时要么提高匹配数上限做冗余,要么调整遮挡方向的光源,后者往往更有效。

4.2 点数计数:Blob 阈值在骰子面上的应用

骰子点数是圆形凹坑,白底黑点或黑底白点,与底色灰度差非常明显,用 Blob 数连通域是最快的思路。和硬币统计不同,这里的 Blob 不做“大范围面积过滤”,而是过滤小噪点,保留中等大小的圆坑。以下是案例的点数计数脚本:

// 骰子点数统计:定位 + 摆正 + 点数计数 CogPMAlignTool dieLocator = new CogPMAlignTool(); dieLocator.InputImage = convert.OutputImage; dieLocator.Pattern.Train(); dieLocator.Run(); CogFixtureTool fix = new CogFixtureTool(); fix.InputImage = convert.OutputImage; fix.FixtureTransform = dieLocator.GetLastRunResult().GetTransform(); fix.Run(); CogBlobTool pip = new CogBlobTool(); pip.InputImage = fix.OutputImage; pip.SegmentationParams.Method = CogBlobSegmentationMethodConstants.Threshold; pip.SegmentationParams.Threshold = 200; pip.SegmentationParams.Connectivity = CogBlobConnectivityConstants.Connect8; pip.Run(); int dotCount = 0; foreach (CogBlobResult b in pip.GetLastRunResult().GetBlobs()) { int area = b.GetArea(); if (area >= 300 && area <= 1200) { dotCount++; } } // 骰子点数 = dotCount(1~6)

逻辑说明:Threshold=200配合默认分割方向,把灰度低于 200 的点坑像素保留下来,白底黑点正好是“黑点低灰度、白底高灰度”,方向天然匹配。点数面积范围 300 到 1200 是单颗点坑在案例分辨率下的实测区间,比硬币区间窄很多,因为点坑面积稳定且形状规则。

参数说明:如果骰子是黑底白点,阈值方向要反过来——用CogBlobSegmentationMethodConstants.Range或把阈值判断改为“大于阈值为前景”。我在切换物料后都会先跑一次直方图,确认点坑灰度峰和底色灰度峰的位置,再决定阈值往高取还是往低取。点数识别是 1 到 6 的映射,数出几个点就是几,不需要布局判断。4 点和 6 点的区别只在个数,不在排布,所以脚本到这里就结束了。

4.3 多骰子并存与防误判

多骰子场景需要在定位阶段就把所有骰子找齐,然后对每个匹配结果单独建立固定坐标系再计数。CogPMAlignTool 的结果集里每个 Match 带一个变换矩阵,循环里逐个喂给 CogFixtureTool,就能逐个统计点数。案例里对每个骰子画一个数字标签,哪个骰子没识别出来一眼就能看到。

防误判主要看两点:一是点数圆度,点坑边缘如果被阈值切碎,圆度会明显下降,这种情况通常是光照角度太陡,凹坑一侧被阴影盖住;二是点数之间的最小间距,异常噪点如果面积和点坑接近,会混进计数,加一个“点坑质心必须落在骰子面 ROI 内”的条件能挡掉大部分噪声。漫反射光源配合低角度相机是拍骰子点数最稳的组合,这一点在案例说明里也标了。

5. VisionPro 常见问题排查:五个翻车现场与修复记录

网上能搜到的康耐视 visionpro 工具详细介绍,大多只讲单个工具怎么拖、怎么设参数,真正难的是工具与工具之间的衔接——恰恰是这些衔接处最容易翻车。以下五条来自案例调试过程的真实记录,按“现象、原因、解决”顺序写出,每条都能对应到具体参数。

5.1 现象一:阈值分割换班后集体失效

现象:白天调试好的硬币统计,当天晚上换班后一运行,画面里硬币全变成了黑色大块,统计数量直接爆炸。

原因:现场自然光占比过高。白天的窗外光把硬币整体灰度抬高了 30 到 50,晚上灯光切换后,直方图双峰的位置整体漂移,固定阈值 130 把背景也包了进来。

解决:先固定光源,用环形低角度光把环境光压下去;再把阈值从固定值改成直方图自适应,动态取硬币峰和背景峰的谷底。案例里保留了两套方式,固定阈值用于光照稳定的封闭工位,自适应阈值用于半开放工位。从那以后我每个分割类项目都会先问一句:这个工位的光照是封闭还是开放,答案直接决定阈值写死还是写活。

5.2 现象二:卡尺测量值忽大忽小

现象:同一个零件不移动,连测 10 次,宽度结果最大最小差了 0.4mm,超出产线公差。

原因:第一步就查错了方向。最初以为是卡尺参数问题,反复调 EdgeWidth 和对比度,毫无改善。后来把 PMAlign 的评分调出来看,发现零件每次定位的 Score 在 0.6 到 0.98 之间波动,定位本身就飘,卡尺跟着定位坐标一起飘,测量值自然稳不住。

解决:先把模板 ROI 换到特征更锐利的位置,Score 稳定到 0.95 以上;再把搜索区域从 2 倍缩到 1.5 倍,减少干扰。定位稳了之后,卡尺哪怕参数不变,重复性也立刻回到 ±0.02mm 以内。测量问题先查定位,这是我在这个案例里花掉半天换来的结论。

5.3 现象三:PMAlign 偶尔锁到错误特征上

现象:骰子点数案例中,PMAlign 偶发地把骰子旁边的一个金属铭牌当成了目标,骰子点数显示成乱码。

原因:搜索区域设得太大,几乎覆盖了整幅图像,而铭牌的某条边和骰子边缘轮廓高度相似。PMAlign 按“最像”输出,相似度反而压过了真目标。

解决:把搜索区域收到骰子最大偏移范围附近,同时把相似度阈值从 0.5 提到 0.75,两个参数一起改之后,连续跑 500 次没有误匹配。参数不是越大越保险,搜索范围大,匹配的候选就多,误伤概率跟着涨。

5.4 现象四:视野边缘的硬币被漏计

现象:统计一盘硬币,实际 15 枚,视觉只输出 13 枚,缺的数量每次都是紧贴图像边缘的那几枚。

原因:边缘硬币被图像边界切开,Blob 面积只有完整硬币的 50% 到 70%,落进面积下限之外被过滤掉了。开始以为是面积范围设得太窄,把下限从 8000 降到 4000,结果背景里的高亮灰尘也开始被计进来,越调越糟。

解决:设置统计有效区,要求硬币质心必须落在有效区内,边缘的被切开目标直接不参与统计。真正要处理边缘硬币时,把相机位置或机构角度调整一下,让硬币整体远离边界,靠算法补面积属于用锤子拧螺丝。

5.5 现象五:骰子点数识别在旋转后出错

现象:骰子正面朝上时点数完全正确,操作工用手拨了一下骰子,点数就从 6 变成了 4 或者直接报错。

原因:拨动后骰子不再是平面正对相机,点坑在斜视角度下变成月牙形高光区,Blob 把高光当成了背景,点坑面积被切开,计数就不对了。更隐蔽的一种是凹坑反光出现“甜甜圈”效果,点坑中心亮、边缘暗,Blob 把中心亮区判成背景,一个点被劈成两个环。

解决:改成漫射光源,让凹坑内部亮度均匀;在 Blob 前加一次闭运算,把同一点的破碎区域重新连起来;最终判断时把面积上下限适当放宽,允许点坑面积有 30% 的波动。如果骰子姿态变化太随意,视觉判侧面的意义不大,产线应当约束姿态,保证骰子面大致朝上。

这里要说一句:很多视觉问题追到根上其实是机械和光源问题,工具只是把物理事实读出来。案例包能帮你省时间的地方,正是把这些坑预先标在了工程注释里,你拿到手直接避着走。

6. 案例到产线的验证习惯:标定、重复性与调试顺序

6.1 验证三件套:重复性、标定误差、节拍

案例跑通只算第一步,上产线前我会强制做三项验证。第一项是重复性:同一个物料不动机器测 20 次,看输出值标准差,尺寸测量的标准差应该小于公差带的十分之一;第二项是标定误差:放一个已知尺寸的标准量块,视觉测出来的值和量块标称值对比,误差超 0.1mm 就重新标定;第三项是节拍:从采图到结果输出算总耗时,VisionPro 的工具链都在毫秒级,真正吃时间的往往是采图和显示,脚本里不要做耗时的图像拷贝。三项数据记录在案例调试日志里,换型时直接对照,不用重新摸索。

6.2 我每次改参数后强制走的三步

改完参数不直接上产线,我习惯按固定顺序自检:第一步只看定位,在结果图里打开 PMAlign 的 Score 和变换坐标,确认定位稳定;第二步看分割,把阈值处理后的二值图叠在灰度图上检查有没有过分割和欠分割;第三步看最终数值,和人工测量结果比对一遍。每一步都过了,才把工程重新发布到现场。

从那以后,我每次改完案例里的任何一个工具参数,都强制走一遍这三步,再急也不跳过定位这一步。量测类项目里十个有九个问题出在“定位没锁死就往下走”。希望这份案例的参数和坑位记录能帮你在同样的路上少走几趟。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询