简介:这份资源面向自动化视觉与SMT贴片机开发方向的C#工程师及机器视觉学习者,围绕Halcon模板识别、相机标定、MARK点4点校正与2点补偿、贴合补偿算法以及上下双相机对位贴合等核心环节,提供一套可参考的源程序实现,帮助理解贴片机视觉定位与运动控制的完整链路。压缩包共101个文件,约10.45MB,以cs源码、exe可执行文件、dll与pdb调试文件、config配置、manifest与application清单、cache缓存及resx资源文件为主,另含sln解决方案与csproj工程文件,便于直接打开工程梳理模块结构。目前已有876人学习下载。读者可从中获取模板匹配定位、相机标定流程、MARK点校正与补偿策略、双相机协同对位等关键实现思路,适合作为SMT视觉项目开发与算法调试的参考范例。
1. 拆开这个 SMT 贴片机视觉源码包:C# 上位机 + Halcon 模板识别到底能跑出什么
如果你正在做 SMT 贴片机或者精密组装设备的上位机,大概率绕不开两个东西:C# 写控制逻辑,Halcon 做视觉定位。这个压缩包就是一套已经跑通的组合拳——C# 上位机框架、Halcon 模板识别、相机标定、MARK 点 4 点校正加 2 点补偿、贴合补偿算法,还有上下双相机对位贴合。它不是那种只丢几个函数片段的 demo,而是带工程文件(.csproj)、带运行时配置(.application、.vshost.application)、带 HalconCamera_Cshare.csproj 这种相机封装工程的完整源码目录。适合谁?做 SMT 设备软件、视觉对位贴合、或者想从零搭一套 C# 调用 Halcon 的工程师。新手能顺着工程结构摸清模块划分,熟手能直接抠出标定和补偿的算法实现。下面我按“先搞懂它怎么组织,再动手跑起来,最后把坑填平”的顺序拆一遍。
2. 工程结构与模块拆解:从 .csproj 到 HalconCamera_Cshare 的调用链
2.1 先认清目录里每个文件是干什么的
拿到一个源码包,别急着双击 .sln。先看目录里有什么。这个包里出现了几个关键文件:nbglin SMT system.application、nbglin SMT system.vshost.application、DesignTimeResolveAssemblyReferences.cache、HalconCamera_Cshare.csproj、ResolveAssemblyReference.cache。这些名字看着杂,其实分两类:一类是 ClickOnce 发布产生的运行时清单(.application 和 .vshost.application),另一类是 MSBuild 编译过程中的缓存文件(.cache)。真正要关注的是HalconCamera_Cshare.csproj——这是相机封装层的工程文件,说明整个系统把 Halcon 相机操作单独抽了一个 C# 项目出来,而不是全塞在一个大工程里。
常见做法是:主工程负责 UI 和流程调度,HalconCamera_Cshare负责 Halcon 的采集、模板匹配、标定计算。这样拆的好处是,换相机或者换 Halcon 版本时,只动相机层,不动业务逻辑。你打开 .csproj 后,重点看它引用了哪些 HalconNET 的 dll,比如halcondotnet.dll和hdevengine.dll,这两个是 C# 调 Halcon 的核心。
提示:如果 .csproj 里引用的 Halcon dll 路径是绝对路径,换机器后大概率报“找不到程序集”,后面避坑章节会细说。
2.2 主工程与相机层的调用关系
从工程命名看,主工程叫nbglin SMT system,相机层叫HalconCamera_Cshare。典型的调用链是:主工程初始化时创建相机对象,调用HalconCamera_Cshare里的OpenCamera、GrabImage、FindTemplate等方法。模板识别这块,Halcon 的FindShapeModel或FindNccModel会被封装成一个 C# 方法,输入是图像和模板句柄,输出是匹配到的行列坐标和角度。
我一般会先找HalconCamera_Cshare里有没有CreateShapeModel和FindShapeModel的封装。如果有,说明模板识别是走形状匹配,适合 MARK 点和元件定位;如果只有FindNccModel,那对光照变化更敏感,但速度更快。这个包同时涉及 MARK 点校正和贴合补偿,所以大概率两种匹配都会用到——MARK 点用形状匹配抗干扰,元件贴合可能用 NCC 提速度。
2.3 编译前必须确认的三件事
第一,Halcon 版本。C# 调 Halcon 对版本很敏感,halcondotnet.dll的版本必须和本机安装的 Halcon 一致。你可以在 .csproj 的<Reference>节点里看到 HintPath,指向哪个版本的 dll,就去装哪个版本的 Halcon 运行时。
第二,平台目标。SMT 上位机通常编译成 x64,因为 Halcon 的 64 位库性能更好,而且大图像处理不容易内存溢出。在 Visual Studio 里把配置管理器切到 x64,别用 Any CPU。
第三,.NET Framework 版本。老一点的 Halcon 版本配 .NET Framework 4.5 或 4.6.1,新版本可能支持 .NET 6。看 .csproj 里的<TargetFrameworkVersion>,装对应的开发包。
# 检查本机 Halcon 安装路径下是否有对应版本的 dotnet dll ls "C:\Program Files\MVTec\HALCON-*\bin\dotnet35" # 或者 dotnet64 目录,取决于你的 Halcon 版本和平台这段命令是让你确认 Halcon 安装目录里有没有halcondotnet.dll。如果没有,说明安装时没勾选 .NET 接口组件,需要重新运行安装程序补上。参数上注意dotnet35和dotnet64的区别:32 位 Halcon 对应 dotnet35,64 位对应 dotnet64。SMT 设备一律用 64 位。
3. 相机标定与 MARK 点校正:4 点校正加 2 点补偿怎么落到代码
3.1 相机标定的参数到底在标什么
相机标定在 SMT 贴片机里解决的是一个核心问题:图像上的像素坐标怎么变成机械轴的实际毫米坐标。Halcon 的标定流程分两步:先标内参(焦距、畸变系数、像元尺寸),再标外参(相机相对于机械平台的位置和角度)。内参标定通常用标定板,Halcon 提供FindCalibObject和CalibrateCameras算子。外参标定则依赖 MARK 点——在机械平台上放已知间距的 MARK 点,让相机去看,算出像素到毫米的映射关系。
这个包里提到的“4 点校正”就是外参标定的一种简化实现:用四个 MARK 点建立一个平面坐标系,通过仿射变换把像素坐标映射到机械坐标。四个点比三个点多一个冗余,可以算最小二乘,降低单点误差的影响。“2 点补偿”则是在 4 点校正的基础上,用另外两个点做验证和微调,相当于给标定结果加一道校验。
3.2 4 点校正的代码实现逻辑
在 C# 里,4 点校正一般用 Halcon 的VectorToHomMat2d或者自己写仿射变换矩阵。下面是一个典型的实现片段,假设已经从图像里拿到了四个 MARK 点的像素坐标和对应的机械坐标。
// 假设 pixelPoints 和 machinePoints 都是 4 个点的数组 // pixelPoints: 图像上检测到的 MARK 点坐标 (Row, Column) // machinePoints: 机械坐标 (X, Y),单位毫米 HTuple pixelRows = new HTuple(pixelPoints.Select(p => p.Row).ToArray()); HTuple pixelCols = new HTuple(pixelPoints.Select(p => p.Col).ToArray()); HTuple machineX = new HTuple(machinePoints.Select(p => p.X).ToArray()); HTuple machineY = new HTuple(machinePoints.Select(p => p.Y).ToArray()); // 用 Halcon 的 VectorToHomMat2d 计算仿射变换矩阵 // 注意:Halcon 的 VectorToHomMat2d 要求输入是 (Row, Column) 对应 (Y, X) HTuple homMat2D; HOperatorSet.VectorToHomMat2d(pixelRows, pixelCols, machineY, machineX, out homMat2D); // 之后任意像素点转机械坐标 HTuple machineYResult, machineXResult; HOperatorSet.AffineTransPoint2d(homMat2D, pixelRow, pixelCol, out machineYResult, out machineXResult);逻辑说明:VectorToHomMat2d根据至少 3 对点计算仿射变换矩阵,这里给 4 对点,内部走最小二乘。参数顺序容易搞混——Halcon 的图像坐标是 (Row, Column),对应机械坐标的 (Y, X),所以传参时 machineY 对应 Row,machineX 对应 Column。如果你传反了,标定结果会整体旋转 90 度,贴片位置全错。
参数说明:homMat2D是一个 2D 仿射变换矩阵,包含旋转、平移和缩放。AffineTransPoint2d用这个矩阵把像素点转成机械点。实际工程里,这个矩阵会存下来,每次换产品或者重启设备时重新算一遍。
3.3 2 点补偿的校验与微调
4 点校正算完矩阵后,用另外两个 MARK 点做验证。把这两个点的像素坐标通过矩阵转成机械坐标,和实际机械坐标对比,算误差。如果误差超过阈值(比如 0.05mm),就需要补偿。
补偿的常见做法是:计算两个验证点的误差向量,取平均,然后把这个平均误差加到变换矩阵的平移分量上。Halcon 里可以用HomMat2dTranslate来调整平移。
// 计算两个验证点的误差 HTuple verifyPixelRow = new HTuple(new double[] { row1, row2 }); HTuple verifyPixelCol = new HTuple(new double[] { col1, col2 }); HTuple verifyMachineY = new HTuple(new double[] { y1, y2 }); HTuple verifyMachineX = new HTuple(new double[] { x1, x2 }); HTuple transY, transX; HOperatorSet.AffineTransPoint2d(homMat2D, verifyPixelRow, verifyPixelCol, out transY, out transX); // 误差 = 实际机械坐标 - 变换后坐标 HTuple errY = verifyMachineY - transY; HTuple errX = verifyMachineX - transX; // 取平均误差,补偿到矩阵 HTuple avgErrY = errY.TupleMean(); HTuple avgErrX = errX.TupleMean(); HTuple homMat2DCompensated; HOperatorSet.HomMat2dTranslate(homMat2D, avgErrY, avgErrX, out homMat2DCompensated);这段代码的关键在于:补偿量是加在变换后的机械坐标上的,所以用HomMat2dTranslate直接平移矩阵。注意HomMat2dTranslate的参数顺序是 (HomMat2D, Tx, Ty, HomMat2DTranslate),其中 Tx 对应列方向,Ty 对应行方向。如果你把 avgErrY 和 avgErrX 传反了,补偿方向就错了。
注意:2 点补偿不是万能的。如果两个验证点的误差方向相反,说明标定本身有问题,比如 MARK 点识别偏了或者机械平台有间隙,这时候强行补偿反而会引入更大误差。我一般会先看误差向量的一致性,再决定补不补。
4. 模板识别与贴合补偿:Halcon 匹配参数怎么调才不翻车
4.1 模板识别的两种模式与选型
Halcon 模板识别在 SMT 里主要用两种:形状匹配(Shape-based)和 NCC 匹配(Normalized Cross Correlation)。形状匹配基于边缘梯度,对光照变化和部分遮挡不敏感,适合 MARK 点和有缺口的元件。NCC 匹配基于灰度相关性,速度快,但对光照和对比度变化敏感,适合光照稳定的元件贴合。
这个包里同时有 MARK 点校正和贴合补偿,所以大概率 MARK 点用形状匹配,元件贴合用 NCC 或者形状匹配加 ROI 缩小搜索范围。你可以在HalconCamera_Cshare里找CreateShapeModel和CreateNccModel的调用,看它们分别用在哪个流程。
形状匹配的关键参数:AngleStart、AngleExtent、MinScore、NumMatches。SMT 元件通常角度变化不大,AngleStart设 -0.1 到 0.1 弧度就够了,MinScore设 0.7 到 0.8,太低会误匹配,太高会漏匹配。
// 创建形状模板 HTuple modelID; HOperatorSet.CreateShapeModel( templateImage, // 模板图像 "auto", // 对比度自动 -0.1, // 起始角度 0.2, // 角度范围 "auto", // 角度步长 "auto", // 优化 "use_polarity", // 极性 "auto", // 最小对比度 out modelID ); // 查找模板 HTuple findRow, findCol, findAngle, findScore; HOperatorSet.FindShapeModel( searchImage, modelID, -0.1, 0.2, 0.75, // 最小分数 1, // 最大匹配数 0.5, // 最大重叠 "least_squares", // 亚像素模式 0, 0.9, out findRow, out findCol, out findAngle, out findScore );参数说明:MinScore设 0.75 是一个经验值,实际要根据图像质量调。NumMatches设 1 是因为 MARK 点通常只有一个,如果找多个元件可以设大。MaxOverlap设 0.5 防止重叠匹配。亚像素模式选least_squares能把定位精度提到亚像素级,对 SMT 贴片很重要。
4.2 贴合补偿算法的核心思路
贴合补偿解决的是:理论贴片位置和实际贴片位置之间的偏差。偏差来源很多——机械轴回程间隙、相机标定残差、元件在吸嘴上的偏移、PCB 热胀冷缩。补偿算法一般分两步:先建模,再预测。
建模阶段,用历史数据拟合偏差和位置的关系。简单做法是线性补偿:假设偏差在 X 和 Y 方向上是位置的线性函数,用最小二乘拟合。复杂一点可以用多项式或者查表。这个包里既然叫“贴合补偿算法”,大概率是线性补偿加查表结合。
预测阶段,根据当前贴片位置,用模型算出补偿量,加到理论坐标上。Halcon 本身不提供补偿算法,这部分是 C# 写的。你可以在主工程里找Compensate或者Offset相关的方法。
// 简化的线性补偿模型 // 假设偏差 = a * x + b * y + c // 用历史数据拟合 a, b, c public class CompensationModel { private double aX, bX, cX; // X方向补偿系数 private double aY, bY, cY; // Y方向补偿系数 public void Fit(List<DataPoint> history) { // 最小二乘拟合,这里省略矩阵运算细节 // 实际工程里用 MathNet.Numerics 或者自己写高斯消元 } public (double offsetX, double offsetY) Predict(double x, double y) { double offsetX = aX * x + bX * y + cX; double offsetY = aY * x + bY * y + cY; return (offsetX, offsetY); } }逻辑说明:这个模型假设偏差随位置线性变化。实际工程里,如果偏差非线性明显,可以加二次项,或者按区域查表。参数 a、b、c 通过历史贴片数据拟合,数据越多越准。注意补偿量要在贴片前加到目标坐标上,而不是贴片后修正。
4.3 上下双相机对位贴合的协同逻辑
上下双相机在 SMT 里通常是一个看上、一个看下。上相机看 PCB 上的 MARK 点,确定 PCB 的实际位置和角度;下相机看吸嘴上的元件,确定元件相对于吸嘴的偏移和角度。两者结合,算出贴片时的最终补偿量。
协同逻辑一般是:上相机先拍 MARK 点,算出 PCB 的仿射变换矩阵;下相机拍元件,算出元件中心相对于吸嘴中心的偏移;然后把元件偏移通过吸嘴旋转和机械运动,映射到 PCB 坐标系,最终得到贴片坐标。
这个流程里最容易出问题的是坐标系转换。上相机和下相机的坐标系原点不同,需要各自标定,然后通过机械坐标统一。如果两个相机的标定矩阵不一致,贴片位置会系统性偏移。
提示:双相机对位时,先确认两个相机的标定是否用了同一套机械坐标基准。如果上相机标定用平台原点,下相机标定用吸嘴原点,转换时容易漏掉一个平移量。
5. 避坑与排查:Halcon 版本、dll 引用和标定残差的五个血泪经验
5.1 现象:编译报“找不到 halcondotnet.dll” → 原因:Halcon 版本不匹配或路径不对 → 解决:统一版本并改 HintPath
这是最常见的翻车点。.csproj 里引用的halcondotnet.dll路径可能是原作者机器的绝对路径,比如C:\Program Files\MVTec\HALCON-20.11\bin\dotnet35\halcondotnet.dll。你机器上装的是 HALCON-22.11,路径就变了。解决方法是:先确认本机 Halcon 版本,然后在 .csproj 里把 HintPath 改成你的实际路径。如果不想改工程文件,可以在 Visual Studio 里删掉引用,重新从本机路径添加。
5.2 现象:程序运行时报“Halcon license 无效” → 原因:license 文件没放对位置或过期 → 解决:检查 license 路径和版本
Halcon 运行时需要 license 文件。常见问题是 license 放在安装目录下,但程序以管理员权限运行时找不到,或者 license 是试用版已过期。解决:把 license 文件放到系统环境变量HALCONLICENSE指向的路径,或者直接放到程序运行目录。注意 license 版本要和 Halcon 版本一致,20.11 的 license 不能给 22.11 用。
5.3 现象:标定后贴片位置整体偏移 → 原因:4 点校正的坐标顺序传反 → 解决:检查 Row/Column 与 X/Y 的对应
前面代码里提过,Halcon 的图像坐标是 (Row, Column),机械坐标是 (X, Y)。VectorToHomMat2d的参数顺序是 (PixelRow, PixelCol, MachineY, MachineX)。如果你传成 (PixelRow, PixelCol, MachineX, MachineY),标定矩阵会旋转 90 度,贴片位置全错。排查方法:标定完后,用验证点转一下,看误差是不是在合理范围。如果误差很大且方向一致,大概率是坐标顺序问题。
5.4 现象:模板匹配偶尔找不到 MARK 点 → 原因:MinScore 设太高或光照变化 → 解决:降低 MinScore 并加 ROI
MARK 点匹配失败,先看 MinScore。设 0.9 太高,光照稍微变化就掉到 0.85,匹配失败。我一般设 0.7 到 0.8,然后加 ROI 缩小搜索范围,减少误匹配。如果还不行,检查模板图像和搜索图像的对比度是否一致,必要时用Emphasize增强边缘。
5.5 现象:贴合补偿后误差反而变大 → 原因:补偿模型过拟合或数据有离群点 → 解决:加正则化或剔除离群点
补偿算法用历史数据拟合时,如果数据里有离群点(比如某次贴片异常),拟合出的系数会偏。解决:拟合前先做数据清洗,剔除误差超过 3 倍标准差的点。如果数据量少,加正则化项,防止过拟合。另外,补偿量不要设太大,一般不超过 0.1mm,超过说明机械或标定有大问题,先修硬件再补软件。
6. 进阶技巧:用 Halcon 的 Measure 和 Calib 算子验证标定残差
标定做完不是就完了,得验证残差。我一般用 Halcon 的MeasurePos或者MeasurePairs算子,在标定板上取多条边,测实际像素距离,和理论距离对比,算残差。残差在 0.02mm 以内算合格,超过 0.05mm 就得重新标。
具体做法:用标定板图像,找 5 到 10 条边,每条边用MeasurePos测亚像素位置,然后算相邻边的像素距离。再用标定矩阵把像素距离转成毫米,和标定板实际间距对比。
// 用 MeasurePos 测边缘亚像素位置 HTuple measureHandle; HOperatorSet.GenMeasureRectangle2(row, col, phi, length1, length2, width, height, "nearest_neighbor", out measureHandle); HTuple edgeRow, edgeCol, amplitude, distance; HOperatorSet.MeasurePos(image, measureHandle, 1.0, 30, "all", "all", out edgeRow, out edgeCol, out amplitude, out distance); // 算像素距离,再用标定矩阵转毫米 // 对比理论值,算残差参数说明:MeasurePos的Sigma设 1.0 是平滑系数,Threshold设 30 是边缘幅度阈值。Transition选 "all" 表示正负边缘都测。测完后,用distance或者自己算相邻边缘的像素差,再通过标定矩阵转毫米。
我自己的习惯是:每次换相机、换镜头、或者机械平台拆装后,都强制走一遍标定残差验证。有一次偷懒没验,结果贴片偏移了 0.15mm,整批板子返修。从那以后我每次标定完都跑一遍 MeasurePos,残差超过 0.03mm 就重新标。希望帮到你。
本文还有配套的精品资源,点击获取